@evergis/react 3.1.50 → 3.1.51
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/index.d.ts +3 -0
- package/dist/components/Dashboard/containers/TaskContainer/styled.d.ts +2 -0
- package/dist/components/Dashboard/containers/UploadContainer/index.d.ts +3 -0
- package/dist/components/Dashboard/containers/UploadContainer/styled.d.ts +2 -0
- package/dist/components/Dashboard/containers/index.d.ts +1 -0
- package/dist/components/Dashboard/containers/registry.d.ts +2 -0
- package/dist/components/Dashboard/types.d.ts +10 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/task/constants.d.ts +4 -0
- package/dist/hooks/task/index.d.ts +3 -0
- package/dist/hooks/task/types.d.ts +16 -0
- package/dist/hooks/task/usePythonTask.d.ts +12 -0
- package/dist/index.js +181 -0
- package/dist/index.js.map +1 -1
- package/dist/react.esm.js +181 -3
- package/dist/react.esm.js.map +1 -1
- package/package.json +4 -4
|
@@ -27,5 +27,7 @@ export declare const containerComponents: {
|
|
|
27
27
|
readonly AddFeature: import('react').FC<import('../types').ContainerProps>;
|
|
28
28
|
readonly Divider: import('react').FC<import('../types').ContainerProps>;
|
|
29
29
|
readonly ExportPdf: import('react').FC<import('../types').ContainerProps>;
|
|
30
|
+
readonly Upload: import('react').FC<import('../types').ContainerProps>;
|
|
31
|
+
readonly Task: import('react').FC<import('../types').ContainerProps>;
|
|
30
32
|
readonly default: import('react').FC<import('../types').ContainerProps>;
|
|
31
33
|
};
|
|
@@ -27,6 +27,11 @@ export interface ConfigRelatedDataSource {
|
|
|
27
27
|
hideAxis?: boolean;
|
|
28
28
|
filterName?: string;
|
|
29
29
|
}
|
|
30
|
+
export interface ConfigRelatedResource {
|
|
31
|
+
resourceId: string;
|
|
32
|
+
parameters: Record<string, unknown>;
|
|
33
|
+
script?: string;
|
|
34
|
+
}
|
|
30
35
|
export interface BaseMapSettings {
|
|
31
36
|
opacity?: number;
|
|
32
37
|
showBuildings?: boolean;
|
|
@@ -38,10 +43,13 @@ export interface ConfigOptions {
|
|
|
38
43
|
themeName?: ThemeName;
|
|
39
44
|
relatedDataSources?: ConfigRelatedDataSource[];
|
|
40
45
|
relatedAttributes?: ConfigRelatedAttribute[];
|
|
46
|
+
relatedResources?: ConfigRelatedResource[];
|
|
41
47
|
chartType?: "bar" | "line" | "pie" | "stack";
|
|
42
48
|
layerNames?: string[];
|
|
43
49
|
layerName?: string;
|
|
44
50
|
geometryType?: GeometryType | EditGeometryType;
|
|
51
|
+
fileExtensions?: string;
|
|
52
|
+
parentResourceId?: string;
|
|
45
53
|
srid?: string;
|
|
46
54
|
title?: string;
|
|
47
55
|
label?: string;
|
|
@@ -253,6 +261,8 @@ export declare enum ContainerTemplate {
|
|
|
253
261
|
AddFeature = "AddFeature",
|
|
254
262
|
Slideshow = "Slideshow",
|
|
255
263
|
ExportPdf = "ExportPdf",
|
|
264
|
+
Upload = "Upload",
|
|
265
|
+
Task = "Task",
|
|
256
266
|
Divider = "Divider"
|
|
257
267
|
}
|
|
258
268
|
export declare enum HeaderTemplate {
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { RemoteTaskStatus } from '@evergis/api';
|
|
2
|
+
export interface PythonTaskProgressSubscription {
|
|
3
|
+
tag: "python_task_progress_event";
|
|
4
|
+
taskId: string;
|
|
5
|
+
}
|
|
6
|
+
export interface PythonTaskProgressNotification {
|
|
7
|
+
data: {
|
|
8
|
+
log: string;
|
|
9
|
+
progress: number;
|
|
10
|
+
status: RemoteTaskStatus;
|
|
11
|
+
subTaskId?: string;
|
|
12
|
+
taskId: string;
|
|
13
|
+
};
|
|
14
|
+
tag: string;
|
|
15
|
+
createdAt: string;
|
|
16
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const usePythonTask: () => {
|
|
2
|
+
runTask: ({ resourceId, parameters, script, }: {
|
|
3
|
+
resourceId: string;
|
|
4
|
+
parameters: Record<string, unknown>;
|
|
5
|
+
script: string;
|
|
6
|
+
}) => Promise<void>;
|
|
7
|
+
stopTask: () => Promise<void>;
|
|
8
|
+
result: string;
|
|
9
|
+
error: Error;
|
|
10
|
+
loading: boolean;
|
|
11
|
+
executionTime: number;
|
|
12
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -3382,6 +3382,8 @@ exports.ContainerTemplate = void 0;
|
|
|
3382
3382
|
ContainerTemplate["AddFeature"] = "AddFeature";
|
|
3383
3383
|
ContainerTemplate["Slideshow"] = "Slideshow";
|
|
3384
3384
|
ContainerTemplate["ExportPdf"] = "ExportPdf";
|
|
3385
|
+
ContainerTemplate["Upload"] = "Upload";
|
|
3386
|
+
ContainerTemplate["Task"] = "Task";
|
|
3385
3387
|
ContainerTemplate["Divider"] = "Divider";
|
|
3386
3388
|
})(exports.ContainerTemplate || (exports.ContainerTemplate = {}));
|
|
3387
3389
|
exports.HeaderTemplate = void 0;
|
|
@@ -4994,6 +4996,88 @@ const useServerNotificationsContext = () => {
|
|
|
4994
4996
|
return React.useContext(ServerNotificationsContext);
|
|
4995
4997
|
};
|
|
4996
4998
|
|
|
4999
|
+
const SERVER_NOTIFICATION_EVENT = {
|
|
5000
|
+
ReceiveFeaturesUpdate: "ReceiveFeaturesUpdateNotification",
|
|
5001
|
+
PythonProgressNotification: "ReceivePythonProgressNotification",
|
|
5002
|
+
};
|
|
5003
|
+
|
|
5004
|
+
const usePythonTask = () => {
|
|
5005
|
+
const { api: api$1, t } = useGlobalContext();
|
|
5006
|
+
const { addSubscription, connection, unsubscribeById } = useServerNotificationsContext();
|
|
5007
|
+
const [result, setResult] = React.useState(null);
|
|
5008
|
+
const [error, setError] = React.useState(null);
|
|
5009
|
+
const [loading, setLoading] = React.useState(false);
|
|
5010
|
+
const [executionTime, setExecutionTime] = React.useState(null);
|
|
5011
|
+
const [taskId, setTaskId] = React.useState(null);
|
|
5012
|
+
const [subscriptionId, setSubscriptionId] = React.useState(null);
|
|
5013
|
+
const reset = React.useCallback(() => {
|
|
5014
|
+
setResult(null);
|
|
5015
|
+
setError(null);
|
|
5016
|
+
setLoading(true);
|
|
5017
|
+
setExecutionTime(null);
|
|
5018
|
+
setTaskId(null);
|
|
5019
|
+
setSubscriptionId(null);
|
|
5020
|
+
}, []);
|
|
5021
|
+
const runTask = React.useCallback(async ({ resourceId, parameters, script, }) => {
|
|
5022
|
+
reset();
|
|
5023
|
+
const start = Date.now();
|
|
5024
|
+
let prototypeId = await api$1.remoteTaskManager.createTaskPrototype({
|
|
5025
|
+
enabled: true,
|
|
5026
|
+
startIfPreviousError: true,
|
|
5027
|
+
startIfPreviousNotFinished: true,
|
|
5028
|
+
subTaskSettings: [
|
|
5029
|
+
{
|
|
5030
|
+
type: "pythonService",
|
|
5031
|
+
startParameters: {
|
|
5032
|
+
resourceId,
|
|
5033
|
+
parameters,
|
|
5034
|
+
script,
|
|
5035
|
+
method: "pythonrunner/run",
|
|
5036
|
+
},
|
|
5037
|
+
},
|
|
5038
|
+
],
|
|
5039
|
+
});
|
|
5040
|
+
prototypeId = prototypeId.replace(/["']+/g, "");
|
|
5041
|
+
const { id: newTaskId, success } = await api$1.remoteTaskManager.startTask1(prototypeId);
|
|
5042
|
+
if (!success) {
|
|
5043
|
+
setResult(t("taskRunFail", { ns: "devMode", defaultValue: "Не удалось запустить задачу" }));
|
|
5044
|
+
setExecutionTime(Date.now() - start);
|
|
5045
|
+
setLoading(false);
|
|
5046
|
+
}
|
|
5047
|
+
const newSubscriptionId = await addSubscription({
|
|
5048
|
+
tag: "python_task_progress_event",
|
|
5049
|
+
taskId: newTaskId,
|
|
5050
|
+
});
|
|
5051
|
+
setTaskId(newTaskId);
|
|
5052
|
+
setSubscriptionId(newSubscriptionId);
|
|
5053
|
+
const onNotification = ({ data }) => {
|
|
5054
|
+
if (data?.taskId === newTaskId) {
|
|
5055
|
+
setResult(`${data ? `${data}\n` : ""}${data.log || ""}`);
|
|
5056
|
+
setError(null);
|
|
5057
|
+
setExecutionTime(Date.now() - start);
|
|
5058
|
+
setLoading(false);
|
|
5059
|
+
setTaskId([api.RemoteTaskStatus.Completed, api.RemoteTaskStatus.Error].includes(data.status)
|
|
5060
|
+
? undefined
|
|
5061
|
+
: newTaskId);
|
|
5062
|
+
setSubscriptionId([api.RemoteTaskStatus.Completed, api.RemoteTaskStatus.Error].includes(data.status)
|
|
5063
|
+
? undefined
|
|
5064
|
+
: newSubscriptionId);
|
|
5065
|
+
if ([api.RemoteTaskStatus.Completed, api.RemoteTaskStatus.Error].includes(data.status)) {
|
|
5066
|
+
unsubscribeById(newSubscriptionId);
|
|
5067
|
+
connection.off(SERVER_NOTIFICATION_EVENT.PythonProgressNotification, onNotification);
|
|
5068
|
+
}
|
|
5069
|
+
}
|
|
5070
|
+
};
|
|
5071
|
+
connection.on(SERVER_NOTIFICATION_EVENT.PythonProgressNotification, onNotification);
|
|
5072
|
+
}, [api$1, connection, addSubscription, unsubscribeById, reset]);
|
|
5073
|
+
const stopTask = React.useCallback(async () => {
|
|
5074
|
+
await api$1.remoteTaskManager.stop(taskId);
|
|
5075
|
+
reset();
|
|
5076
|
+
unsubscribeById(subscriptionId);
|
|
5077
|
+
}, [api$1, reset, unsubscribeById, taskId, subscriptionId]);
|
|
5078
|
+
return { runTask, stopTask, result, error, loading, executionTime };
|
|
5079
|
+
};
|
|
5080
|
+
|
|
4997
5081
|
const useAppHeight = () => {
|
|
4998
5082
|
React.useEffect(() => {
|
|
4999
5083
|
const setAppHeight = () => {
|
|
@@ -6637,6 +6721,98 @@ const ExportPdfContainer = React.memo(({ type, elementConfig }) => {
|
|
|
6637
6721
|
return (jsxRuntime.jsx(Container, { id: id, style: style, children: jsxRuntime.jsx(uilibGl.IconButton, { kind: icon || "download", primary: true, disabled: loading, onClick: onExport, children: title ?? t("downloadPdf", { ns: "dashboard", defaultValue: "Скачать PDF" }) }) }));
|
|
6638
6722
|
});
|
|
6639
6723
|
|
|
6724
|
+
const UploaderContainer = styled(Container) `
|
|
6725
|
+
${uilibGl.UploaderItemArea} {
|
|
6726
|
+
overflow: visible;
|
|
6727
|
+
padding-top: 1rem;
|
|
6728
|
+
padding-bottom: 1rem;
|
|
6729
|
+
}
|
|
6730
|
+
|
|
6731
|
+
${uilibGl.UploaderTitleWrapper} {
|
|
6732
|
+
top: 0;
|
|
6733
|
+
padding-top: 0;
|
|
6734
|
+
border: 0;
|
|
6735
|
+
}
|
|
6736
|
+
`;
|
|
6737
|
+
const UploaderTitle = styled(uilibGl.Flex) `
|
|
6738
|
+
flex-direction: column;
|
|
6739
|
+
align-items: center;
|
|
6740
|
+
width: 11rem;
|
|
6741
|
+
margin: 0 auto;
|
|
6742
|
+
text-align: center;
|
|
6743
|
+
font-size: 0.625rem;
|
|
6744
|
+
color: ${({ theme: { palette } }) => palette.textSecondary};
|
|
6745
|
+
|
|
6746
|
+
span[kind] {
|
|
6747
|
+
width: 1.5rem;
|
|
6748
|
+
height: 1.5rem;
|
|
6749
|
+
margin-bottom: 0.75rem;
|
|
6750
|
+
|
|
6751
|
+
:after {
|
|
6752
|
+
font-size: 1.5rem;
|
|
6753
|
+
color: ${({ theme: { palette } }) => palette.textSecondary};
|
|
6754
|
+
opacity: 0.12;
|
|
6755
|
+
}
|
|
6756
|
+
}
|
|
6757
|
+
`;
|
|
6758
|
+
|
|
6759
|
+
const DEFAULT_FILE_EXTENSIONS = ".txt,.csv,.py";
|
|
6760
|
+
const UploadContainer = React.memo(({ type, elementConfig, renderElement }) => {
|
|
6761
|
+
const { t, api } = useGlobalContext();
|
|
6762
|
+
const { changeFilters } = useWidgetContext(type);
|
|
6763
|
+
const [files, setFiles] = React.useState([]);
|
|
6764
|
+
const refInput = React.useRef();
|
|
6765
|
+
const { id, style, options } = elementConfig || {};
|
|
6766
|
+
const { icon, title, filterName, fileExtensions = DEFAULT_FILE_EXTENSIONS, parentResourceId, multiSelect } = options || {};
|
|
6767
|
+
const onUpload = React.useCallback(async (input) => {
|
|
6768
|
+
const files = Array.isArray(input) ? input : [input];
|
|
6769
|
+
const response = await Promise.all(files.map(file => {
|
|
6770
|
+
return api.file.upload(file, true, parentResourceId);
|
|
6771
|
+
}));
|
|
6772
|
+
const uploadedFiles = response.map(item => ({
|
|
6773
|
+
name: item.name,
|
|
6774
|
+
id: item.resourceId,
|
|
6775
|
+
done: true,
|
|
6776
|
+
}));
|
|
6777
|
+
setFiles(currentFiles => ([...uploadedFiles, ...currentFiles]));
|
|
6778
|
+
}, [parentResourceId]);
|
|
6779
|
+
const onDelete = React.useCallback(async (id) => {
|
|
6780
|
+
const index = files.findIndex(file => file.id === id);
|
|
6781
|
+
if (index === -1)
|
|
6782
|
+
return;
|
|
6783
|
+
const resourceId = files[index].id;
|
|
6784
|
+
await api.file.deleteResource(resourceId);
|
|
6785
|
+
setFiles(currentFiles => currentFiles.filter(({ id }) => id !== resourceId));
|
|
6786
|
+
}, [files]);
|
|
6787
|
+
const renderTitle = React.useMemo(() => {
|
|
6788
|
+
if (files.length)
|
|
6789
|
+
return null;
|
|
6790
|
+
return (jsxRuntime.jsxs(UploaderTitle, { children: [jsxRuntime.jsx(uilibGl.Icon, { kind: icon || "upload" }), jsxRuntime.jsx("div", { children: title ?? t("uploadTitle", {
|
|
6791
|
+
ns: "dashboard",
|
|
6792
|
+
defaultValue: "Перетащите файл сюда или нажмите, чтобы выбрать",
|
|
6793
|
+
}) })] }));
|
|
6794
|
+
}, [icon, t, title, files.length]);
|
|
6795
|
+
React.useEffect(() => {
|
|
6796
|
+
if (!filterName)
|
|
6797
|
+
return;
|
|
6798
|
+
changeFilters({ [filterName]: { value: files.map(({ id }) => id) } });
|
|
6799
|
+
}, [files]);
|
|
6800
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), jsxRuntime.jsx(UploaderContainer, { id: id, style: style, children: jsxRuntime.jsx(uilibGl.Uploader, { title: renderTitle, accept: fileExtensions, fileItems: files, currentRef: refInput, isMultiple: multiSelect, onUpload: onUpload, onDelete: onDelete }) })] }));
|
|
6801
|
+
});
|
|
6802
|
+
|
|
6803
|
+
const TaskContainer = React.memo(({ elementConfig }) => {
|
|
6804
|
+
const { t } = useGlobalContext();
|
|
6805
|
+
const { runTask, error, result, executionTime, loading } = usePythonTask();
|
|
6806
|
+
const { options } = elementConfig || {};
|
|
6807
|
+
const { title, relatedResources } = options || {};
|
|
6808
|
+
const onClick = React.useCallback(async () => {
|
|
6809
|
+
await Promise.all(relatedResources.map(({ resourceId, parameters, script }) => {
|
|
6810
|
+
return runTask({ resourceId, parameters, script });
|
|
6811
|
+
}));
|
|
6812
|
+
}, [relatedResources, runTask]);
|
|
6813
|
+
return (jsxRuntime.jsx(uilibGl.WaitingButton, { primary: true, isWaiting: loading, disabled: !relatedResources?.length, onClick: onClick, children: title || t("run", { ns: "dashboard", defaultValue: "Запуск" }) }));
|
|
6814
|
+
});
|
|
6815
|
+
|
|
6640
6816
|
const containerComponents = {
|
|
6641
6817
|
[exports.ContainerTemplate.DefaultAttributes]: DefaultAttributesContainer,
|
|
6642
6818
|
[exports.ContainerTemplate.Pages]: PagesContainer,
|
|
@@ -6658,6 +6834,8 @@ const containerComponents = {
|
|
|
6658
6834
|
[exports.ContainerTemplate.AddFeature]: AddFeatureContainer,
|
|
6659
6835
|
[exports.ContainerTemplate.Divider]: DividerContainer,
|
|
6660
6836
|
[exports.ContainerTemplate.ExportPdf]: ExportPdfContainer,
|
|
6837
|
+
[exports.ContainerTemplate.Upload]: UploadContainer,
|
|
6838
|
+
[exports.ContainerTemplate.Task]: TaskContainer,
|
|
6661
6839
|
default: ContainersGroupContainer,
|
|
6662
6840
|
};
|
|
6663
6841
|
|
|
@@ -10699,6 +10877,7 @@ exports.PresentationPanelWrapper = PresentationPanelWrapper;
|
|
|
10699
10877
|
exports.PresentationWrapper = PresentationWrapper;
|
|
10700
10878
|
exports.ProgressContainer = ProgressContainer;
|
|
10701
10879
|
exports.RoundedBackgroundContainer = RoundedBackgroundContainer;
|
|
10880
|
+
exports.SERVER_NOTIFICATION_EVENT = SERVER_NOTIFICATION_EVENT;
|
|
10702
10881
|
exports.ServerNotificationsContext = ServerNotificationsContext;
|
|
10703
10882
|
exports.ServerNotificationsProvider = ServerNotificationsProvider;
|
|
10704
10883
|
exports.SlideshowContainer = SlideshowContainer;
|
|
@@ -10717,6 +10896,7 @@ exports.TitleContainer = TitleContainer;
|
|
|
10717
10896
|
exports.TopContainer = TopContainer;
|
|
10718
10897
|
exports.TopContainerButtons = TopContainerButtons;
|
|
10719
10898
|
exports.TwoColumnContainer = TwoColumnContainer;
|
|
10899
|
+
exports.UploadContainer = UploadContainer;
|
|
10720
10900
|
exports.addDataSource = addDataSource;
|
|
10721
10901
|
exports.addDataSources = addDataSources;
|
|
10722
10902
|
exports.applyFiltersToCondition = applyFiltersToCondition;
|
|
@@ -10825,6 +11005,7 @@ exports.useLayerParams = useLayerParams;
|
|
|
10825
11005
|
exports.useMapContext = useMapContext;
|
|
10826
11006
|
exports.useMapDraw = useMapDraw;
|
|
10827
11007
|
exports.useProjectDashboardInit = useProjectDashboardInit;
|
|
11008
|
+
exports.usePythonTask = usePythonTask;
|
|
10828
11009
|
exports.useRedrawLayer = useRedrawLayer;
|
|
10829
11010
|
exports.useRelatedDataSourceAttributes = useRelatedDataSourceAttributes;
|
|
10830
11011
|
exports.useRenderElement = useRenderElement;
|