@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/components/Dashboard/containers/TaskContainer/components/LogDialog/constants.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { RemoteTaskStatus } from '@evergis/api';
|
|
2
|
+
export declare const STATUS_TRANSLATION_KEYS: Partial<Record<RemoteTaskStatus, string>>;
|
|
3
|
+
export declare const STATUS_DEFAULT_VALUES: Partial<Record<RemoteTaskStatus, string>>;
|
|
4
|
+
export declare const STATUS_COLORS: Partial<Record<RemoteTaskStatus, string>>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { RemoteTaskStatus } from '@evergis/api';
|
|
2
|
+
export declare const StatusWaitingButton: import('styled-components').StyledComponent<import('react').FC<import('@evergis/uilib-gl').IWaitingButton>, any, {
|
|
3
|
+
status?: RemoteTaskStatus;
|
|
4
|
+
statusColors?: Record<RemoteTaskStatus, string>;
|
|
5
|
+
}, never>;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { CSSProperties, FC, ReactNode } from 'react';
|
|
2
2
|
import { Projection } from 'mapbox-gl';
|
|
3
|
-
import {
|
|
3
|
+
import { i18n } from 'i18next';
|
|
4
|
+
import { AttributeDefinitionDc, AttributeFormatDefinitionDc, AttributeType, EqlRequestDc, FeatureDc, GeometryType, PagedFeaturesListDc, PositionDc, RemoteTaskStatus, StringSubType } from '@evergis/api';
|
|
4
5
|
import { PieChartData, BarChartMarker } from '@evergis/charts';
|
|
5
6
|
import { IOption } from '@evergis/uilib-gl';
|
|
6
7
|
import { FeatureAttributeValue, EditGeometryType, LayerInfo, ThemeName } from '../../types';
|
|
7
8
|
import { InnerContainerProps } from './containers/DataSourceInnerContainer/types';
|
|
8
|
-
import { i18n } from 'i18next';
|
|
9
9
|
export interface DashboardsProps {
|
|
10
10
|
zIndex?: CSSProperties["zIndex"];
|
|
11
11
|
}
|
|
@@ -46,6 +46,7 @@ export interface ConfigOptions {
|
|
|
46
46
|
relatedDataSources?: ConfigRelatedDataSource[];
|
|
47
47
|
relatedAttributes?: ConfigRelatedAttribute[];
|
|
48
48
|
relatedResources?: ConfigRelatedResource[];
|
|
49
|
+
statusColors?: Record<RemoteTaskStatus, string>;
|
|
49
50
|
chartType?: "bar" | "line" | "pie" | "stack";
|
|
50
51
|
layerNames?: string[];
|
|
51
52
|
layerName?: string;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { RemoteTaskStatus } from '@evergis/api';
|
|
1
2
|
export declare const usePythonTask: () => {
|
|
3
|
+
taskId: string;
|
|
2
4
|
runTask: ({ resourceId, parameters, script, fileName, methodName, }: {
|
|
3
5
|
resourceId: string;
|
|
4
6
|
parameters: Record<string, unknown>;
|
|
@@ -7,8 +9,12 @@ export declare const usePythonTask: () => {
|
|
|
7
9
|
methodName?: string;
|
|
8
10
|
}) => Promise<void>;
|
|
9
11
|
stopTask: () => Promise<void>;
|
|
12
|
+
openLog: () => void;
|
|
10
13
|
result: string;
|
|
11
14
|
error: Error;
|
|
15
|
+
status: RemoteTaskStatus;
|
|
12
16
|
loading: boolean;
|
|
13
17
|
executionTime: number;
|
|
18
|
+
isLogDialogOpen: boolean;
|
|
19
|
+
closeLog: () => void;
|
|
14
20
|
};
|
package/dist/index.js
CHANGED
|
@@ -4827,22 +4827,28 @@ const SERVER_NOTIFICATION_EVENT = {
|
|
|
4827
4827
|
const usePythonTask = () => {
|
|
4828
4828
|
const { api: api$1, t } = useGlobalContext();
|
|
4829
4829
|
const { addSubscription, connection, unsubscribeById } = useServerNotificationsContext();
|
|
4830
|
+
const [status, setStatus] = React.useState(api.RemoteTaskStatus.Unknown);
|
|
4830
4831
|
const [result, setResult] = React.useState(null);
|
|
4831
4832
|
const [error, setError] = React.useState(null);
|
|
4832
4833
|
const [loading, setLoading] = React.useState(false);
|
|
4833
4834
|
const [executionTime, setExecutionTime] = React.useState(null);
|
|
4834
4835
|
const [taskId, setTaskId] = React.useState(null);
|
|
4835
4836
|
const [subscriptionId, setSubscriptionId] = React.useState(null);
|
|
4837
|
+
const [isLogDialogOpen, setIsLogDialogOpen] = React.useState(false);
|
|
4838
|
+
const resultRef = React.useRef(null);
|
|
4836
4839
|
const reset = React.useCallback(() => {
|
|
4837
|
-
|
|
4840
|
+
setStatus(api.RemoteTaskStatus.Unknown);
|
|
4838
4841
|
setError(null);
|
|
4839
|
-
setLoading(
|
|
4842
|
+
setLoading(false);
|
|
4840
4843
|
setExecutionTime(null);
|
|
4841
4844
|
setTaskId(null);
|
|
4842
4845
|
setSubscriptionId(null);
|
|
4843
4846
|
}, []);
|
|
4844
4847
|
const runTask = React.useCallback(async ({ resourceId, parameters, script, fileName, methodName, }) => {
|
|
4845
4848
|
reset();
|
|
4849
|
+
setStatus(api.RemoteTaskStatus.Process);
|
|
4850
|
+
setResult(null);
|
|
4851
|
+
setLoading(true);
|
|
4846
4852
|
const start = Date.now();
|
|
4847
4853
|
let prototypeId = await api$1.remoteTaskManager.createTaskPrototype({
|
|
4848
4854
|
enabled: true,
|
|
@@ -4865,6 +4871,7 @@ const usePythonTask = () => {
|
|
|
4865
4871
|
prototypeId = prototypeId.replace(/["']+/g, "");
|
|
4866
4872
|
const { id: newTaskId, success } = await api$1.remoteTaskManager.startTask1(prototypeId);
|
|
4867
4873
|
if (!success) {
|
|
4874
|
+
setStatus(api.RemoteTaskStatus.Error);
|
|
4868
4875
|
setResult(t("taskRunFail", { ns: "devMode", defaultValue: "Не удалось запустить задачу" }));
|
|
4869
4876
|
setExecutionTime(Date.now() - start);
|
|
4870
4877
|
setLoading(false);
|
|
@@ -4877,7 +4884,8 @@ const usePythonTask = () => {
|
|
|
4877
4884
|
setSubscriptionId(newSubscriptionId);
|
|
4878
4885
|
const onNotification = ({ data }) => {
|
|
4879
4886
|
if (data?.taskId === newTaskId) {
|
|
4880
|
-
|
|
4887
|
+
setStatus(data.status);
|
|
4888
|
+
setResult([data.log, resultRef.current].filter(Boolean).join("\n\n"));
|
|
4881
4889
|
setError(null);
|
|
4882
4890
|
setExecutionTime(Date.now() - start);
|
|
4883
4891
|
setLoading(false);
|
|
@@ -4900,7 +4908,28 @@ const usePythonTask = () => {
|
|
|
4900
4908
|
reset();
|
|
4901
4909
|
unsubscribeById(subscriptionId);
|
|
4902
4910
|
}, [api$1, reset, unsubscribeById, taskId, subscriptionId]);
|
|
4903
|
-
|
|
4911
|
+
const openLog = React.useCallback(() => {
|
|
4912
|
+
setIsLogDialogOpen(true);
|
|
4913
|
+
}, []);
|
|
4914
|
+
const closeLog = React.useCallback(() => {
|
|
4915
|
+
setIsLogDialogOpen(false);
|
|
4916
|
+
}, []);
|
|
4917
|
+
React.useEffect(() => {
|
|
4918
|
+
resultRef.current = result;
|
|
4919
|
+
}, [result]);
|
|
4920
|
+
return {
|
|
4921
|
+
taskId,
|
|
4922
|
+
runTask,
|
|
4923
|
+
stopTask,
|
|
4924
|
+
openLog,
|
|
4925
|
+
result,
|
|
4926
|
+
error,
|
|
4927
|
+
status,
|
|
4928
|
+
loading,
|
|
4929
|
+
executionTime,
|
|
4930
|
+
isLogDialogOpen,
|
|
4931
|
+
closeLog,
|
|
4932
|
+
};
|
|
4904
4933
|
};
|
|
4905
4934
|
|
|
4906
4935
|
const useAppHeight = () => {
|
|
@@ -6732,13 +6761,83 @@ const UploadContainer = React.memo(({ type, elementConfig, renderElement }) => {
|
|
|
6732
6761
|
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && renderElement({ id: "uploader", wrap: false })] }));
|
|
6733
6762
|
});
|
|
6734
6763
|
|
|
6764
|
+
const StatusBadge = styled(uilibGl.Flex) `
|
|
6765
|
+
margin-bottom: 1rem;
|
|
6766
|
+
padding: 0.5rem 1rem;
|
|
6767
|
+
background-color: ${({ $statusColor }) => $statusColor};
|
|
6768
|
+
color: ${({ theme }) => theme.palette.iconContrast};
|
|
6769
|
+
border-radius: 0.25rem;
|
|
6770
|
+
`;
|
|
6771
|
+
const LogContainer = styled.div `
|
|
6772
|
+
flex: 1;
|
|
6773
|
+
padding: 1rem;
|
|
6774
|
+
background-color: ${({ theme }) => theme.palette.element};
|
|
6775
|
+
color: ${({ theme }) => theme.palette.textPrimary};
|
|
6776
|
+
font-family: monospace;
|
|
6777
|
+
font-size: 0.875rem;
|
|
6778
|
+
overflow: auto;
|
|
6779
|
+
white-space: pre-wrap;
|
|
6780
|
+
word-break: break-word;
|
|
6781
|
+
border-radius: 0.25rem;
|
|
6782
|
+
max-height: 31.25rem;
|
|
6783
|
+
`;
|
|
6784
|
+
|
|
6785
|
+
const STATUS_TRANSLATION_KEYS = {
|
|
6786
|
+
[api.RemoteTaskStatus.Process]: "task.status.process",
|
|
6787
|
+
[api.RemoteTaskStatus.Completed]: "task.status.completed",
|
|
6788
|
+
[api.RemoteTaskStatus.Error]: "task.status.error",
|
|
6789
|
+
[api.RemoteTaskStatus.Unknown]: "task.status.unknown",
|
|
6790
|
+
};
|
|
6791
|
+
const STATUS_DEFAULT_VALUES = {
|
|
6792
|
+
[api.RemoteTaskStatus.Process]: "Выполняется...",
|
|
6793
|
+
[api.RemoteTaskStatus.Completed]: "Завершено",
|
|
6794
|
+
[api.RemoteTaskStatus.Error]: "Ошибка",
|
|
6795
|
+
[api.RemoteTaskStatus.Unknown]: "Неизвестно",
|
|
6796
|
+
};
|
|
6797
|
+
const STATUS_COLORS = {
|
|
6798
|
+
[api.RemoteTaskStatus.Process]: "#2196f3",
|
|
6799
|
+
[api.RemoteTaskStatus.Completed]: "#4caf50",
|
|
6800
|
+
[api.RemoteTaskStatus.Error]: "#f44336",
|
|
6801
|
+
[api.RemoteTaskStatus.Unknown]: "#757575",
|
|
6802
|
+
};
|
|
6803
|
+
|
|
6804
|
+
const LogDialog = ({ isOpen, onClose, logs, status, statusColors }) => {
|
|
6805
|
+
const { t } = useGlobalContext();
|
|
6806
|
+
const contentRef = React.useRef(null);
|
|
6807
|
+
React.useEffect(() => {
|
|
6808
|
+
if (contentRef.current) {
|
|
6809
|
+
contentRef.current.scrollTop = 0;
|
|
6810
|
+
}
|
|
6811
|
+
}, [logs]);
|
|
6812
|
+
const getStatusText = React.useCallback((status) => {
|
|
6813
|
+
const translationKey = STATUS_TRANSLATION_KEYS[status] || STATUS_TRANSLATION_KEYS[api.RemoteTaskStatus.Unknown];
|
|
6814
|
+
const defaultValue = STATUS_DEFAULT_VALUES[status] || STATUS_DEFAULT_VALUES[api.RemoteTaskStatus.Unknown];
|
|
6815
|
+
return t(translationKey, { ns: "dashboard", defaultValue });
|
|
6816
|
+
}, [t]);
|
|
6817
|
+
const getStatusColor = React.useCallback((status) => {
|
|
6818
|
+
return statusColors?.[status] || STATUS_COLORS[status] || STATUS_COLORS[api.RemoteTaskStatus.Unknown];
|
|
6819
|
+
}, [statusColors]);
|
|
6820
|
+
return (jsxRuntime.jsxs(uilibGl.Dialog, { isOpen: isOpen, onCloseRequest: onClose, modal: true, maxWidth: "800px", minWidth: "600px", minHeight: "400px", children: [jsxRuntime.jsx(uilibGl.DialogTitle, { children: jsxRuntime.jsxs(uilibGl.Flex, { justifyContent: "space-between", alignItems: "center", children: [jsxRuntime.jsx("span", { children: t("task.logs.title", { ns: "dashboard", defaultValue: "Логи выполнения задачи" }) }), jsxRuntime.jsx(uilibGl.IconButton, { kind: "close", onClick: onClose })] }) }), jsxRuntime.jsx(uilibGl.DialogContent, { children: jsxRuntime.jsxs(uilibGl.Flex, { flexDirection: "column", height: "100%", marginBottom: "2rem", children: [jsxRuntime.jsxs(StatusBadge, { "$statusColor": getStatusColor(status), children: [t("task.status.label", { ns: "dashboard", defaultValue: "Статус" }), ": ", getStatusText(status)] }), jsxRuntime.jsx(LogContainer, { ref: contentRef, children: logs || t("task.logs.empty", { ns: "dashboard", defaultValue: "Логи отсутствуют" }) })] }) })] }));
|
|
6821
|
+
};
|
|
6822
|
+
|
|
6823
|
+
const StatusWaitingButton = styled(uilibGl.WaitingButton) `
|
|
6824
|
+
${({ status = api.RemoteTaskStatus.Unknown, statusColors }) => !!statusColors?.[status] && styled.css `
|
|
6825
|
+
transition: background-color ${uilibGl.transition.toggle};
|
|
6826
|
+
background-color: ${statusColors[status]};
|
|
6827
|
+
|
|
6828
|
+
:hover {
|
|
6829
|
+
background-color: ${statusColors[status]};
|
|
6830
|
+
}
|
|
6831
|
+
`}
|
|
6832
|
+
`;
|
|
6833
|
+
|
|
6735
6834
|
const TaskContainer = React.memo(({ type, elementConfig }) => {
|
|
6736
6835
|
const { t, ewktGeometry } = useGlobalContext();
|
|
6737
6836
|
const { dataSources, filters: selectedFilters } = useWidgetContext(type);
|
|
6738
6837
|
const { currentPage } = useWidgetPage(type);
|
|
6739
|
-
const { runTask, loading } = usePythonTask();
|
|
6838
|
+
const { taskId, runTask, stopTask, status, openLog, loading, isLogDialogOpen, closeLog, result } = usePythonTask();
|
|
6740
6839
|
const { options } = elementConfig || {};
|
|
6741
|
-
const { title, relatedResources, center, icon } = options || {};
|
|
6840
|
+
const { title, relatedResources, center, icon, statusColors } = options || {};
|
|
6742
6841
|
const onClick = React.useCallback(async () => {
|
|
6743
6842
|
await Promise.all(relatedResources.map(({ resourceId, parameters, script, fileName, methodName }) => {
|
|
6744
6843
|
const newParams = applyQueryFilters({
|
|
@@ -6751,7 +6850,7 @@ const TaskContainer = React.memo(({ type, elementConfig }) => {
|
|
|
6751
6850
|
return runTask({ resourceId, parameters: newParams, script, fileName, methodName });
|
|
6752
6851
|
}));
|
|
6753
6852
|
}, [currentPage.filters, dataSources, ewktGeometry, relatedResources, runTask, selectedFilters]);
|
|
6754
|
-
return (jsxRuntime.jsx(uilibGl.Flex, { justifyContent: center ? "center" : "flex-start", children: jsxRuntime.jsxs(
|
|
6853
|
+
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs(uilibGl.Flex, { justifyContent: center ? "center" : "flex-start", children: [jsxRuntime.jsxs(StatusWaitingButton, { primary: true, status: status, statusColors: statusColors, isWaiting: loading, disabled: !relatedResources?.length, onClick: onClick, children: [icon && jsxRuntime.jsx(uilibGl.FlexSpan, { marginRight: "0.5rem", children: jsxRuntime.jsx(uilibGl.Icon, { kind: icon }) }), title || t("run", { ns: "dashboard", defaultValue: "Запуск" })] }), !!taskId && (jsxRuntime.jsx(uilibGl.IconButton, { kind: "stop", onClick: stopTask })), !!result && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(uilibGl.IconButton, { kind: "info", onClick: openLog }), jsxRuntime.jsx(LogDialog, { isOpen: isLogDialogOpen, onClose: closeLog, logs: result, status: status, statusColors: statusColors })] }))] }) }));
|
|
6755
6854
|
});
|
|
6756
6855
|
|
|
6757
6856
|
const containerComponents = {
|