@evergis/react 4.0.61 → 4.0.63
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/componentTypes.d.ts +2 -2
- package/dist/components/Dashboard/components/TextTrim/index.d.ts +2 -0
- package/dist/components/Dashboard/components/TextTrim/styled.d.ts +4 -0
- package/dist/components/Dashboard/containers/TaskContainer/useTaskNotifications.d.ts +9 -0
- package/dist/components/Dashboard/elements/ElementImage/useElementImage.d.ts +11 -0
- package/dist/components/Dashboard/hooks/useGlobalContext.d.ts +7 -0
- package/dist/components/Dashboard/types.d.ts +2 -0
- package/dist/contexts/GlobalContext/types.d.ts +8 -0
- package/dist/hooks/task/usePythonTask.d.ts +1 -0
- package/dist/index.js +154 -49
- package/dist/index.js.map +1 -1
- package/dist/react.esm.js +154 -49
- package/dist/react.esm.js.map +1 -1
- package/package.json +3 -3
|
@@ -403,7 +403,7 @@ export interface SlideshowContainerConfig extends Omit<ConfigContainerChild, "op
|
|
|
403
403
|
export interface SlideshowContainerProps extends Omit<ContainerProps, "elementConfig"> {
|
|
404
404
|
elementConfig?: SlideshowContainerConfig;
|
|
405
405
|
}
|
|
406
|
-
export type TabsContainerOptions = Pick<ConfigOptions, "radius" | "column" | "bgColor" | "noBg" | "onlyIcon" | "shownItems" | "maxLength">;
|
|
406
|
+
export type TabsContainerOptions = Pick<ConfigOptions, "radius" | "column" | "bgColor" | "noBg" | "onlyIcon" | "shownItems" | "maxLength" | "wordBreak">;
|
|
407
407
|
export type TabOptions = Pick<ConfigOptions, "icon">;
|
|
408
408
|
export interface TabChild extends Omit<ConfigContainerChild, "options" | "type" | "children"> {
|
|
409
409
|
options?: TabOptions;
|
|
@@ -416,7 +416,7 @@ export interface TabsContainerConfig extends Omit<ConfigContainerChild, "options
|
|
|
416
416
|
export interface TabsContainerProps extends Omit<ContainerProps, "elementConfig"> {
|
|
417
417
|
elementConfig?: TabsContainerConfig;
|
|
418
418
|
}
|
|
419
|
-
export type TaskContainerOptions = Pick<ConfigOptions, "title" | "relatedResources" | "center" | "icon" | "statusColors" | "responseFilters">;
|
|
419
|
+
export type TaskContainerOptions = Pick<ConfigOptions, "title" | "relatedResources" | "center" | "icon" | "statusColors" | "responseFilters" | "useNotifications">;
|
|
420
420
|
export interface TaskContainerConfig extends Omit<ConfigContainerChild, "options" | "templateName"> {
|
|
421
421
|
templateName?: ContainerTemplate.Task;
|
|
422
422
|
options?: TaskContainerOptions;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { RemoteTaskStatus } from '@evergis/api';
|
|
2
|
+
interface UseTaskNotificationsParams {
|
|
3
|
+
enabled: boolean;
|
|
4
|
+
status: RemoteTaskStatus;
|
|
5
|
+
lastMessage: string | null;
|
|
6
|
+
openLog: () => void;
|
|
7
|
+
}
|
|
8
|
+
export declare const useTaskNotifications: ({ enabled, status, lastMessage, openLog, }: UseTaskNotificationsParams) => void;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ConfigContainerChild, WidgetType } from '../../types';
|
|
2
|
+
interface UseElementImageProps {
|
|
3
|
+
type?: WidgetType;
|
|
4
|
+
elementConfig?: ConfigContainerChild;
|
|
5
|
+
}
|
|
6
|
+
interface UseElementImageResult {
|
|
7
|
+
src: string | null;
|
|
8
|
+
alt: string;
|
|
9
|
+
}
|
|
10
|
+
export declare const useElementImage: ({ type, elementConfig, }: UseElementImageProps) => UseElementImageResult;
|
|
11
|
+
export {};
|
|
@@ -5,4 +5,11 @@ export declare const useGlobalContext: () => {
|
|
|
5
5
|
themeName: import('../../..').ThemeName;
|
|
6
6
|
api: import('@evergis/api').Api;
|
|
7
7
|
ewktGeometry: string;
|
|
8
|
+
notification: {
|
|
9
|
+
add: (item: import('@evergis/uilib-gl').INotificationItem) => void;
|
|
10
|
+
update: (patch: Partial<import('@evergis/uilib-gl').INotificationItem> & {
|
|
11
|
+
id: string;
|
|
12
|
+
}) => void;
|
|
13
|
+
close: (id: string) => void;
|
|
14
|
+
};
|
|
8
15
|
};
|
|
@@ -184,6 +184,7 @@ export interface ConfigTextDisplayOptions {
|
|
|
184
184
|
hideTitle?: boolean;
|
|
185
185
|
simple?: boolean;
|
|
186
186
|
maxLength?: number;
|
|
187
|
+
wordBreak?: "break-word" | "break-all";
|
|
187
188
|
separator?: string;
|
|
188
189
|
lineBreak?: string;
|
|
189
190
|
}
|
|
@@ -261,6 +262,7 @@ export interface ConfigMiscOptions {
|
|
|
261
262
|
tabId?: string;
|
|
262
263
|
downloadById?: string;
|
|
263
264
|
parentResourceId?: string;
|
|
265
|
+
useNotifications?: boolean;
|
|
264
266
|
}
|
|
265
267
|
/**
|
|
266
268
|
* Flat-объединение всех доменных миксинов. Существующие места, использующие
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { PropsWithChildren } from 'react';
|
|
2
2
|
import { i18n } from 'i18next';
|
|
3
3
|
import { Api } from '@evergis/api';
|
|
4
|
+
import { INotificationItem } from '@evergis/uilib-gl';
|
|
4
5
|
import { ThemeName } from '../../types';
|
|
5
6
|
export type GlobalContextProps = PropsWithChildren<{
|
|
6
7
|
t?: i18n["t"];
|
|
@@ -8,4 +9,11 @@ export type GlobalContextProps = PropsWithChildren<{
|
|
|
8
9
|
ewktGeometry?: string;
|
|
9
10
|
themeName?: ThemeName;
|
|
10
11
|
api?: Api;
|
|
12
|
+
notification?: {
|
|
13
|
+
add: (item: INotificationItem) => void;
|
|
14
|
+
update: (patch: Partial<INotificationItem> & {
|
|
15
|
+
id: string;
|
|
16
|
+
}) => void;
|
|
17
|
+
close: (id: string) => void;
|
|
18
|
+
};
|
|
11
19
|
}>;
|
package/dist/index.js
CHANGED
|
@@ -4217,7 +4217,7 @@ const useAttachmentItems = ({ type, elementConfig, valueOverride, }) => {
|
|
|
4217
4217
|
};
|
|
4218
4218
|
|
|
4219
4219
|
const useGlobalContext = () => {
|
|
4220
|
-
const { t, language, themeName, api, ewktGeometry } = React.useContext(GlobalContext) || {};
|
|
4220
|
+
const { t, language, themeName, api, ewktGeometry, notification } = React.useContext(GlobalContext) || {};
|
|
4221
4221
|
const translate = React.useCallback((value, options) => {
|
|
4222
4222
|
if (t)
|
|
4223
4223
|
return t(value, options);
|
|
@@ -4229,7 +4229,8 @@ const useGlobalContext = () => {
|
|
|
4229
4229
|
themeName,
|
|
4230
4230
|
api,
|
|
4231
4231
|
ewktGeometry,
|
|
4232
|
-
|
|
4232
|
+
notification,
|
|
4233
|
+
}), [language, translate, api, ewktGeometry, themeName, notification]);
|
|
4233
4234
|
};
|
|
4234
4235
|
|
|
4235
4236
|
const GRID_TILE_SIZE = "4.5rem";
|
|
@@ -5622,6 +5623,7 @@ const usePythonTask = () => {
|
|
|
5622
5623
|
const { preparePythonSandbox } = usePythonSandbox();
|
|
5623
5624
|
const [status, setStatus] = React.useState(api.RemoteTaskStatus.Unknown);
|
|
5624
5625
|
const [log, setLog] = React.useState(null);
|
|
5626
|
+
const [lastMessage, setLastMessage] = React.useState(null);
|
|
5625
5627
|
const [error, setError] = React.useState(null);
|
|
5626
5628
|
const [loading, setLoading] = React.useState(false);
|
|
5627
5629
|
const [executionTime, setExecutionTime] = React.useState(null);
|
|
@@ -5643,6 +5645,7 @@ const usePythonTask = () => {
|
|
|
5643
5645
|
reset();
|
|
5644
5646
|
setStatus(api.RemoteTaskStatus.Process);
|
|
5645
5647
|
setLog(null);
|
|
5648
|
+
setLastMessage(null);
|
|
5646
5649
|
setLoading(true);
|
|
5647
5650
|
const start = Date.now();
|
|
5648
5651
|
let prototypeId = await api$1.remoteTaskManager.createTaskPrototype({
|
|
@@ -5683,6 +5686,8 @@ const usePythonTask = () => {
|
|
|
5683
5686
|
const isFinished = [api.RemoteTaskStatus.Completed, api.RemoteTaskStatus.Error].includes(data.status);
|
|
5684
5687
|
setStatus(data.status);
|
|
5685
5688
|
setLog([logRef.current, data.log].filter(Boolean).join("\n"));
|
|
5689
|
+
if (data.log)
|
|
5690
|
+
setLastMessage(data.log);
|
|
5686
5691
|
setExecutionTime(Date.now() - start);
|
|
5687
5692
|
setLoading(false);
|
|
5688
5693
|
setTaskId(isFinished ? null : newTaskId);
|
|
@@ -5735,6 +5740,7 @@ const usePythonTask = () => {
|
|
|
5735
5740
|
stopTask,
|
|
5736
5741
|
openLog,
|
|
5737
5742
|
log,
|
|
5743
|
+
lastMessage,
|
|
5738
5744
|
error,
|
|
5739
5745
|
status,
|
|
5740
5746
|
loading,
|
|
@@ -6254,7 +6260,7 @@ const formatElementValue = ({ t, value, elementConfig, attributes, wrap, }) => {
|
|
|
6254
6260
|
|
|
6255
6261
|
const getAttributeValue = (element, attributes) => {
|
|
6256
6262
|
const attribute = getAttributeByName(element?.attributeName, attributes);
|
|
6257
|
-
const { maxLength, separator, expandable, lineBreak } = element.options || {};
|
|
6263
|
+
const { maxLength, wordBreak, separator, expandable, lineBreak } = element.options || {};
|
|
6258
6264
|
let value;
|
|
6259
6265
|
if (attribute?.type === api.AttributeType.Boolean && typeof attribute.value === "boolean") {
|
|
6260
6266
|
return jsxRuntime.jsx(DashboardCheckbox, { title: attribute.alias || attribute.attributeName, checked: attribute.value });
|
|
@@ -6269,7 +6275,7 @@ const getAttributeValue = (element, attributes) => {
|
|
|
6269
6275
|
? JSON.stringify(rawValue)
|
|
6270
6276
|
: (rawValue || "");
|
|
6271
6277
|
}
|
|
6272
|
-
return typeof value === "string" && maxLength && maxLength < value.length ? (jsxRuntime.jsx(TextTrim, { maxLength: maxLength, expandable: expandable, lineBreak: lineBreak, children: value })) : (value);
|
|
6278
|
+
return typeof value === "string" && maxLength && maxLength < value.length ? (jsxRuntime.jsx(TextTrim, { maxLength: maxLength, wordBreak: wordBreak, expandable: expandable, lineBreak: lineBreak, children: value })) : (value);
|
|
6273
6279
|
};
|
|
6274
6280
|
|
|
6275
6281
|
const getChartAxes = (chartElement) => chartElement?.options?.relatedDataSources?.filter(({ chartAxis }) => chartAxis === "y");
|
|
@@ -7399,7 +7405,7 @@ const TabsContainer = React.memo(({ elementConfig, type }) => {
|
|
|
7399
7405
|
const { palette } = styled.useTheme();
|
|
7400
7406
|
const { selectedTabId, setSelectedTabId } = useWidgetContext(type);
|
|
7401
7407
|
const { id, options, style, children: tabs } = elementConfig || {};
|
|
7402
|
-
const { radius, column, bgColor, noBg, onlyIcon, shownItems, maxLength = 12 } = options || {};
|
|
7408
|
+
const { radius, column, bgColor, noBg, onlyIcon, shownItems, maxLength = 12, wordBreak } = options || {};
|
|
7403
7409
|
const renderIcon = React.useCallback((icon, active) => {
|
|
7404
7410
|
if (!icon)
|
|
7405
7411
|
return null;
|
|
@@ -7407,16 +7413,16 @@ const TabsContainer = React.memo(({ elementConfig, type }) => {
|
|
|
7407
7413
|
return jsxRuntime.jsx(uilibGl.Icon, { kind: icon });
|
|
7408
7414
|
return icon.endsWith(".svg") ? (jsxRuntime.jsx(SvgImage, { url: icon, width: 16, fontColor: active ? palette.textContrast : palette.textSecondary })) : (jsxRuntime.jsx("img", { src: icon, alt: "" }));
|
|
7409
7415
|
}, [palette.textContrast, palette.textSecondary]);
|
|
7410
|
-
const onClick = React.useCallback((
|
|
7411
|
-
setSelectedTabId(
|
|
7412
|
-
window.location.hash = `#${
|
|
7416
|
+
const onClick = React.useCallback((tabId) => {
|
|
7417
|
+
setSelectedTabId(tabId);
|
|
7418
|
+
window.location.hash = `#${tabId}`;
|
|
7413
7419
|
}, [setSelectedTabId]);
|
|
7414
7420
|
React.useEffect(() => {
|
|
7415
7421
|
if (!selectedTabId) {
|
|
7416
7422
|
setSelectedTabId(tabs[0].id);
|
|
7417
7423
|
}
|
|
7418
7424
|
}, []);
|
|
7419
|
-
return (jsxRuntime.jsx(SwiperContainer, { id: id, style: style, children: jsxRuntime.jsx(react.Swiper, { spaceBetween: 0, slidesPerView: shownItems || 2, children: tabs.map(({ id, value, options: tabOptions }) => (jsxRuntime.jsxs(react.SwiperSlide, { children: [jsxRuntime.jsxs(TabContainer, { href: `#${
|
|
7425
|
+
return (jsxRuntime.jsx(SwiperContainer, { id: id, style: style, children: jsxRuntime.jsx(react.Swiper, { spaceBetween: 0, slidesPerView: shownItems || 2, children: tabs.map(({ id: tabId, value, options: tabOptions }) => (jsxRuntime.jsxs(react.SwiperSlide, { children: [jsxRuntime.jsxs(TabContainer, { href: `#${tabId}`, active: selectedTabId === tabId, column: column, bgColor: bgColor, noBg: noBg, radius: radius, onlyIcon: onlyIcon, hasIcon: !!tabOptions?.icon, onClick: () => onClick(tabId), children: [renderIcon(tabOptions?.icon, selectedTabId === tabId), !onlyIcon && (jsxRuntime.jsx(TabValue, { children: jsxRuntime.jsx(TextTrim, { maxLength: maxLength, wordBreak: wordBreak, children: value }) }))] }), jsxRuntime.jsx(TabAnchor, { id: tabId })] }, tabId))) }) }));
|
|
7420
7426
|
});
|
|
7421
7427
|
|
|
7422
7428
|
const ContainerIconValue = styled(uilibGl.Flex) ``;
|
|
@@ -7524,7 +7530,7 @@ const RoundedBackgroundContainer = React.memo(({ type, elementConfig, feature, r
|
|
|
7524
7530
|
feature,
|
|
7525
7531
|
});
|
|
7526
7532
|
const { id, options, style, children } = elementConfig || {};
|
|
7527
|
-
const { maxLength, center, fontColor, innerTemplateStyle, inlineUnits, big, bigIcon, hideEmpty, colorAttribute } = options || {};
|
|
7533
|
+
const { maxLength, wordBreak, center, fontColor, innerTemplateStyle, inlineUnits, big, bigIcon, hideEmpty, colorAttribute } = options || {};
|
|
7528
7534
|
const iconElement = children?.find(item => item.id === "icon");
|
|
7529
7535
|
const aliasElement = children?.find(item => item.id === "alias");
|
|
7530
7536
|
const unitsElement = children?.find(item => item.id === "units");
|
|
@@ -7543,7 +7549,7 @@ const RoundedBackgroundContainer = React.memo(({ type, elementConfig, feature, r
|
|
|
7543
7549
|
return null;
|
|
7544
7550
|
return (jsxRuntime.jsx(uilibGl.FlexSpan, { width: iconElement.options?.width || "1rem", alignItems: "center", mr: "0.5rem", children: renderElement({ id: "icon", wrap: false }) }));
|
|
7545
7551
|
}, [iconElement, renderElement]);
|
|
7546
|
-
const renderAlias = React.useMemo(() => (jsxRuntime.jsx(ContainerAlias, { style: aliasElement?.style, children: jsxRuntime.jsx(TextTrim, { maxLength: maxLength || ALIAS_DEFAULT_MAX_LENGTH, children: renderElement({ id: "alias", wrap: false }) }) })), [aliasElement?.style, maxLength, renderElement]);
|
|
7552
|
+
const renderAlias = React.useMemo(() => (jsxRuntime.jsx(ContainerAlias, { style: aliasElement?.style, children: jsxRuntime.jsx(TextTrim, { maxLength: maxLength || ALIAS_DEFAULT_MAX_LENGTH, wordBreak: wordBreak, children: renderElement({ id: "alias", wrap: false }) }) })), [aliasElement?.style, maxLength, renderElement, wordBreak]);
|
|
7547
7553
|
const renderValue = React.useMemo(() => lodash.isNil(value) ? null : (jsxRuntime.jsxs(ContainerValue, { style: valueElement?.style, big: true, children: [value, !!unitsElement && (jsxRuntime.jsx(ContainerUnits, { style: unitsElement?.style, children: renderElement({ id: "units" }) }))] })), [valueElement?.style, value, unitsElement, renderElement]);
|
|
7548
7554
|
if (lodash.isNil(value) && hideEmpty)
|
|
7549
7555
|
return null;
|
|
@@ -7708,14 +7714,93 @@ const buildFiltersFromResponse = (responseFilters, result) => {
|
|
|
7708
7714
|
return Object.keys(filters).length ? filters : null;
|
|
7709
7715
|
};
|
|
7710
7716
|
|
|
7717
|
+
const RUN_ID_RADIX = 36;
|
|
7718
|
+
const RUN_ID_LENGTH = 8;
|
|
7719
|
+
const generateRunId = () => `task-${Date.now()}-${Math.random().toString(RUN_ID_RADIX).slice(2, RUN_ID_LENGTH)}`;
|
|
7720
|
+
const useTaskNotifications = ({ enabled, status, lastMessage, openLog, }) => {
|
|
7721
|
+
const { t, notification } = useGlobalContext();
|
|
7722
|
+
const runIdRef = React.useRef(null);
|
|
7723
|
+
const prevStatusRef = React.useRef(api.RemoteTaskStatus.Unknown);
|
|
7724
|
+
React.useEffect(() => {
|
|
7725
|
+
if (!enabled) {
|
|
7726
|
+
if (runIdRef.current) {
|
|
7727
|
+
notification?.close(runIdRef.current);
|
|
7728
|
+
runIdRef.current = null;
|
|
7729
|
+
}
|
|
7730
|
+
prevStatusRef.current = status;
|
|
7731
|
+
return;
|
|
7732
|
+
}
|
|
7733
|
+
if (status === api.RemoteTaskStatus.Unknown) {
|
|
7734
|
+
prevStatusRef.current = status;
|
|
7735
|
+
return;
|
|
7736
|
+
}
|
|
7737
|
+
const isFreshRun = status === api.RemoteTaskStatus.Process && prevStatusRef.current !== api.RemoteTaskStatus.Process;
|
|
7738
|
+
if (isFreshRun) {
|
|
7739
|
+
runIdRef.current = generateRunId();
|
|
7740
|
+
}
|
|
7741
|
+
if (!runIdRef.current) {
|
|
7742
|
+
runIdRef.current = generateRunId();
|
|
7743
|
+
}
|
|
7744
|
+
const id = runIdRef.current;
|
|
7745
|
+
const description = lastMessage || t("taskStarted", { ns: "dashboard", defaultValue: "Запуск задачи…" });
|
|
7746
|
+
const button = t("details", { ns: "dashboard", defaultValue: "Подробнее" });
|
|
7747
|
+
const base = {
|
|
7748
|
+
id,
|
|
7749
|
+
title: "",
|
|
7750
|
+
description,
|
|
7751
|
+
duration: Number.MAX_SAFE_INTEGER,
|
|
7752
|
+
button,
|
|
7753
|
+
buttonIcon: "info",
|
|
7754
|
+
buttonColor: "primary",
|
|
7755
|
+
onButtonClick: openLog,
|
|
7756
|
+
};
|
|
7757
|
+
if (status === api.RemoteTaskStatus.Process) {
|
|
7758
|
+
const item = {
|
|
7759
|
+
...base,
|
|
7760
|
+
title: t("taskInProgress", { ns: "dashboard", defaultValue: "Выполняется" }),
|
|
7761
|
+
progress: true,
|
|
7762
|
+
};
|
|
7763
|
+
if (isFreshRun) {
|
|
7764
|
+
notification?.add(item);
|
|
7765
|
+
}
|
|
7766
|
+
else {
|
|
7767
|
+
notification?.update(item);
|
|
7768
|
+
}
|
|
7769
|
+
}
|
|
7770
|
+
else if (status === api.RemoteTaskStatus.Completed) {
|
|
7771
|
+
notification?.update({
|
|
7772
|
+
...base,
|
|
7773
|
+
title: t("taskCompleted", { ns: "dashboard", defaultValue: "Выполнено" }),
|
|
7774
|
+
success: true,
|
|
7775
|
+
progress: false,
|
|
7776
|
+
});
|
|
7777
|
+
}
|
|
7778
|
+
else if (status === api.RemoteTaskStatus.Error) {
|
|
7779
|
+
notification?.update({
|
|
7780
|
+
...base,
|
|
7781
|
+
title: t("taskError", { ns: "dashboard", defaultValue: "Ошибка" }),
|
|
7782
|
+
error: true,
|
|
7783
|
+
progress: false,
|
|
7784
|
+
});
|
|
7785
|
+
}
|
|
7786
|
+
prevStatusRef.current = status;
|
|
7787
|
+
}, [enabled, status, lastMessage, openLog, t, notification]);
|
|
7788
|
+
};
|
|
7789
|
+
|
|
7711
7790
|
const TaskContainer = React.memo(({ type, elementConfig, renderElement }) => {
|
|
7712
7791
|
const { t, ewktGeometry } = useGlobalContext();
|
|
7713
7792
|
const { dataSources, filters: selectedFilters, attributes, layerInfo, changeFilters, } = useWidgetContext(type);
|
|
7714
7793
|
const { dataSources: projectDataSources } = useWidgetContext(exports.WidgetType.Dashboard);
|
|
7715
7794
|
const { currentPage } = useWidgetPage(type);
|
|
7716
|
-
const { taskId, runTask, stopTask, status, openLog, loading, isLogDialogOpen, closeLog, log, result, } = usePythonTask();
|
|
7795
|
+
const { taskId, runTask, stopTask, status, openLog, loading, isLogDialogOpen, closeLog, log, lastMessage, result, } = usePythonTask();
|
|
7717
7796
|
const { options } = elementConfig || {};
|
|
7718
|
-
const { title, relatedResources, center, icon, statusColors, responseFilters } = options || {};
|
|
7797
|
+
const { title, relatedResources, center, icon, statusColors, responseFilters, useNotifications, } = options || {};
|
|
7798
|
+
useTaskNotifications({
|
|
7799
|
+
enabled: !!useNotifications,
|
|
7800
|
+
status,
|
|
7801
|
+
lastMessage,
|
|
7802
|
+
openLog,
|
|
7803
|
+
});
|
|
7719
7804
|
React.useEffect(() => {
|
|
7720
7805
|
const filtersToApply = buildFiltersFromResponse(responseFilters, result);
|
|
7721
7806
|
if (filtersToApply)
|
|
@@ -8787,15 +8872,7 @@ const RowHeaderMixin = styled.css `
|
|
|
8787
8872
|
const OverlayHeaderMixin = (overlay) => styled.css `
|
|
8788
8873
|
&&& {
|
|
8789
8874
|
:after {
|
|
8790
|
-
content: "";
|
|
8791
|
-
z-index: 2;
|
|
8792
|
-
position: absolute;
|
|
8793
|
-
top: 0;
|
|
8794
|
-
left: 0;
|
|
8795
|
-
width: 100%;
|
|
8796
|
-
height: 100%;
|
|
8797
8875
|
background: ${overlay};
|
|
8798
|
-
pointer-events: none;
|
|
8799
8876
|
}
|
|
8800
8877
|
}
|
|
8801
8878
|
`;
|
|
@@ -8851,8 +8928,10 @@ const LayerIconContainer = styled.div `
|
|
|
8851
8928
|
display: flex;
|
|
8852
8929
|
align-items: center;
|
|
8853
8930
|
justify-content: center;
|
|
8854
|
-
min-width:
|
|
8855
|
-
|
|
8931
|
+
min-width: 1.5rem;
|
|
8932
|
+
width: 1.5rem;
|
|
8933
|
+
height: 1.5rem;
|
|
8934
|
+
margin-right: 1rem;
|
|
8856
8935
|
`;
|
|
8857
8936
|
const AlertIconContainer = styled(uilibGl.Flex) `
|
|
8858
8937
|
align-items: center;
|
|
@@ -9484,29 +9563,49 @@ const ElementIcon = React.memo(({ type, elementConfig }) => {
|
|
|
9484
9563
|
return (jsxRuntime.jsx(StyledIcon, { kind: iconValue, fontSize: fontSize, fontColor: fontColor, style: style }));
|
|
9485
9564
|
});
|
|
9486
9565
|
|
|
9487
|
-
const
|
|
9566
|
+
const useElementImage = ({ type, elementConfig, }) => {
|
|
9488
9567
|
const { attributes } = useWidgetContext(type);
|
|
9489
|
-
const { value, attributeName
|
|
9490
|
-
const
|
|
9491
|
-
|
|
9492
|
-
|
|
9568
|
+
const { value, attributeName } = elementConfig || {};
|
|
9569
|
+
const attribute = React.useMemo(() => {
|
|
9570
|
+
if (!attributeName || Array.isArray(attributeName))
|
|
9571
|
+
return undefined;
|
|
9572
|
+
return attributes?.find(item => item.attributeName === attributeName);
|
|
9573
|
+
}, [attributeName, attributes]);
|
|
9574
|
+
const isAttachmentAttribute = attribute?.subType === api.StringSubType.Attachments;
|
|
9575
|
+
const { items } = useAttachmentItems({ type, elementConfig });
|
|
9576
|
+
const imageItems = React.useMemo(() => items
|
|
9577
|
+
.filter(item => IMAGE_FILE_TYPES.includes(getFileType(item.mimeType, item.name)))
|
|
9578
|
+
.slice(0, 1), [items]);
|
|
9579
|
+
const attachmentImages = useAttachmentPreviewImages({
|
|
9580
|
+
items: imageItems,
|
|
9581
|
+
active: isAttachmentAttribute,
|
|
9582
|
+
});
|
|
9583
|
+
const stringUrl = React.useMemo(() => {
|
|
9584
|
+
if (value)
|
|
9493
9585
|
return getResourceUrl(value.toString());
|
|
9494
|
-
|
|
9495
|
-
|
|
9586
|
+
if (isAttachmentAttribute)
|
|
9587
|
+
return null;
|
|
9588
|
+
if (!attributeName || Array.isArray(attributeName))
|
|
9496
9589
|
return null;
|
|
9497
|
-
}
|
|
9498
|
-
const attribute = attributes?.find(item => item.attributeName === attributeName);
|
|
9499
9590
|
const imageUrl = attribute?.value?.split(";")?.[0];
|
|
9500
|
-
if (!imageUrl)
|
|
9591
|
+
if (!imageUrl)
|
|
9501
9592
|
return null;
|
|
9502
|
-
}
|
|
9503
9593
|
return getResourceUrl(imageUrl);
|
|
9504
|
-
}, [
|
|
9505
|
-
const
|
|
9506
|
-
|
|
9594
|
+
}, [value, isAttachmentAttribute, attributeName, attribute]);
|
|
9595
|
+
const stringBlobUrl = useFetchImageWithAuth(stringUrl);
|
|
9596
|
+
const attachmentSrc = attachmentImages[0]?.src || null;
|
|
9597
|
+
const src = isAttachmentAttribute ? attachmentSrc : stringBlobUrl;
|
|
9598
|
+
const alt = isAttachmentAttribute ? attachmentImages[0]?.fileName ?? "" : stringUrl ?? "";
|
|
9599
|
+
return { src, alt };
|
|
9600
|
+
};
|
|
9601
|
+
|
|
9602
|
+
const ElementImage = React.memo(({ type, elementConfig }) => {
|
|
9603
|
+
const { options, style } = elementConfig || {};
|
|
9604
|
+
const { width } = options || {};
|
|
9605
|
+
const { src, alt } = useElementImage({ type, elementConfig });
|
|
9606
|
+
if (!src)
|
|
9507
9607
|
return null;
|
|
9508
|
-
}
|
|
9509
|
-
return (jsxRuntime.jsx("img", { src: blobUrl, alt: firstImage ?? "", width: width, style: style }));
|
|
9608
|
+
return jsxRuntime.jsx("img", { src: src, alt: alt, width: width, style: style });
|
|
9510
9609
|
});
|
|
9511
9610
|
|
|
9512
9611
|
const ElementLegend = React.memo(({ type, element, elementConfig }) => {
|
|
@@ -9874,7 +9973,8 @@ const SlideshowHeaderWrapper = styled.div `
|
|
|
9874
9973
|
position: absolute;
|
|
9875
9974
|
top: 0;
|
|
9876
9975
|
left: 0;
|
|
9877
|
-
|
|
9976
|
+
width: 100%;
|
|
9977
|
+
height: 100%;
|
|
9878
9978
|
pointer-events: none;
|
|
9879
9979
|
}
|
|
9880
9980
|
|
|
@@ -9884,8 +9984,7 @@ const SlideshowHeaderWrapper = styled.div `
|
|
|
9884
9984
|
}
|
|
9885
9985
|
|
|
9886
9986
|
:after {
|
|
9887
|
-
|
|
9888
|
-
background: linear-gradient(180deg, #000000 0%, rgba(0, 0, 0, 0) 100%);
|
|
9987
|
+
background: linear-gradient(180deg, rgba(17, 37, 47, 0.75) 0%, rgba(17, 37, 47, 0.00) 100%);
|
|
9889
9988
|
}
|
|
9890
9989
|
|
|
9891
9990
|
:hover {
|
|
@@ -9933,12 +10032,13 @@ const HeaderSlideshow = styled.div `
|
|
|
9933
10032
|
`;
|
|
9934
10033
|
|
|
9935
10034
|
const FeatureCardBackgroundHeader = () => {
|
|
10035
|
+
const { themeName: pageThemeName } = useGlobalContext();
|
|
9936
10036
|
const { config } = useWidgetConfig(exports.WidgetType.FeatureCard);
|
|
9937
10037
|
const { header } = config || {};
|
|
9938
10038
|
const { options } = header || {};
|
|
9939
10039
|
const { fontColor, bgColor, height, overlay, bigIcon, withPadding, bottomBlur, themeName, column } = options || {};
|
|
9940
10040
|
const renderElement = useHeaderRender(header);
|
|
9941
|
-
return (jsxRuntime.jsx(BackgroundHeaderWrapper, { "$fontColor": fontColor, "$bgColor": bgColor, "$height": height, "$bigIcon": bigIcon, "$withPadding": withPadding, "$bottomBlur": bottomBlur, children: jsxRuntime.jsx(uilibGl.ThemeProvider, { theme: getThemeByName(themeName), children: jsxRuntime.jsxs(Header, { "$overlay": overlay, "$isRow": !column, children: [jsxRuntime.jsxs(HeaderFrontView, { children: [jsxRuntime.jsxs(HeaderContainer, { column: column, children: [jsxRuntime.jsx(HeaderLayerIcon, {}), jsxRuntime.jsx(FeatureCardTitle, { title: renderElement({
|
|
10041
|
+
return (jsxRuntime.jsx(BackgroundHeaderWrapper, { "$fontColor": fontColor, "$bgColor": bgColor, "$height": height, "$bigIcon": bigIcon, "$withPadding": withPadding, "$bottomBlur": bottomBlur, children: jsxRuntime.jsx(uilibGl.ThemeProvider, { theme: getThemeByName(themeName ?? pageThemeName), children: jsxRuntime.jsxs(Header, { "$overlay": overlay, "$isRow": !column, children: [jsxRuntime.jsxs(HeaderFrontView, { children: [jsxRuntime.jsxs(HeaderContainer, { column: column, children: [jsxRuntime.jsx(HeaderLayerIcon, {}), jsxRuntime.jsx(FeatureCardTitle, { title: renderElement({
|
|
9942
10042
|
id: "title",
|
|
9943
10043
|
wrap: false,
|
|
9944
10044
|
}), description: renderElement({
|
|
@@ -10324,8 +10424,8 @@ const getElementValue = ({ getDefaultContainer, ...props }) => {
|
|
|
10324
10424
|
return "";
|
|
10325
10425
|
}
|
|
10326
10426
|
const alias = attribute?.alias || attributeName || "";
|
|
10327
|
-
const { maxLength, lineBreak, expandable } = options || {};
|
|
10328
|
-
return alias && maxLength && maxLength < alias.length ? (jsxRuntime.jsx(TextTrim, { maxLength: maxLength, expandable: expandable, lineBreak: lineBreak, children: alias })) : (alias);
|
|
10427
|
+
const { maxLength, wordBreak, lineBreak, expandable } = options || {};
|
|
10428
|
+
return alias && maxLength && maxLength < alias.length ? (jsxRuntime.jsx(TextTrim, { maxLength: maxLength, wordBreak: wordBreak, expandable: expandable, lineBreak: lineBreak, children: alias })) : (alias);
|
|
10329
10429
|
}
|
|
10330
10430
|
if (type === "attributeValue") {
|
|
10331
10431
|
/* return isHandbookAttribute(attribute?.name, layerInfo) ? (
|
|
@@ -13187,15 +13287,20 @@ const SvgImage = React.memo(({ url, width, height, fontColor }) => {
|
|
|
13187
13287
|
return (jsxRuntime.jsx(StyledSvg, { "$width": width, "$height": height, "$fontColor": fontColor, dangerouslySetInnerHTML: { __html: svg } }));
|
|
13188
13288
|
});
|
|
13189
13289
|
|
|
13190
|
-
const
|
|
13290
|
+
const TextTrimValue = styled.div `
|
|
13291
|
+
word-break: ${({ wordBreak }) => wordBreak ?? "break-word"};
|
|
13292
|
+
overflow: hidden;
|
|
13293
|
+
`;
|
|
13294
|
+
|
|
13295
|
+
const TextTrim = React.memo(({ maxLength, expandable, lineBreak, wordBreak, children }) => {
|
|
13191
13296
|
const { t } = useGlobalContext();
|
|
13192
13297
|
const [expanded, toggleExpanded] = useToggle();
|
|
13193
13298
|
const text = children?.toString();
|
|
13194
13299
|
const formatValue = React.useCallback((value) => {
|
|
13195
13300
|
if (!lineBreak)
|
|
13196
|
-
return value;
|
|
13197
|
-
return jsxRuntime.jsx(
|
|
13198
|
-
}, [lineBreak]);
|
|
13301
|
+
return jsxRuntime.jsx(TextTrimValue, { wordBreak: wordBreak, children: value });
|
|
13302
|
+
return jsxRuntime.jsx(TextTrimValue, { wordBreak: wordBreak, dangerouslySetInnerHTML: { __html: lodash.unescape(value).split(lineBreak).join("<br />") } });
|
|
13303
|
+
}, [lineBreak, wordBreak]);
|
|
13199
13304
|
if (!text?.length || !maxLength || text.length <= maxLength)
|
|
13200
13305
|
return jsxRuntime.jsx(jsxRuntime.Fragment, { children: formatValue(text) });
|
|
13201
13306
|
const substring = `${text.substring(0, maxLength)}...`;
|