@evergis/react 4.0.63 → 4.0.64

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,6 +1,6 @@
1
1
  import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
2
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, Dialog, DialogTitle, ThemeProvider, darkTheme, DialogContent, CircularProgress, Switch, AutoComplete, Input, Slider, Dropdown, Checkbox, DatePicker, getLocale, IconToggleButton, LinearProgress, ActionsGroup, DialogActions, RaisedButton, Preview, H2, Blank, Popover, UploaderItemArea, UploaderTitleWrapper, Uploader, NumberRangeSlider, useAsyncAutocomplete, RangeNumberInput, defaultTheme, dateFormat } from '@evergis/uilib-gl';
3
- import { createContext, memo, useRef, useState, useCallback, useEffect, useContext, useMemo, isValidElement, Fragment } from 'react';
3
+ import { createContext, memo, useRef, useState, useCallback, useEffect, useContext, useMemo, isValidElement, Fragment, createElement } 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';
6
6
  import { AttributeType, generateId, STORAGE_TOKEN_KEY, parseJwt, STORAGE_REFRESH_TOKEN_KEY, RemoteTaskStatus, LayerServiceType, OgcGeometryType, StringSubType, AttributeConfigurationType } from '@evergis/api';
@@ -5629,7 +5629,6 @@ const usePythonTask = () => {
5629
5629
  const [subscriptionId, setSubscriptionId] = useState(null);
5630
5630
  const [isLogDialogOpen, setIsLogDialogOpen] = useState(false);
5631
5631
  const [result, setResult] = useState(null);
5632
- const logRef = useRef(null);
5633
5632
  const reset = useCallback(() => {
5634
5633
  setStatus(RemoteTaskStatus.Unknown);
5635
5634
  setError(null);
@@ -5683,7 +5682,7 @@ const usePythonTask = () => {
5683
5682
  if (data?.taskId === newTaskId) {
5684
5683
  const isFinished = [RemoteTaskStatus.Completed, RemoteTaskStatus.Error].includes(data.status);
5685
5684
  setStatus(data.status);
5686
- setLog([logRef.current, data.log].filter(Boolean).join("\n"));
5685
+ setLog(prev => [prev, data.log].filter(Boolean).join(""));
5687
5686
  if (data.log)
5688
5687
  setLastMessage(data.log);
5689
5688
  setExecutionTime(Date.now() - start);
@@ -5729,9 +5728,6 @@ const usePythonTask = () => {
5729
5728
  const closeLog = useCallback(() => {
5730
5729
  setIsLogDialogOpen(false);
5731
5730
  }, []);
5732
- useEffect(() => {
5733
- logRef.current = log;
5734
- }, [log]);
5735
5731
  return {
5736
5732
  taskId,
5737
5733
  runTask,
@@ -7639,17 +7635,17 @@ const STATUS_ICONS = {
7639
7635
  [RemoteTaskStatus.Unknown]: "play",
7640
7636
  };
7641
7637
 
7642
- const LogDialog = ({ isOpen, onClose, logs, status, statusColors }) => {
7638
+ const LogDialog = ({ isOpen, onClose, onMinimize, logs, status, statusColors }) => {
7643
7639
  const { t } = useGlobalContext();
7644
- const getStatusTitle = useCallback((status) => {
7645
- const translationKey = STATUS_TRANSLATION_KEYS[status] || STATUS_TRANSLATION_KEYS[RemoteTaskStatus.Unknown];
7646
- const defaultValue = STATUS_TITLES[status] || STATUS_TITLES[RemoteTaskStatus.Unknown];
7640
+ const getStatusTitle = useCallback((currentStatus) => {
7641
+ const translationKey = STATUS_TRANSLATION_KEYS[currentStatus] || STATUS_TRANSLATION_KEYS[RemoteTaskStatus.Unknown];
7642
+ const defaultValue = STATUS_TITLES[currentStatus] || STATUS_TITLES[RemoteTaskStatus.Unknown];
7647
7643
  return t(translationKey, { ns: "dashboard", defaultValue });
7648
7644
  }, [t]);
7649
- const getStatusColor = useCallback((status) => {
7650
- return statusColors?.[status] || STATUS_COLORS[status] || STATUS_COLORS[RemoteTaskStatus.Unknown];
7645
+ const getStatusColor = useCallback((currentStatus) => {
7646
+ return statusColors?.[currentStatus] || STATUS_COLORS[currentStatus] || STATUS_COLORS[RemoteTaskStatus.Unknown];
7651
7647
  }, [statusColors]);
7652
- return (jsxs(Dialog, { isOpen: isOpen, onCloseRequest: onClose, modal: true, maxWidth: "800px", minWidth: "600px", minHeight: "600px", children: [jsx(DialogTitle, { children: jsxs(Flex, { justifyContent: "space-between", alignItems: "center", children: [jsxs(Flex, { alignItems: "center", children: [jsx(FlexSpan, { marginRight: "1rem", children: t("taskLogs", { ns: "dashboard", defaultValue: "Логи выполнения задачи" }) }), jsx(ThemeProvider, { theme: darkTheme, children: jsx(StatusBadge, { text: getStatusTitle(status), bgColor: getStatusColor(status) }) })] }), jsx(IconButton, { kind: "close", onClick: onClose })] }) }), jsx(DialogContent, { children: jsx(Flex, { flexDirection: "column", height: "100%", marginBottom: "2rem", children: jsx(LogTerminal, { log: logs || t("taskLogsEmpty", { ns: "dashboard", defaultValue: "Логи отсутствуют" }) }) }) })] }));
7648
+ return (jsxs(Dialog, { isOpen: isOpen, onCloseRequest: onClose, modal: true, maxWidth: "800px", minWidth: "600px", minHeight: "600px", children: [jsx(DialogTitle, { children: jsxs(Flex, { justifyContent: "space-between", alignItems: "center", children: [jsxs(Flex, { alignItems: "center", children: [jsx(FlexSpan, { marginRight: "1rem", children: t("taskLogs", { ns: "dashboard", defaultValue: "Логи выполнения задачи" }) }), jsx(ThemeProvider, { theme: darkTheme, children: jsx(StatusBadge, { text: getStatusTitle(status), bgColor: getStatusColor(status) }) })] }), jsxs(Flex, { alignItems: "center", width: "auto", children: [onMinimize && jsx(IconButton, { kind: "change_geom", onClick: onMinimize }), jsx(IconButton, { kind: "close", onClick: onClose })] })] }) }), jsx(DialogContent, { children: jsx(Flex, { flexDirection: "column", height: "100%", marginBottom: "2rem", children: jsx(LogTerminal, { log: logs || t("taskLogsEmpty", { ns: "dashboard", defaultValue: "Логи отсутствуют" }) }) }) })] }));
7653
7649
  };
7654
7650
 
7655
7651
  var ThemeName;
@@ -7712,19 +7708,32 @@ const buildFiltersFromResponse = (responseFilters, result) => {
7712
7708
  return Object.keys(filters).length ? filters : null;
7713
7709
  };
7714
7710
 
7711
+ const ClampedText = styled.div `
7712
+ display: -webkit-box;
7713
+ -webkit-line-clamp: 2;
7714
+ -webkit-box-orient: vertical;
7715
+ overflow: hidden;
7716
+ text-overflow: ellipsis;
7717
+ word-break: break-word;
7718
+ `;
7719
+ const clampDescription = (text) => createElement(ClampedText, null, text);
7720
+
7715
7721
  const RUN_ID_RADIX = 36;
7716
7722
  const RUN_ID_LENGTH = 8;
7717
7723
  const generateRunId = () => `task-${Date.now()}-${Math.random().toString(RUN_ID_RADIX).slice(2, RUN_ID_LENGTH)}`;
7718
- const useTaskNotifications = ({ enabled, status, lastMessage, openLog, }) => {
7724
+ const useTaskNotifications = ({ enabled, suppressed, status, lastMessage, openLog, }) => {
7719
7725
  const { t, notification } = useGlobalContext();
7720
7726
  const runIdRef = useRef(null);
7721
7727
  const prevStatusRef = useRef(RemoteTaskStatus.Unknown);
7728
+ const isVisibleRef = useRef(false);
7729
+ const [dismissed, setDismissed] = useState(false);
7722
7730
  useEffect(() => {
7723
7731
  if (!enabled) {
7724
7732
  if (runIdRef.current) {
7725
7733
  notification?.close(runIdRef.current);
7726
7734
  runIdRef.current = null;
7727
7735
  }
7736
+ isVisibleRef.current = false;
7728
7737
  prevStatusRef.current = status;
7729
7738
  return;
7730
7739
  }
@@ -7735,54 +7744,70 @@ const useTaskNotifications = ({ enabled, status, lastMessage, openLog, }) => {
7735
7744
  const isFreshRun = status === RemoteTaskStatus.Process && prevStatusRef.current !== RemoteTaskStatus.Process;
7736
7745
  if (isFreshRun) {
7737
7746
  runIdRef.current = generateRunId();
7747
+ isVisibleRef.current = false;
7748
+ setDismissed(false);
7738
7749
  }
7739
7750
  if (!runIdRef.current) {
7740
7751
  runIdRef.current = generateRunId();
7741
7752
  }
7742
7753
  const id = runIdRef.current;
7743
- const description = lastMessage || t("taskStarted", { ns: "dashboard", defaultValue: "Запуск задачи…" });
7744
- const button = t("details", { ns: "dashboard", defaultValue: "Подробнее" });
7754
+ const description = clampDescription(lastMessage || t("taskStarted", { ns: "dashboard", defaultValue: "Запуск задачи…" }));
7745
7755
  const base = {
7746
7756
  id,
7747
7757
  title: "",
7748
7758
  description,
7749
7759
  duration: Number.MAX_SAFE_INTEGER,
7750
- button,
7751
- buttonIcon: "info",
7752
- buttonColor: "primary",
7753
- onButtonClick: openLog,
7760
+ ...(lastMessage ? {
7761
+ button: t("details", { ns: "dashboard", defaultValue: "Подробнее" }),
7762
+ buttonIcon: "info",
7763
+ buttonColor: "primary",
7764
+ onButtonClick: openLog,
7765
+ } : {}),
7754
7766
  };
7767
+ let item = null;
7755
7768
  if (status === RemoteTaskStatus.Process) {
7756
- const item = {
7769
+ item = {
7757
7770
  ...base,
7758
7771
  title: t("taskInProgress", { ns: "dashboard", defaultValue: "Выполняется" }),
7759
7772
  progress: true,
7760
7773
  };
7761
- if (isFreshRun) {
7762
- notification?.add(item);
7763
- }
7764
- else {
7765
- notification?.update(item);
7766
- }
7767
7774
  }
7768
7775
  else if (status === RemoteTaskStatus.Completed) {
7769
- notification?.update({
7776
+ item = {
7770
7777
  ...base,
7771
7778
  title: t("taskCompleted", { ns: "dashboard", defaultValue: "Выполнено" }),
7772
7779
  success: true,
7773
7780
  progress: false,
7774
- });
7781
+ };
7775
7782
  }
7776
7783
  else if (status === RemoteTaskStatus.Error) {
7777
- notification?.update({
7784
+ item = {
7778
7785
  ...base,
7779
7786
  title: t("taskError", { ns: "dashboard", defaultValue: "Ошибка" }),
7780
7787
  error: true,
7781
7788
  progress: false,
7782
- });
7789
+ };
7790
+ }
7791
+ if (!item) {
7792
+ prevStatusRef.current = status;
7793
+ return;
7794
+ }
7795
+ if (suppressed || dismissed) {
7796
+ if (isVisibleRef.current) {
7797
+ notification?.close(id);
7798
+ isVisibleRef.current = false;
7799
+ }
7800
+ }
7801
+ else if (isVisibleRef.current) {
7802
+ notification?.update(item);
7803
+ }
7804
+ else {
7805
+ notification?.add(item);
7806
+ isVisibleRef.current = true;
7783
7807
  }
7784
7808
  prevStatusRef.current = status;
7785
- }, [enabled, status, lastMessage, openLog, t, notification]);
7809
+ }, [enabled, suppressed, dismissed, status, lastMessage, openLog, t, notification]);
7810
+ return { setNotificationDismissed: setDismissed };
7786
7811
  };
7787
7812
 
7788
7813
  const TaskContainer = memo(({ type, elementConfig, renderElement }) => {
@@ -7793,12 +7818,21 @@ const TaskContainer = memo(({ type, elementConfig, renderElement }) => {
7793
7818
  const { taskId, runTask, stopTask, status, openLog, loading, isLogDialogOpen, closeLog, log, lastMessage, result, } = usePythonTask();
7794
7819
  const { options } = elementConfig || {};
7795
7820
  const { title, relatedResources, center, icon, statusColors, responseFilters, useNotifications, } = options || {};
7796
- useTaskNotifications({
7821
+ const { setNotificationDismissed } = useTaskNotifications({
7797
7822
  enabled: !!useNotifications,
7823
+ suppressed: isLogDialogOpen,
7798
7824
  status,
7799
7825
  lastMessage,
7800
7826
  openLog,
7801
7827
  });
7828
+ const onCloseLog = useCallback(() => {
7829
+ setNotificationDismissed(true);
7830
+ closeLog();
7831
+ }, [closeLog, setNotificationDismissed]);
7832
+ const onMinimizeLog = useCallback(() => {
7833
+ setNotificationDismissed(false);
7834
+ closeLog();
7835
+ }, [closeLog, setNotificationDismissed]);
7802
7836
  useEffect(() => {
7803
7837
  const filtersToApply = buildFiltersFromResponse(responseFilters, result);
7804
7838
  if (filtersToApply)
@@ -7823,7 +7857,7 @@ const TaskContainer = memo(({ type, elementConfig, renderElement }) => {
7823
7857
  return runTask({ resourceId, parameters: newParams, script, fileName, methodName });
7824
7858
  }));
7825
7859
  }, [attributes, currentPage.filters, dataSources, ewktGeometry, layerInfo, projectDataSources, relatedResources, runTask, selectedFilters, stopTask, taskId]);
7826
- return (jsxs(Fragment$1, { children: [jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), jsxs(Flex, { justifyContent: center ? "center" : "flex-start", children: [jsx(StatusWaitingButton, { title: title || t("run", { ns: "dashboard", defaultValue: "Запуск" }), icon: icon, status: status, statusColors: statusColors, isWaiting: loading || !!taskId, isDisabled: !relatedResources?.length, onClick: onClick }), !!(log || taskId) && (jsxs(Fragment$1, { children: [jsx(IconButton, { kind: "info", onClick: openLog }), jsx(LogDialog, { logs: log, status: status, statusColors: statusColors, isOpen: isLogDialogOpen, onClose: closeLog })] }))] })] }));
7860
+ return (jsxs(Fragment$1, { children: [jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), jsxs(Flex, { justifyContent: center ? "center" : "flex-start", children: [jsx(StatusWaitingButton, { title: title || t("run", { ns: "dashboard", defaultValue: "Запуск" }), icon: icon, status: status, statusColors: statusColors, isWaiting: loading || !!taskId, isDisabled: !relatedResources?.length, onClick: onClick }), !!(log || taskId) && (jsxs(Fragment$1, { children: [jsx(IconButton, { kind: "info", onClick: openLog }), jsx(LogDialog, { logs: log, status: status, statusColors: statusColors, isOpen: isLogDialogOpen, onClose: onCloseLog, onMinimize: useNotifications ? onMinimizeLog : undefined })] }))] })] }));
7827
7861
  });
7828
7862
 
7829
7863
  const EditContainer = ({ type, elementConfig, renderElement }) => {