@evergis/react 3.1.38 → 3.1.40
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/ExportPdfContainer/index.d.ts +3 -0
- package/dist/components/Dashboard/containers/registry.d.ts +1 -0
- package/dist/components/Dashboard/hooks/index.d.ts +1 -0
- package/dist/components/Dashboard/hooks/useExportPdf.d.ts +4 -0
- package/dist/components/Dashboard/types.d.ts +1 -0
- package/dist/components/Dashboard/utils/getRootElementId.d.ts +2 -0
- package/dist/components/Dashboard/utils/index.d.ts +2 -0
- package/dist/index.js +116 -3
- package/dist/index.js.map +1 -1
- package/dist/react.esm.js +114 -4
- package/dist/react.esm.js.map +1 -1
- package/package.json +7 -3
|
@@ -27,5 +27,6 @@ export declare const containerComponents: {
|
|
|
27
27
|
readonly Camera: import('react').FC<import('../types').ContainerProps>;
|
|
28
28
|
readonly AddFeature: import('react').FC<import('../types').ContainerProps>;
|
|
29
29
|
readonly Divider: import('react').FC<import('../types').ContainerProps>;
|
|
30
|
+
readonly ExportPdf: import('react').FC<import('../types').ContainerProps>;
|
|
30
31
|
readonly default: import('react').FC<import('../types').ContainerProps>;
|
|
31
32
|
};
|
|
@@ -4,6 +4,7 @@ export * from './useDashboardHeader';
|
|
|
4
4
|
export * from './useDataSources';
|
|
5
5
|
export * from './useDiffPage';
|
|
6
6
|
export * from './useExpandableContainers';
|
|
7
|
+
export * from './useExportPdf';
|
|
7
8
|
export * from './useWidgetFilters';
|
|
8
9
|
export * from './useGetConfigLayer';
|
|
9
10
|
export * from './useGlobalContext';
|
|
@@ -14,6 +14,7 @@ export * from './formatElementValue';
|
|
|
14
14
|
export * from './getAttributeByName';
|
|
15
15
|
export * from './getAttributesConfiguration';
|
|
16
16
|
export * from './getAttributeValue';
|
|
17
|
+
export * from './getChartAxes';
|
|
17
18
|
export * from './getChartFilterName';
|
|
18
19
|
export * from './getChartMarkers';
|
|
19
20
|
export * from './getConfigFilter';
|
|
@@ -44,6 +45,7 @@ export * from './getSlideshowImages';
|
|
|
44
45
|
export * from './getSvgUrl';
|
|
45
46
|
export * from './getTotalFromAttributes';
|
|
46
47
|
export * from './getTotalFromRelatedFeatures';
|
|
48
|
+
export * from './getRootElementId';
|
|
47
49
|
export * from './isEmptyElementValue';
|
|
48
50
|
export * from './isEmptyValue';
|
|
49
51
|
export * from './isHiddenEmptyValue';
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,8 @@ var enUS = require('date-fns/locale/en-US');
|
|
|
14
14
|
var lodash = require('lodash');
|
|
15
15
|
var signalr = require('@microsoft/signalr');
|
|
16
16
|
var findAnd = require('find-and');
|
|
17
|
+
var jspdf = require('jspdf');
|
|
18
|
+
var html2canvas = require('html2canvas');
|
|
17
19
|
var MapboxDraw = require('@mapbox/mapbox-gl-draw');
|
|
18
20
|
var turf = require('@turf/turf');
|
|
19
21
|
var MapGL = require('react-map-gl/mapbox');
|
|
@@ -3377,6 +3379,7 @@ exports.ContainerTemplate = void 0;
|
|
|
3377
3379
|
ContainerTemplate["Camera"] = "Camera";
|
|
3378
3380
|
ContainerTemplate["AddFeature"] = "AddFeature";
|
|
3379
3381
|
ContainerTemplate["Slideshow"] = "Slideshow";
|
|
3382
|
+
ContainerTemplate["ExportPdf"] = "ExportPdf";
|
|
3380
3383
|
ContainerTemplate["Divider"] = "Divider";
|
|
3381
3384
|
})(exports.ContainerTemplate || (exports.ContainerTemplate = {}));
|
|
3382
3385
|
exports.HeaderTemplate = void 0;
|
|
@@ -5411,6 +5414,8 @@ const getAttributeValue = (element, attributes) => {
|
|
|
5411
5414
|
return maxLength && maxLength < value.length ? (jsxRuntime.jsx(TextTrim, { maxLength: maxLength, expandable: expandable, lineBreak: lineBreak, children: value })) : (value);
|
|
5412
5415
|
};
|
|
5413
5416
|
|
|
5417
|
+
const getChartAxes = (chartElement) => chartElement?.options?.relatedDataSources?.filter(({ chartAxis }) => chartAxis === "y");
|
|
5418
|
+
|
|
5414
5419
|
const getChartFilterName = (relatedDataSources) => {
|
|
5415
5420
|
const relatedAttributes = relatedDataSources || [];
|
|
5416
5421
|
const axes = relatedAttributes.filter(({ chartAxis }) => chartAxis === "y");
|
|
@@ -6004,7 +6009,7 @@ const PagesContainer = React.memo(({ type = exports.WidgetType.Dashboard, noBord
|
|
|
6004
6009
|
setSelectedTabId,
|
|
6005
6010
|
type,
|
|
6006
6011
|
]);
|
|
6007
|
-
return (jsxRuntime.
|
|
6012
|
+
return (jsxRuntime.jsx(Container, { id: getRootElementId(type), style: { width }, isMain: true, isColumn: isColumn, noBorders: noBorders, children: jsxRuntime.jsx(ContainerChildren, { items: filteredChildren, isMain: true, renderElement: renderElement }) }));
|
|
6008
6013
|
});
|
|
6009
6014
|
|
|
6010
6015
|
const TwoColumnsInnerContainer = React.memo(({ renderElement }) => {
|
|
@@ -6572,6 +6577,14 @@ const LayersContainer = React.memo(({ type, elementConfig, renderElement }) => {
|
|
|
6572
6577
|
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(LayersContainerWrapper, { style: style, children: jsxRuntime.jsx(LayerTree, { layers: layers, onlyMainTools: true }) }))] }));
|
|
6573
6578
|
});
|
|
6574
6579
|
|
|
6580
|
+
const ExportPdfContainer = React.memo(({ type, elementConfig }) => {
|
|
6581
|
+
const { t } = useGlobalContext();
|
|
6582
|
+
const { loading, onExport } = useExportPdf(getRootElementId(type));
|
|
6583
|
+
const { style, options } = elementConfig || {};
|
|
6584
|
+
const { icon, title } = options || {};
|
|
6585
|
+
return (jsxRuntime.jsx(Container, { children: jsxRuntime.jsx(uilibGl.IconButton, { kind: icon || "download", primary: true, disabled: loading, style: style, onClick: onExport, children: title ?? t("downloadPdf", { ns: "dashboard", defaultValue: "Скачать PDF" }) }) }));
|
|
6586
|
+
});
|
|
6587
|
+
|
|
6575
6588
|
const containerComponents = {
|
|
6576
6589
|
[exports.ContainerTemplate.DefaultAttributes]: DefaultAttributesContainer,
|
|
6577
6590
|
[exports.ContainerTemplate.Pages]: PagesContainer,
|
|
@@ -6593,6 +6606,7 @@ const containerComponents = {
|
|
|
6593
6606
|
[exports.ContainerTemplate.Camera]: CameraContainer,
|
|
6594
6607
|
[exports.ContainerTemplate.AddFeature]: AddFeatureContainer,
|
|
6595
6608
|
[exports.ContainerTemplate.Divider]: DividerContainer,
|
|
6609
|
+
[exports.ContainerTemplate.ExportPdf]: ExportPdfContainer,
|
|
6596
6610
|
default: ContainersGroupContainer,
|
|
6597
6611
|
};
|
|
6598
6612
|
|
|
@@ -7420,8 +7434,6 @@ const ElementImage = React.memo(({ type, elementConfig }) => {
|
|
|
7420
7434
|
return firstImage ? jsxRuntime.jsx("img", { src: firstImage, alt: firstImage, width: width }) : null;
|
|
7421
7435
|
});
|
|
7422
7436
|
|
|
7423
|
-
const getChartAxes = (chartElement) => chartElement?.options?.relatedDataSources?.filter(({ chartAxis }) => chartAxis === "y");
|
|
7424
|
-
|
|
7425
7437
|
const ElementLegend = React.memo(({ type, element, elementConfig, expandedContainers }) => {
|
|
7426
7438
|
const { attributes, dataSources } = useWidgetContext(type);
|
|
7427
7439
|
const { options } = elementConfig || {};
|
|
@@ -8632,6 +8644,8 @@ const getTotalFromRelatedFeatures = (data) => {
|
|
|
8632
8644
|
return data?.reduce((result, { value }) => result + Number(value), 0)?.toFixed(0) || "";
|
|
8633
8645
|
};
|
|
8634
8646
|
|
|
8647
|
+
const getRootElementId = (type = exports.WidgetType.Dashboard) => `${type}-root`;
|
|
8648
|
+
|
|
8635
8649
|
const pieChartTooltipFromAttributes = (t, data, attributes) => {
|
|
8636
8650
|
const attribute = attributes?.find(({ name }) => name === data[0].name);
|
|
8637
8651
|
const renderValue = attribute
|
|
@@ -9086,6 +9100,102 @@ const useExpandableContainers = () => {
|
|
|
9086
9100
|
return [expandedContainers, expandContainer];
|
|
9087
9101
|
};
|
|
9088
9102
|
|
|
9103
|
+
const useExportPdf = (id, margin = 20) => {
|
|
9104
|
+
const [loading, setLoading] = React.useState(false);
|
|
9105
|
+
const onExport = React.useCallback(async () => {
|
|
9106
|
+
if (!id) {
|
|
9107
|
+
return;
|
|
9108
|
+
}
|
|
9109
|
+
setLoading(true);
|
|
9110
|
+
const container = document.querySelector(`#${id}`);
|
|
9111
|
+
if (!container) {
|
|
9112
|
+
setLoading(false);
|
|
9113
|
+
return;
|
|
9114
|
+
}
|
|
9115
|
+
// Сохраняем оригинальные стили для восстановления
|
|
9116
|
+
const originalStyles = {
|
|
9117
|
+
overflow: container.style.overflow,
|
|
9118
|
+
position: container.style.position,
|
|
9119
|
+
};
|
|
9120
|
+
// Временные стили для точного измерения
|
|
9121
|
+
container.style.overflow = 'visible';
|
|
9122
|
+
container.style.position = 'relative';
|
|
9123
|
+
const pdf = new jspdf.jsPDF("p", "px", "a4", false);
|
|
9124
|
+
const pageWidth = pdf.internal.pageSize.getWidth();
|
|
9125
|
+
const pageHeight = pdf.internal.pageSize.getHeight();
|
|
9126
|
+
const availableHeight = pageHeight - (2 * margin);
|
|
9127
|
+
// Получаем все дочерние элементы
|
|
9128
|
+
const children = Array.from(container.children);
|
|
9129
|
+
let currentPageHeight = 0;
|
|
9130
|
+
let currentPageElements = [];
|
|
9131
|
+
const pages = [];
|
|
9132
|
+
// Распределяем элементы по страницам
|
|
9133
|
+
for (const child of children) {
|
|
9134
|
+
const childHeight = child.offsetHeight;
|
|
9135
|
+
// Если элемент не помещается на текущей странице, начинаем новую
|
|
9136
|
+
if (currentPageHeight + childHeight > availableHeight && currentPageElements.length > 0) {
|
|
9137
|
+
pages.push([...currentPageElements]);
|
|
9138
|
+
currentPageElements = [];
|
|
9139
|
+
currentPageHeight = 0;
|
|
9140
|
+
}
|
|
9141
|
+
currentPageElements.push(child);
|
|
9142
|
+
currentPageHeight += childHeight;
|
|
9143
|
+
}
|
|
9144
|
+
// Добавляем последнюю страницу
|
|
9145
|
+
if (currentPageElements.length > 0) {
|
|
9146
|
+
pages.push(currentPageElements);
|
|
9147
|
+
}
|
|
9148
|
+
// Генерируем PDF для каждой страницы
|
|
9149
|
+
for (let pageIndex = 0; pageIndex < pages.length; pageIndex++) {
|
|
9150
|
+
if (pageIndex > 0) {
|
|
9151
|
+
pdf.addPage();
|
|
9152
|
+
}
|
|
9153
|
+
const pageElements = pages[pageIndex];
|
|
9154
|
+
// Создаем временный контейнер для текущей страницы
|
|
9155
|
+
const tempContainer = document.createElement('div');
|
|
9156
|
+
tempContainer.style.position = 'absolute';
|
|
9157
|
+
tempContainer.style.left = '-9999px';
|
|
9158
|
+
tempContainer.style.top = '0';
|
|
9159
|
+
tempContainer.style.width = container.offsetWidth + 'px';
|
|
9160
|
+
tempContainer.style.overflow = 'visible';
|
|
9161
|
+
// Клонируем элементы для текущей страницы
|
|
9162
|
+
pageElements.forEach(element => {
|
|
9163
|
+
const clone = element.cloneNode(true);
|
|
9164
|
+
tempContainer.appendChild(clone);
|
|
9165
|
+
});
|
|
9166
|
+
document.body.appendChild(tempContainer);
|
|
9167
|
+
try {
|
|
9168
|
+
const canvas = await html2canvas(tempContainer, {
|
|
9169
|
+
scale: 2,
|
|
9170
|
+
useCORS: true,
|
|
9171
|
+
logging: false,
|
|
9172
|
+
backgroundColor: '#ffffff',
|
|
9173
|
+
width: container.offsetWidth,
|
|
9174
|
+
height: tempContainer.offsetHeight,
|
|
9175
|
+
});
|
|
9176
|
+
const imgData = canvas.toDataURL('image/png', 1.0);
|
|
9177
|
+
const imgWidth = pageWidth - (2 * margin);
|
|
9178
|
+
const imgHeight = (canvas.height * imgWidth) / canvas.width;
|
|
9179
|
+
// Центрируем по горизонтали и добавляем с верхним отступом
|
|
9180
|
+
pdf.addImage(imgData, 'PNG', margin, margin, imgWidth, imgHeight);
|
|
9181
|
+
}
|
|
9182
|
+
catch (error) {
|
|
9183
|
+
console.error('Error generating page:', error);
|
|
9184
|
+
}
|
|
9185
|
+
finally {
|
|
9186
|
+
// Удаляем временный контейнер
|
|
9187
|
+
document.body.removeChild(tempContainer);
|
|
9188
|
+
}
|
|
9189
|
+
}
|
|
9190
|
+
// Восстанавливаем оригинальные стили
|
|
9191
|
+
container.style.overflow = originalStyles.overflow;
|
|
9192
|
+
container.style.position = originalStyles.position;
|
|
9193
|
+
pdf.save(`${dateFns.format(new Date(), "yyyy-MM-dd_HH:mm:ss")}.pdf`);
|
|
9194
|
+
setLoading(false);
|
|
9195
|
+
}, [id, margin]);
|
|
9196
|
+
return { loading, onExport };
|
|
9197
|
+
};
|
|
9198
|
+
|
|
9089
9199
|
const getMinMaxFromStringValue = (items, value, current, type) => {
|
|
9090
9200
|
const valueIndex = items.findIndex(item => item.value === (type === "min" ? value.min : value.max));
|
|
9091
9201
|
const currentIndex = items.findIndex(item => item.value === (type === "min" ? value.min : value.max));
|
|
@@ -10142,6 +10252,7 @@ exports.getActualExtrusionHeight = getActualExtrusionHeight;
|
|
|
10142
10252
|
exports.getAttributeByName = getAttributeByName;
|
|
10143
10253
|
exports.getAttributeValue = getAttributeValue;
|
|
10144
10254
|
exports.getAttributesConfiguration = getAttributesConfiguration;
|
|
10255
|
+
exports.getChartAxes = getChartAxes;
|
|
10145
10256
|
exports.getChartFilterName = getChartFilterName;
|
|
10146
10257
|
exports.getChartMarkers = getChartMarkers;
|
|
10147
10258
|
exports.getConfigFilter = getConfigFilter;
|
|
@@ -10170,6 +10281,7 @@ exports.getProxyService = getProxyService;
|
|
|
10170
10281
|
exports.getRelatedAttribute = getRelatedAttribute;
|
|
10171
10282
|
exports.getRenderElement = getRenderElement;
|
|
10172
10283
|
exports.getResourceUrl = getResourceUrl;
|
|
10284
|
+
exports.getRootElementId = getRootElementId;
|
|
10173
10285
|
exports.getSelectedFilterValue = getSelectedFilterValue;
|
|
10174
10286
|
exports.getSlideshowImages = getSlideshowImages;
|
|
10175
10287
|
exports.getSvgUrl = getSvgUrl;
|
|
@@ -10209,6 +10321,7 @@ exports.useDataSources = useDataSources;
|
|
|
10209
10321
|
exports.useDebouncedCallback = useDebouncedCallback;
|
|
10210
10322
|
exports.useDiffPage = useDiffPage;
|
|
10211
10323
|
exports.useExpandableContainers = useExpandableContainers;
|
|
10324
|
+
exports.useExportPdf = useExportPdf;
|
|
10212
10325
|
exports.useGetConfigLayer = useGetConfigLayer;
|
|
10213
10326
|
exports.useGlobalContext = useGlobalContext;
|
|
10214
10327
|
exports.useHeaderRender = useHeaderRender;
|