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