@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.
@@ -0,0 +1,3 @@
1
+ import { FC } from 'react';
2
+ import { ContainerProps } from '../../types';
3
+ export declare const ExportPdfContainer: FC<ContainerProps>;
@@ -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';
@@ -0,0 +1,4 @@
1
+ export declare const useExportPdf: (id: string, margin?: number) => {
2
+ loading: boolean;
3
+ onExport: () => Promise<void>;
4
+ };
@@ -238,6 +238,7 @@ export declare enum ContainerTemplate {
238
238
  Camera = "Camera",
239
239
  AddFeature = "AddFeature",
240
240
  Slideshow = "Slideshow",
241
+ ExportPdf = "ExportPdf",
241
242
  Divider = "Divider"
242
243
  }
243
244
  export declare enum HeaderTemplate {
@@ -0,0 +1,2 @@
1
+ import { WidgetType } from '../types';
2
+ export declare const getRootElementId: (type?: WidgetType) => string;
@@ -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.jsxs("div", { style: { width }, children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: config, type: type, renderElement: renderElement }), jsxRuntime.jsx(Container, { isColumn: isColumn, isMain: true, noBorders: noBorders, children: jsxRuntime.jsx(ContainerChildren, { items: filteredChildren, isMain: true, renderElement: renderElement }) })] }));
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;