@evergis/react 3.1.65 → 3.1.67
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/components/Dashboard/containers/TaskContainer/components/LogDialog/constants.d.ts +4 -0
- package/dist/components/Dashboard/containers/TaskContainer/components/LogDialog/index.d.ts +3 -0
- package/dist/components/Dashboard/containers/TaskContainer/components/LogDialog/styled.d.ts +4 -0
- package/dist/components/Dashboard/containers/TaskContainer/components/LogDialog/types.d.ts +8 -0
- package/dist/components/Dashboard/containers/TaskContainer/styled.d.ts +5 -0
- package/dist/components/Dashboard/types.d.ts +3 -2
- package/dist/hooks/task/usePythonTask.d.ts +6 -0
- package/dist/index.js +106 -7
- package/dist/index.js.map +1 -1
- package/dist/react.esm.js +107 -8
- package/dist/react.esm.js.map +1 -1
- package/package.json +3 -3
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, WaitingButton, LinearProgress, H2, ThemeProvider, defaultTheme, Preview, Blank, Popover, Expander, darkTheme, UploaderItemArea, UploaderTitleWrapper, Uploader, 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, Dialog, DialogTitle, DialogContent, WaitingButton, LinearProgress, H2, ThemeProvider, defaultTheme, Preview, Blank, Popover, Expander, darkTheme, UploaderItemArea, UploaderTitleWrapper, Uploader, 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';
|
|
@@ -4825,22 +4825,28 @@ const SERVER_NOTIFICATION_EVENT = {
|
|
|
4825
4825
|
const usePythonTask = () => {
|
|
4826
4826
|
const { api, t } = useGlobalContext();
|
|
4827
4827
|
const { addSubscription, connection, unsubscribeById } = useServerNotificationsContext();
|
|
4828
|
+
const [status, setStatus] = useState(RemoteTaskStatus.Unknown);
|
|
4828
4829
|
const [result, setResult] = useState(null);
|
|
4829
4830
|
const [error, setError] = useState(null);
|
|
4830
4831
|
const [loading, setLoading] = useState(false);
|
|
4831
4832
|
const [executionTime, setExecutionTime] = useState(null);
|
|
4832
4833
|
const [taskId, setTaskId] = useState(null);
|
|
4833
4834
|
const [subscriptionId, setSubscriptionId] = useState(null);
|
|
4835
|
+
const [isLogDialogOpen, setIsLogDialogOpen] = useState(false);
|
|
4836
|
+
const resultRef = useRef(null);
|
|
4834
4837
|
const reset = useCallback(() => {
|
|
4835
|
-
|
|
4838
|
+
setStatus(RemoteTaskStatus.Unknown);
|
|
4836
4839
|
setError(null);
|
|
4837
|
-
setLoading(
|
|
4840
|
+
setLoading(false);
|
|
4838
4841
|
setExecutionTime(null);
|
|
4839
4842
|
setTaskId(null);
|
|
4840
4843
|
setSubscriptionId(null);
|
|
4841
4844
|
}, []);
|
|
4842
4845
|
const runTask = useCallback(async ({ resourceId, parameters, script, fileName, methodName, }) => {
|
|
4843
4846
|
reset();
|
|
4847
|
+
setStatus(RemoteTaskStatus.Process);
|
|
4848
|
+
setResult(null);
|
|
4849
|
+
setLoading(true);
|
|
4844
4850
|
const start = Date.now();
|
|
4845
4851
|
let prototypeId = await api.remoteTaskManager.createTaskPrototype({
|
|
4846
4852
|
enabled: true,
|
|
@@ -4863,6 +4869,7 @@ const usePythonTask = () => {
|
|
|
4863
4869
|
prototypeId = prototypeId.replace(/["']+/g, "");
|
|
4864
4870
|
const { id: newTaskId, success } = await api.remoteTaskManager.startTask1(prototypeId);
|
|
4865
4871
|
if (!success) {
|
|
4872
|
+
setStatus(RemoteTaskStatus.Error);
|
|
4866
4873
|
setResult(t("taskRunFail", { ns: "devMode", defaultValue: "Не удалось запустить задачу" }));
|
|
4867
4874
|
setExecutionTime(Date.now() - start);
|
|
4868
4875
|
setLoading(false);
|
|
@@ -4875,7 +4882,8 @@ const usePythonTask = () => {
|
|
|
4875
4882
|
setSubscriptionId(newSubscriptionId);
|
|
4876
4883
|
const onNotification = ({ data }) => {
|
|
4877
4884
|
if (data?.taskId === newTaskId) {
|
|
4878
|
-
|
|
4885
|
+
setStatus(data.status);
|
|
4886
|
+
setResult([data.log, resultRef.current].filter(Boolean).join("\n\n"));
|
|
4879
4887
|
setError(null);
|
|
4880
4888
|
setExecutionTime(Date.now() - start);
|
|
4881
4889
|
setLoading(false);
|
|
@@ -4898,7 +4906,28 @@ const usePythonTask = () => {
|
|
|
4898
4906
|
reset();
|
|
4899
4907
|
unsubscribeById(subscriptionId);
|
|
4900
4908
|
}, [api, reset, unsubscribeById, taskId, subscriptionId]);
|
|
4901
|
-
|
|
4909
|
+
const openLog = useCallback(() => {
|
|
4910
|
+
setIsLogDialogOpen(true);
|
|
4911
|
+
}, []);
|
|
4912
|
+
const closeLog = useCallback(() => {
|
|
4913
|
+
setIsLogDialogOpen(false);
|
|
4914
|
+
}, []);
|
|
4915
|
+
useEffect(() => {
|
|
4916
|
+
resultRef.current = result;
|
|
4917
|
+
}, [result]);
|
|
4918
|
+
return {
|
|
4919
|
+
taskId,
|
|
4920
|
+
runTask,
|
|
4921
|
+
stopTask,
|
|
4922
|
+
openLog,
|
|
4923
|
+
result,
|
|
4924
|
+
error,
|
|
4925
|
+
status,
|
|
4926
|
+
loading,
|
|
4927
|
+
executionTime,
|
|
4928
|
+
isLogDialogOpen,
|
|
4929
|
+
closeLog,
|
|
4930
|
+
};
|
|
4902
4931
|
};
|
|
4903
4932
|
|
|
4904
4933
|
const useAppHeight = () => {
|
|
@@ -6730,13 +6759,83 @@ const UploadContainer = memo(({ type, elementConfig, renderElement }) => {
|
|
|
6730
6759
|
return (jsxs(Fragment$1, { children: [jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && renderElement({ id: "uploader", wrap: false })] }));
|
|
6731
6760
|
});
|
|
6732
6761
|
|
|
6762
|
+
const StatusBadge = styled(Flex) `
|
|
6763
|
+
margin-bottom: 1rem;
|
|
6764
|
+
padding: 0.5rem 1rem;
|
|
6765
|
+
background-color: ${({ $statusColor }) => $statusColor};
|
|
6766
|
+
color: ${({ theme }) => theme.palette.iconContrast};
|
|
6767
|
+
border-radius: 0.25rem;
|
|
6768
|
+
`;
|
|
6769
|
+
const LogContainer = styled.div `
|
|
6770
|
+
flex: 1;
|
|
6771
|
+
padding: 1rem;
|
|
6772
|
+
background-color: ${({ theme }) => theme.palette.element};
|
|
6773
|
+
color: ${({ theme }) => theme.palette.textPrimary};
|
|
6774
|
+
font-family: monospace;
|
|
6775
|
+
font-size: 0.875rem;
|
|
6776
|
+
overflow: auto;
|
|
6777
|
+
white-space: pre-wrap;
|
|
6778
|
+
word-break: break-word;
|
|
6779
|
+
border-radius: 0.25rem;
|
|
6780
|
+
max-height: 31.25rem;
|
|
6781
|
+
`;
|
|
6782
|
+
|
|
6783
|
+
const STATUS_TRANSLATION_KEYS = {
|
|
6784
|
+
[RemoteTaskStatus.Process]: "task.status.process",
|
|
6785
|
+
[RemoteTaskStatus.Completed]: "task.status.completed",
|
|
6786
|
+
[RemoteTaskStatus.Error]: "task.status.error",
|
|
6787
|
+
[RemoteTaskStatus.Unknown]: "task.status.unknown",
|
|
6788
|
+
};
|
|
6789
|
+
const STATUS_DEFAULT_VALUES = {
|
|
6790
|
+
[RemoteTaskStatus.Process]: "Выполняется...",
|
|
6791
|
+
[RemoteTaskStatus.Completed]: "Завершено",
|
|
6792
|
+
[RemoteTaskStatus.Error]: "Ошибка",
|
|
6793
|
+
[RemoteTaskStatus.Unknown]: "Неизвестно",
|
|
6794
|
+
};
|
|
6795
|
+
const STATUS_COLORS = {
|
|
6796
|
+
[RemoteTaskStatus.Process]: "#2196f3",
|
|
6797
|
+
[RemoteTaskStatus.Completed]: "#4caf50",
|
|
6798
|
+
[RemoteTaskStatus.Error]: "#f44336",
|
|
6799
|
+
[RemoteTaskStatus.Unknown]: "#757575",
|
|
6800
|
+
};
|
|
6801
|
+
|
|
6802
|
+
const LogDialog = ({ isOpen, onClose, logs, status, statusColors }) => {
|
|
6803
|
+
const { t } = useGlobalContext();
|
|
6804
|
+
const contentRef = useRef(null);
|
|
6805
|
+
useEffect(() => {
|
|
6806
|
+
if (contentRef.current) {
|
|
6807
|
+
contentRef.current.scrollTop = 0;
|
|
6808
|
+
}
|
|
6809
|
+
}, [logs]);
|
|
6810
|
+
const getStatusText = useCallback((status) => {
|
|
6811
|
+
const translationKey = STATUS_TRANSLATION_KEYS[status] || STATUS_TRANSLATION_KEYS[RemoteTaskStatus.Unknown];
|
|
6812
|
+
const defaultValue = STATUS_DEFAULT_VALUES[status] || STATUS_DEFAULT_VALUES[RemoteTaskStatus.Unknown];
|
|
6813
|
+
return t(translationKey, { ns: "dashboard", defaultValue });
|
|
6814
|
+
}, [t]);
|
|
6815
|
+
const getStatusColor = useCallback((status) => {
|
|
6816
|
+
return statusColors?.[status] || STATUS_COLORS[status] || STATUS_COLORS[RemoteTaskStatus.Unknown];
|
|
6817
|
+
}, [statusColors]);
|
|
6818
|
+
return (jsxs(Dialog, { isOpen: isOpen, onCloseRequest: onClose, modal: true, maxWidth: "800px", minWidth: "600px", minHeight: "400px", children: [jsx(DialogTitle, { children: jsxs(Flex, { justifyContent: "space-between", alignItems: "center", children: [jsx("span", { children: t("task.logs.title", { ns: "dashboard", defaultValue: "Логи выполнения задачи" }) }), jsx(IconButton, { kind: "close", onClick: onClose })] }) }), jsx(DialogContent, { children: jsxs(Flex, { flexDirection: "column", height: "100%", marginBottom: "2rem", children: [jsxs(StatusBadge, { "$statusColor": getStatusColor(status), children: [t("task.status.label", { ns: "dashboard", defaultValue: "Статус" }), ": ", getStatusText(status)] }), jsx(LogContainer, { ref: contentRef, children: logs || t("task.logs.empty", { ns: "dashboard", defaultValue: "Логи отсутствуют" }) })] }) })] }));
|
|
6819
|
+
};
|
|
6820
|
+
|
|
6821
|
+
const StatusWaitingButton = styled(WaitingButton) `
|
|
6822
|
+
${({ status = RemoteTaskStatus.Unknown, statusColors }) => !!statusColors?.[status] && css `
|
|
6823
|
+
transition: background-color ${transition.toggle};
|
|
6824
|
+
background-color: ${statusColors[status]};
|
|
6825
|
+
|
|
6826
|
+
:hover {
|
|
6827
|
+
background-color: ${statusColors[status]};
|
|
6828
|
+
}
|
|
6829
|
+
`}
|
|
6830
|
+
`;
|
|
6831
|
+
|
|
6733
6832
|
const TaskContainer = memo(({ type, elementConfig }) => {
|
|
6734
6833
|
const { t, ewktGeometry } = useGlobalContext();
|
|
6735
6834
|
const { dataSources, filters: selectedFilters } = useWidgetContext(type);
|
|
6736
6835
|
const { currentPage } = useWidgetPage(type);
|
|
6737
|
-
const { runTask, loading } = usePythonTask();
|
|
6836
|
+
const { taskId, runTask, stopTask, status, openLog, loading, isLogDialogOpen, closeLog, result } = usePythonTask();
|
|
6738
6837
|
const { options } = elementConfig || {};
|
|
6739
|
-
const { title, relatedResources, center, icon } = options || {};
|
|
6838
|
+
const { title, relatedResources, center, icon, statusColors } = options || {};
|
|
6740
6839
|
const onClick = useCallback(async () => {
|
|
6741
6840
|
await Promise.all(relatedResources.map(({ resourceId, parameters, script, fileName, methodName }) => {
|
|
6742
6841
|
const newParams = applyQueryFilters({
|
|
@@ -6749,7 +6848,7 @@ const TaskContainer = memo(({ type, elementConfig }) => {
|
|
|
6749
6848
|
return runTask({ resourceId, parameters: newParams, script, fileName, methodName });
|
|
6750
6849
|
}));
|
|
6751
6850
|
}, [currentPage.filters, dataSources, ewktGeometry, relatedResources, runTask, selectedFilters]);
|
|
6752
|
-
return (jsx(Flex, { justifyContent: center ? "center" : "flex-start", children: jsxs(
|
|
6851
|
+
return (jsx(Fragment$1, { children: jsxs(Flex, { justifyContent: center ? "center" : "flex-start", children: [jsxs(StatusWaitingButton, { primary: true, status: status, statusColors: statusColors, isWaiting: loading, disabled: !relatedResources?.length, onClick: onClick, children: [icon && jsx(FlexSpan, { marginRight: "0.5rem", children: jsx(Icon, { kind: icon }) }), title || t("run", { ns: "dashboard", defaultValue: "Запуск" })] }), !!taskId && (jsx(IconButton, { kind: "stop", onClick: stopTask })), !!result && (jsxs(Fragment$1, { children: [jsx(IconButton, { kind: "info", onClick: openLog }), jsx(LogDialog, { isOpen: isLogDialogOpen, onClose: closeLog, logs: result, status: status, statusColors: statusColors })] }))] }) }));
|
|
6753
6852
|
});
|
|
6754
6853
|
|
|
6755
6854
|
const containerComponents = {
|