@evergis/react 3.1.66 → 3.1.68
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/components/LogTerminal/index.d.ts +6 -0
- package/dist/components/Dashboard/containers/TaskContainer/components/LogTerminal/styled.d.ts +1 -0
- package/dist/hooks/task/usePythonTask.d.ts +4 -1
- package/dist/index.js +214 -17
- package/dist/index.js.map +1 -1
- package/dist/react.esm.js +215 -18
- package/dist/react.esm.js.map +1 -1
- package/package.json +4 -2
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';
|
|
@@ -22,6 +22,9 @@ import 'mapbox-gl/dist/mapbox-gl.css';
|
|
|
22
22
|
import { Swiper, SwiperSlide } from 'swiper/react';
|
|
23
23
|
import ReactMarkdown from 'react-markdown';
|
|
24
24
|
import remarkGfm from 'remark-gfm';
|
|
25
|
+
import { Terminal } from '@xterm/xterm';
|
|
26
|
+
import { FitAddon } from '@xterm/addon-fit';
|
|
27
|
+
import '@xterm/xterm/css/xterm.css';
|
|
25
28
|
|
|
26
29
|
const AddFeatureButton = ({ title, icon = "feature_add" /* , layerName, geometryType*/ }) => {
|
|
27
30
|
// const [, handleAddFeature] = useFeatureCreator(layerName, geometryType);
|
|
@@ -4826,15 +4829,16 @@ const usePythonTask = () => {
|
|
|
4826
4829
|
const { api, t } = useGlobalContext();
|
|
4827
4830
|
const { addSubscription, connection, unsubscribeById } = useServerNotificationsContext();
|
|
4828
4831
|
const [status, setStatus] = useState(RemoteTaskStatus.Unknown);
|
|
4829
|
-
const [
|
|
4832
|
+
const [log, setLog] = useState(null);
|
|
4830
4833
|
const [error, setError] = useState(null);
|
|
4831
4834
|
const [loading, setLoading] = useState(false);
|
|
4832
4835
|
const [executionTime, setExecutionTime] = useState(null);
|
|
4833
4836
|
const [taskId, setTaskId] = useState(null);
|
|
4834
4837
|
const [subscriptionId, setSubscriptionId] = useState(null);
|
|
4838
|
+
const [isLogDialogOpen, setIsLogDialogOpen] = useState(false);
|
|
4839
|
+
const logRef = useRef(null);
|
|
4835
4840
|
const reset = useCallback(() => {
|
|
4836
4841
|
setStatus(RemoteTaskStatus.Unknown);
|
|
4837
|
-
setResult(null);
|
|
4838
4842
|
setError(null);
|
|
4839
4843
|
setLoading(false);
|
|
4840
4844
|
setExecutionTime(null);
|
|
@@ -4844,6 +4848,7 @@ const usePythonTask = () => {
|
|
|
4844
4848
|
const runTask = useCallback(async ({ resourceId, parameters, script, fileName, methodName, }) => {
|
|
4845
4849
|
reset();
|
|
4846
4850
|
setStatus(RemoteTaskStatus.Process);
|
|
4851
|
+
setLog(null);
|
|
4847
4852
|
setLoading(true);
|
|
4848
4853
|
const start = Date.now();
|
|
4849
4854
|
let prototypeId = await api.remoteTaskManager.createTaskPrototype({
|
|
@@ -4868,7 +4873,7 @@ const usePythonTask = () => {
|
|
|
4868
4873
|
const { id: newTaskId, success } = await api.remoteTaskManager.startTask1(prototypeId);
|
|
4869
4874
|
if (!success) {
|
|
4870
4875
|
setStatus(RemoteTaskStatus.Error);
|
|
4871
|
-
|
|
4876
|
+
setLog(t("taskRunFail", { ns: "devMode", defaultValue: "Не удалось запустить задачу" }));
|
|
4872
4877
|
setExecutionTime(Date.now() - start);
|
|
4873
4878
|
setLoading(false);
|
|
4874
4879
|
}
|
|
@@ -4881,10 +4886,8 @@ const usePythonTask = () => {
|
|
|
4881
4886
|
const onNotification = ({ data }) => {
|
|
4882
4887
|
if (data?.taskId === newTaskId) {
|
|
4883
4888
|
setStatus(data.status);
|
|
4884
|
-
|
|
4885
|
-
setError(null);
|
|
4889
|
+
setLog([logRef.current, data.log].filter(Boolean).join("\n\n"));
|
|
4886
4890
|
setExecutionTime(Date.now() - start);
|
|
4887
|
-
setLoading(false);
|
|
4888
4891
|
setTaskId([RemoteTaskStatus.Completed, RemoteTaskStatus.Error].includes(data.status)
|
|
4889
4892
|
? undefined
|
|
4890
4893
|
: newTaskId);
|
|
@@ -4904,7 +4907,28 @@ const usePythonTask = () => {
|
|
|
4904
4907
|
reset();
|
|
4905
4908
|
unsubscribeById(subscriptionId);
|
|
4906
4909
|
}, [api, reset, unsubscribeById, taskId, subscriptionId]);
|
|
4907
|
-
|
|
4910
|
+
const openLog = useCallback(() => {
|
|
4911
|
+
setIsLogDialogOpen(true);
|
|
4912
|
+
}, []);
|
|
4913
|
+
const closeLog = useCallback(() => {
|
|
4914
|
+
setIsLogDialogOpen(false);
|
|
4915
|
+
}, []);
|
|
4916
|
+
useEffect(() => {
|
|
4917
|
+
logRef.current = log;
|
|
4918
|
+
}, [log]);
|
|
4919
|
+
return {
|
|
4920
|
+
taskId,
|
|
4921
|
+
runTask,
|
|
4922
|
+
stopTask,
|
|
4923
|
+
openLog,
|
|
4924
|
+
log,
|
|
4925
|
+
error,
|
|
4926
|
+
status,
|
|
4927
|
+
loading,
|
|
4928
|
+
executionTime,
|
|
4929
|
+
isLogDialogOpen,
|
|
4930
|
+
closeLog,
|
|
4931
|
+
};
|
|
4908
4932
|
};
|
|
4909
4933
|
|
|
4910
4934
|
const useAppHeight = () => {
|
|
@@ -6736,6 +6760,172 @@ const UploadContainer = memo(({ type, elementConfig, renderElement }) => {
|
|
|
6736
6760
|
return (jsxs(Fragment$1, { children: [jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && renderElement({ id: "uploader", wrap: false })] }));
|
|
6737
6761
|
});
|
|
6738
6762
|
|
|
6763
|
+
const StatusBadge = styled(Flex) `
|
|
6764
|
+
margin-bottom: 1rem;
|
|
6765
|
+
padding: 0.5rem 1rem;
|
|
6766
|
+
background-color: ${({ $statusColor }) => $statusColor};
|
|
6767
|
+
color: ${({ theme }) => theme.palette.iconContrast};
|
|
6768
|
+
border-radius: 0.25rem;
|
|
6769
|
+
`;
|
|
6770
|
+
styled.div `
|
|
6771
|
+
flex: 1;
|
|
6772
|
+
padding: 1rem;
|
|
6773
|
+
background-color: ${({ theme }) => theme.palette.element};
|
|
6774
|
+
color: ${({ theme }) => theme.palette.textPrimary};
|
|
6775
|
+
font-family: monospace;
|
|
6776
|
+
font-size: 0.875rem;
|
|
6777
|
+
overflow: auto;
|
|
6778
|
+
white-space: pre-wrap;
|
|
6779
|
+
word-break: break-word;
|
|
6780
|
+
border-radius: 0.25rem;
|
|
6781
|
+
max-height: 31.25rem;
|
|
6782
|
+
`;
|
|
6783
|
+
|
|
6784
|
+
const TerminalWrapper = styled.div `
|
|
6785
|
+
flex: 1;
|
|
6786
|
+
overflow: hidden;
|
|
6787
|
+
padding: 0;
|
|
6788
|
+
margin: 1rem;
|
|
6789
|
+
box-sizing: border-box;
|
|
6790
|
+
min-height: 0;
|
|
6791
|
+
|
|
6792
|
+
& && .xterm-viewport {
|
|
6793
|
+
overflow-y: auto;
|
|
6794
|
+
}
|
|
6795
|
+
`;
|
|
6796
|
+
|
|
6797
|
+
const LogTerminal = ({ log }) => {
|
|
6798
|
+
const terminalRef = useRef(null);
|
|
6799
|
+
const xtermRef = useRef(null);
|
|
6800
|
+
const fitAddonRef = useRef(null);
|
|
6801
|
+
const previousLogRef = useRef("");
|
|
6802
|
+
const theme = useTheme();
|
|
6803
|
+
// Initialize terminal
|
|
6804
|
+
useEffect(() => {
|
|
6805
|
+
if (!terminalRef.current)
|
|
6806
|
+
return;
|
|
6807
|
+
// Create terminal instance
|
|
6808
|
+
const terminal = new Terminal({
|
|
6809
|
+
cursorBlink: false,
|
|
6810
|
+
fontSize: 12,
|
|
6811
|
+
fontFamily: '"Monaco", "Menlo", "Ubuntu Mono", "Consolas", "source-code-pro", monospace',
|
|
6812
|
+
theme: {
|
|
6813
|
+
background: theme.palette.devBackgroundDark,
|
|
6814
|
+
foreground: theme.palette.textPrimary,
|
|
6815
|
+
cursor: theme.palette.primary,
|
|
6816
|
+
},
|
|
6817
|
+
scrollback: 10000,
|
|
6818
|
+
convertEol: true,
|
|
6819
|
+
lineHeight: 1.5,
|
|
6820
|
+
});
|
|
6821
|
+
// Create fit addon
|
|
6822
|
+
const fitAddon = new FitAddon();
|
|
6823
|
+
terminal.loadAddon(fitAddon);
|
|
6824
|
+
// Open terminal
|
|
6825
|
+
terminal.open(terminalRef.current);
|
|
6826
|
+
fitAddon.fit();
|
|
6827
|
+
// Store refs
|
|
6828
|
+
xtermRef.current = terminal;
|
|
6829
|
+
fitAddonRef.current = fitAddon;
|
|
6830
|
+
// Handle window resize
|
|
6831
|
+
const handleResize = () => {
|
|
6832
|
+
fitAddon.fit();
|
|
6833
|
+
};
|
|
6834
|
+
window.addEventListener("resize", handleResize);
|
|
6835
|
+
// Cleanup
|
|
6836
|
+
return () => {
|
|
6837
|
+
window.removeEventListener("resize", handleResize);
|
|
6838
|
+
terminal.dispose();
|
|
6839
|
+
xtermRef.current = null;
|
|
6840
|
+
fitAddonRef.current = null;
|
|
6841
|
+
};
|
|
6842
|
+
}, [theme]);
|
|
6843
|
+
// Update log content
|
|
6844
|
+
useEffect(() => {
|
|
6845
|
+
if (!xtermRef.current)
|
|
6846
|
+
return;
|
|
6847
|
+
// Handle different log types
|
|
6848
|
+
if (typeof log === "string") {
|
|
6849
|
+
// For string logs, only write the new content (append mode)
|
|
6850
|
+
const previousLog = previousLogRef.current;
|
|
6851
|
+
if (log !== previousLog) {
|
|
6852
|
+
if (log.startsWith(previousLog)) {
|
|
6853
|
+
// Log is accumulated - write only the new part
|
|
6854
|
+
const newContent = log.substring(previousLog.length);
|
|
6855
|
+
xtermRef.current.write(`${newContent.replace(/\n/g, "\r\n")}\r\n`);
|
|
6856
|
+
}
|
|
6857
|
+
else {
|
|
6858
|
+
// Log was replaced completely - clear and write all
|
|
6859
|
+
xtermRef.current.clear();
|
|
6860
|
+
xtermRef.current.write(`${log.replace(/\n/g, "\r\n")}\r\n`);
|
|
6861
|
+
}
|
|
6862
|
+
previousLogRef.current = log;
|
|
6863
|
+
}
|
|
6864
|
+
}
|
|
6865
|
+
else if (typeof log === "object") {
|
|
6866
|
+
// JSON object (results) - always replace
|
|
6867
|
+
xtermRef.current.clear();
|
|
6868
|
+
const formatted = JSON.stringify(log, null, 2);
|
|
6869
|
+
xtermRef.current.write(formatted.replace(/\n/g, "\r\n"));
|
|
6870
|
+
previousLogRef.current = "";
|
|
6871
|
+
}
|
|
6872
|
+
else if (!log) {
|
|
6873
|
+
// No log - clear terminal
|
|
6874
|
+
xtermRef.current.clear();
|
|
6875
|
+
previousLogRef.current = "";
|
|
6876
|
+
}
|
|
6877
|
+
// Scroll to bottom
|
|
6878
|
+
xtermRef.current.scrollToBottom();
|
|
6879
|
+
}, [log]);
|
|
6880
|
+
// Fit terminal on container resize
|
|
6881
|
+
useEffect(() => {
|
|
6882
|
+
if (!fitAddonRef.current)
|
|
6883
|
+
return;
|
|
6884
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
6885
|
+
fitAddonRef.current?.fit();
|
|
6886
|
+
});
|
|
6887
|
+
if (terminalRef.current) {
|
|
6888
|
+
resizeObserver.observe(terminalRef.current);
|
|
6889
|
+
}
|
|
6890
|
+
return () => {
|
|
6891
|
+
resizeObserver.disconnect();
|
|
6892
|
+
};
|
|
6893
|
+
}, []);
|
|
6894
|
+
return jsx(TerminalWrapper, { ref: terminalRef });
|
|
6895
|
+
};
|
|
6896
|
+
|
|
6897
|
+
const STATUS_TRANSLATION_KEYS = {
|
|
6898
|
+
[RemoteTaskStatus.Process]: "taskProcess",
|
|
6899
|
+
[RemoteTaskStatus.Completed]: "taskCompleted",
|
|
6900
|
+
[RemoteTaskStatus.Error]: "taskError",
|
|
6901
|
+
[RemoteTaskStatus.Unknown]: "taskUnknown",
|
|
6902
|
+
};
|
|
6903
|
+
const STATUS_DEFAULT_VALUES = {
|
|
6904
|
+
[RemoteTaskStatus.Process]: "Остановить",
|
|
6905
|
+
[RemoteTaskStatus.Completed]: "Завершено",
|
|
6906
|
+
[RemoteTaskStatus.Error]: "Ошибка",
|
|
6907
|
+
[RemoteTaskStatus.Unknown]: "Неизвестно",
|
|
6908
|
+
};
|
|
6909
|
+
const STATUS_COLORS = {
|
|
6910
|
+
[RemoteTaskStatus.Process]: "#2196f3",
|
|
6911
|
+
[RemoteTaskStatus.Completed]: "#4caf50",
|
|
6912
|
+
[RemoteTaskStatus.Error]: "#f44336",
|
|
6913
|
+
[RemoteTaskStatus.Unknown]: "#757575",
|
|
6914
|
+
};
|
|
6915
|
+
|
|
6916
|
+
const LogDialog = ({ isOpen, onClose, logs, status, statusColors }) => {
|
|
6917
|
+
const { t } = useGlobalContext();
|
|
6918
|
+
const getStatusText = useCallback((status) => {
|
|
6919
|
+
const translationKey = STATUS_TRANSLATION_KEYS[status] || STATUS_TRANSLATION_KEYS[RemoteTaskStatus.Unknown];
|
|
6920
|
+
const defaultValue = STATUS_DEFAULT_VALUES[status] || STATUS_DEFAULT_VALUES[RemoteTaskStatus.Unknown];
|
|
6921
|
+
return t(translationKey, { ns: "dashboard", defaultValue });
|
|
6922
|
+
}, [t]);
|
|
6923
|
+
const getStatusColor = useCallback((status) => {
|
|
6924
|
+
return statusColors?.[status] || STATUS_COLORS[status] || STATUS_COLORS[RemoteTaskStatus.Unknown];
|
|
6925
|
+
}, [statusColors]);
|
|
6926
|
+
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("taskLogs", { 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("taskStatus", { ns: "dashboard", defaultValue: "Статус" }), ": ", getStatusText(status)] }), jsx(LogTerminal, { log: logs || t("taskLogsEmpty", { ns: "dashboard", defaultValue: "Логи отсутствуют" }) })] }) })] }));
|
|
6927
|
+
};
|
|
6928
|
+
|
|
6739
6929
|
const StatusWaitingButton = styled(WaitingButton) `
|
|
6740
6930
|
${({ status = RemoteTaskStatus.Unknown, statusColors }) => !!statusColors?.[status] && css `
|
|
6741
6931
|
transition: background-color ${transition.toggle};
|
|
@@ -6747,14 +6937,18 @@ const StatusWaitingButton = styled(WaitingButton) `
|
|
|
6747
6937
|
`}
|
|
6748
6938
|
`;
|
|
6749
6939
|
|
|
6750
|
-
const TaskContainer = memo(({ type, elementConfig }) => {
|
|
6940
|
+
const TaskContainer = memo(({ type, elementConfig, renderElement }) => {
|
|
6751
6941
|
const { t, ewktGeometry } = useGlobalContext();
|
|
6752
6942
|
const { dataSources, filters: selectedFilters } = useWidgetContext(type);
|
|
6753
6943
|
const { currentPage } = useWidgetPage(type);
|
|
6754
|
-
const { taskId, runTask, stopTask, status, loading } = usePythonTask();
|
|
6944
|
+
const { taskId, runTask, stopTask, status, openLog, loading, isLogDialogOpen, closeLog, log } = usePythonTask();
|
|
6755
6945
|
const { options } = elementConfig || {};
|
|
6756
6946
|
const { title, relatedResources, center, icon, statusColors } = options || {};
|
|
6757
6947
|
const onClick = useCallback(async () => {
|
|
6948
|
+
if (taskId) {
|
|
6949
|
+
await stopTask();
|
|
6950
|
+
return;
|
|
6951
|
+
}
|
|
6758
6952
|
await Promise.all(relatedResources.map(({ resourceId, parameters, script, fileName, methodName }) => {
|
|
6759
6953
|
const newParams = applyQueryFilters({
|
|
6760
6954
|
parameters,
|
|
@@ -6765,8 +6959,8 @@ const TaskContainer = memo(({ type, elementConfig }) => {
|
|
|
6765
6959
|
});
|
|
6766
6960
|
return runTask({ resourceId, parameters: newParams, script, fileName, methodName });
|
|
6767
6961
|
}));
|
|
6768
|
-
}, [currentPage.filters, dataSources, ewktGeometry, relatedResources, runTask, selectedFilters]);
|
|
6769
|
-
return (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: "
|
|
6962
|
+
}, [currentPage.filters, dataSources, ewktGeometry, relatedResources, runTask, selectedFilters, stopTask, taskId]);
|
|
6963
|
+
return (jsxs(Fragment$1, { children: [jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), jsxs(Flex, { justifyContent: center ? "center" : "flex-start", children: [jsxs(StatusWaitingButton, { primary: true, status: status, statusColors: statusColors, isWaiting: loading || !!taskId, disabled: !relatedResources?.length, onClick: onClick, children: [icon && jsx(FlexSpan, { marginRight: "0.5rem", children: jsx(Icon, { kind: icon }) }), title || t("run", { ns: "dashboard", defaultValue: "Запуск" })] }), !!taskId && (jsxs(Fragment$1, { children: [jsx(IconButton, { kind: "info", onClick: openLog }), jsx(LogDialog, { logs: log, status: status, statusColors: statusColors, isOpen: isLogDialogOpen, onClose: closeLog })] }))] })] }));
|
|
6770
6964
|
});
|
|
6771
6965
|
|
|
6772
6966
|
const containerComponents = {
|
|
@@ -7596,27 +7790,30 @@ const StyledIcon = styled(Icon) `
|
|
|
7596
7790
|
|
|
7597
7791
|
const ElementIcon = memo(({ type, elementConfig }) => {
|
|
7598
7792
|
const { attributes } = useWidgetContext(type);
|
|
7599
|
-
const { value, attributeName, options } = elementConfig || {};
|
|
7793
|
+
const { value, attributeName, options, style } = elementConfig || {};
|
|
7600
7794
|
const { fontSize, fontColor } = options || {};
|
|
7601
7795
|
const iconValue = useMemo(() => (attributeName ? attributes?.find(item => item.name === attributeName)?.value : value), [attributeName, attributes, value]);
|
|
7602
|
-
return jsx(StyledIcon, { kind: iconValue, fontSize: fontSize, fontColor: fontColor });
|
|
7796
|
+
return jsx(StyledIcon, { kind: iconValue, fontSize: fontSize, fontColor: fontColor, style: style });
|
|
7603
7797
|
});
|
|
7604
7798
|
|
|
7605
7799
|
const ElementImage = memo(({ type, elementConfig }) => {
|
|
7606
7800
|
const { attributes } = useWidgetContext(type);
|
|
7607
|
-
const { value, attributeName, options } = elementConfig || {};
|
|
7801
|
+
const { value, attributeName, options, style } = elementConfig || {};
|
|
7608
7802
|
const { width } = options || {};
|
|
7609
7803
|
const firstImage = useMemo(() => {
|
|
7610
7804
|
if (value) {
|
|
7611
|
-
return value.toString();
|
|
7805
|
+
return getResourceUrl(value.toString());
|
|
7612
7806
|
}
|
|
7613
7807
|
if (!attributeName || Array.isArray(attributeName)) {
|
|
7614
7808
|
return null;
|
|
7615
7809
|
}
|
|
7616
7810
|
const attribute = attributes?.find(item => item.name === attributeName);
|
|
7617
|
-
|
|
7811
|
+
const imageUrl = attribute?.value?.split(";")?.[0];
|
|
7812
|
+
if (!imageUrl)
|
|
7813
|
+
return null;
|
|
7814
|
+
return getResourceUrl(imageUrl);
|
|
7618
7815
|
}, [attributeName, attributes, value]);
|
|
7619
|
-
return firstImage ? jsx("img", { src: firstImage, alt: firstImage, width: width }) : null;
|
|
7816
|
+
return firstImage ? jsx("img", { src: firstImage, alt: firstImage, width: width, style: style }) : null;
|
|
7620
7817
|
});
|
|
7621
7818
|
|
|
7622
7819
|
const ElementLegend = memo(({ type, element, elementConfig }) => {
|