change(ui) - fix dashboard report generate, added lazyload, and other improvements
This commit is contained in:
parent
631b4fdd97
commit
5d67f49a9e
5 changed files with 273 additions and 225 deletions
|
|
@ -1,97 +1,110 @@
|
|||
import React from 'react';
|
||||
import { toJS } from 'mobx'
|
||||
import { useStore } from 'App/mstore';
|
||||
import WidgetWrapper from '../WidgetWrapper';
|
||||
import { NoContent, Loader, Icon } from 'UI';
|
||||
import { useObserver } from 'mobx-react-lite';
|
||||
import AddMetricContainer from './AddMetricContainer'
|
||||
import AddMetricContainer from './AddMetricContainer';
|
||||
import Widget from 'App/mstore/types/widget';
|
||||
|
||||
interface Props {
|
||||
siteId: string,
|
||||
dashboardId: string;
|
||||
onEditHandler: () => void;
|
||||
id?: string;
|
||||
siteId: string;
|
||||
dashboardId: string;
|
||||
onEditHandler: () => void;
|
||||
id?: string;
|
||||
}
|
||||
function DashboardWidgetGrid(props: Props) {
|
||||
const { dashboardId, siteId } = props;
|
||||
const { dashboardStore } = useStore();
|
||||
const loading = useObserver(() => dashboardStore.isLoading);
|
||||
const dashboard = dashboardStore.selectedDashboard;
|
||||
const list = useObserver(() => dashboard?.widgets);
|
||||
const smallWidgets: Widget[] = []
|
||||
const regularWidgets: Widget[] = []
|
||||
const { dashboardId, siteId } = props;
|
||||
const { dashboardStore } = useStore();
|
||||
const loading = useObserver(() => dashboardStore.isLoading);
|
||||
const dashboard = dashboardStore.selectedDashboard;
|
||||
const list = useObserver(() => dashboard?.widgets);
|
||||
const smallWidgets: Widget[] = [];
|
||||
const regularWidgets: Widget[] = [];
|
||||
|
||||
list.forEach(item => {
|
||||
if (item.config.col === 1) {
|
||||
smallWidgets.push(item)
|
||||
} else {
|
||||
regularWidgets.push(item)
|
||||
list.forEach((item) => {
|
||||
if (item.config.col === 1) {
|
||||
smallWidgets.push(item);
|
||||
} else {
|
||||
regularWidgets.push(item);
|
||||
}
|
||||
});
|
||||
|
||||
const smallWidgetsLen = smallWidgets.length;
|
||||
|
||||
return useObserver(() => (
|
||||
// @ts-ignore
|
||||
<Loader loading={loading}>
|
||||
<NoContent
|
||||
show={list.length === 0}
|
||||
icon="no-metrics-chart"
|
||||
title={
|
||||
<span className="text-2xl capitalize-first text-figmaColors-text-primary">
|
||||
Build your dashboard
|
||||
</span>
|
||||
}
|
||||
})
|
||||
subtext={
|
||||
<div className="w-4/5 m-auto mt-4">
|
||||
<AddMetricContainer siteId={siteId} />
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div className="grid gap-4 grid-cols-4 items-start pb-10" id={props.id}>
|
||||
{smallWidgets.length > 0 ? (
|
||||
<>
|
||||
<div className="font-semibold text-xl py-4 flex items-center gap-2 col-span-4">
|
||||
<Icon name="grid-horizontal" size={26} />
|
||||
Web Vitals
|
||||
</div>
|
||||
{smallWidgets &&
|
||||
smallWidgets.map((item: any, index: any) => (
|
||||
<React.Fragment key={item.widgetId}>
|
||||
<WidgetWrapper
|
||||
index={index}
|
||||
widget={item}
|
||||
moveListItem={(dragIndex: any, hoverIndex: any) =>
|
||||
dashboard.swapWidgetPosition(dragIndex, hoverIndex)
|
||||
}
|
||||
dashboardId={dashboardId}
|
||||
siteId={siteId}
|
||||
isWidget={true}
|
||||
grid="vitals"
|
||||
/>
|
||||
</React.Fragment>
|
||||
))}
|
||||
</>
|
||||
) : null}
|
||||
|
||||
const smallWidgetsLen = smallWidgets.length
|
||||
{smallWidgets.length > 0 && regularWidgets.length > 0 ? (
|
||||
<div className="font-semibold text-xl py-4 flex items-center gap-2 col-span-4">
|
||||
<Icon name="grid-horizontal" size={26} />
|
||||
All Metrics
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
return useObserver(() => (
|
||||
// @ts-ignore
|
||||
<Loader loading={loading}>
|
||||
<NoContent
|
||||
show={list.length === 0}
|
||||
icon="no-metrics-chart"
|
||||
title={<span className="text-2xl capitalize-first text-figmaColors-text-primary">Build your dashboard</span>}
|
||||
subtext={
|
||||
<div className="w-4/5 m-auto mt-4"><AddMetricContainer siteId={siteId} /></div>
|
||||
}
|
||||
>
|
||||
{smallWidgets.length > 0 ? (
|
||||
<>
|
||||
<div className="font-semibold text-xl py-4 flex items-center gap-2">
|
||||
<Icon name="grid-horizontal" size={26} />
|
||||
Web Vitals
|
||||
</div>
|
||||
<div className="grid gap-4 grid-cols-4 items-start pb-10" id={props.id}>
|
||||
{smallWidgets && smallWidgets.map((item: any, index: any) => (
|
||||
<React.Fragment key={item.widgetId}>
|
||||
<WidgetWrapper
|
||||
index={index}
|
||||
widget={item}
|
||||
moveListItem={(dragIndex: any, hoverIndex: any) => dashboard.swapWidgetPosition(dragIndex, hoverIndex)}
|
||||
dashboardId={dashboardId}
|
||||
siteId={siteId}
|
||||
isWidget={true}
|
||||
grid="vitals"
|
||||
/>
|
||||
</React.Fragment>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
) : null}
|
||||
{regularWidgets &&
|
||||
regularWidgets.map((item: any, index: any) => (
|
||||
<React.Fragment key={item.widgetId}>
|
||||
<WidgetWrapper
|
||||
index={smallWidgetsLen + index}
|
||||
widget={item}
|
||||
moveListItem={(dragIndex: any, hoverIndex: any) =>
|
||||
dashboard.swapWidgetPosition(dragIndex, hoverIndex)
|
||||
}
|
||||
dashboardId={dashboardId}
|
||||
siteId={siteId}
|
||||
isWidget={true}
|
||||
grid="other"
|
||||
/>
|
||||
</React.Fragment>
|
||||
))}
|
||||
|
||||
{smallWidgets.length > 0 && regularWidgets.length > 0 ? (
|
||||
<div className="font-semibold text-xl py-4 flex items-center gap-2">
|
||||
<Icon name="grid-horizontal" size={26} />
|
||||
All Metrics
|
||||
</div>
|
||||
) : null}
|
||||
<div className="grid gap-4 grid-cols-4 items-start pb-10" id={props.id}>
|
||||
{regularWidgets && regularWidgets.map((item: any, index: any) => (
|
||||
<React.Fragment key={item.widgetId}>
|
||||
<WidgetWrapper
|
||||
index={smallWidgetsLen + index}
|
||||
widget={item}
|
||||
moveListItem={(dragIndex: any, hoverIndex: any) => dashboard.swapWidgetPosition(dragIndex, hoverIndex)}
|
||||
dashboardId={dashboardId}
|
||||
siteId={siteId}
|
||||
isWidget={true}
|
||||
grid="other"
|
||||
/>
|
||||
</React.Fragment>
|
||||
))}
|
||||
<div className="col-span-2"><AddMetricContainer siteId={siteId} /></div>
|
||||
</div>
|
||||
</NoContent>
|
||||
</Loader>
|
||||
));
|
||||
<div className="col-span-2" id="no-print">
|
||||
<AddMetricContainer siteId={siteId} />
|
||||
</div>
|
||||
</div>
|
||||
</NoContent>
|
||||
</Loader>
|
||||
));
|
||||
}
|
||||
|
||||
export default DashboardWidgetGrid;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import TemplateOverlay from './TemplateOverlay';
|
|||
import AlertButton from './AlertButton';
|
||||
import stl from './widgetWrapper.module.css';
|
||||
import { FilterKey } from 'App/types/filter/filterType';
|
||||
import LazyLoad from 'react-lazyload';
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
|
|
@ -147,10 +148,11 @@ function WidgetWrapper(props: Props & RouteComponentProps) {
|
|||
</div>
|
||||
|
||||
{/* <LazyLoad height={!isTemplate ? 300 : 10} offset={!isTemplate ? 100 : 10} > */}
|
||||
<LazyLoad offset={!isTemplate ? 100 : 10} >
|
||||
<div className="px-4" onClick={onChartClick}>
|
||||
<WidgetChart metric={widget} isTemplate={isTemplate} isWidget={isWidget} />
|
||||
</div>
|
||||
{/* </LazyLoad> */}
|
||||
</LazyLoad>
|
||||
</Popup>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -6,154 +6,181 @@ import { observer, useObserver } from 'mobx-react-lite';
|
|||
import { connect } from 'react-redux';
|
||||
import { fileNameFormat } from 'App/utils';
|
||||
import { toast } from 'react-toastify';
|
||||
import { forceVisible } from 'react-lazyload';
|
||||
|
||||
const TEXT_GENERATING = 'Generating report...';
|
||||
const TEXT_SUCCESS = 'Report successfully generated';
|
||||
interface Props {
|
||||
site: any;
|
||||
site: any;
|
||||
}
|
||||
export default function withReport<P extends Props>(WrappedComponent: React.ComponentType<P>) {
|
||||
const ComponentWithReport = (props: P) => {
|
||||
const [rendering, setRendering] = React.useState(false);
|
||||
const { site } = props;
|
||||
const { dashboardStore } = useStore();
|
||||
const dashboard: any = useObserver(() => dashboardStore.selectedDashboard);
|
||||
const widgets: any = useObserver(() => dashboard?.widgets);
|
||||
const period = useObserver(() => dashboardStore.period);
|
||||
const ComponentWithReport = (props: P) => {
|
||||
const [rendering, setRendering] = React.useState(false);
|
||||
const { site } = props;
|
||||
const { dashboardStore } = useStore();
|
||||
const dashboard: any = useObserver(() => dashboardStore.selectedDashboard);
|
||||
const period = useObserver(() => dashboardStore.period);
|
||||
const pendingRequests = useObserver(() => dashboardStore.pendingReuqests);
|
||||
|
||||
const addFooters = (doc: any) => {
|
||||
const pageCount = doc.internal.getNumberOfPages();
|
||||
for (var i = 1; i <= pageCount; i++) {
|
||||
doc.setPage(i);
|
||||
doc.setFontSize(8);
|
||||
doc.setTextColor(136, 136, 136);
|
||||
doc.text('Page ' + String(i) + ' of ' + String(pageCount), 200, 290, null, null, 'right');
|
||||
doc.addImage('/assets/img/logo-open-replay-grey.png', 'png', 10, 288, 20, 0);
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
if (rendering && pendingRequests <= 0) {
|
||||
processReport();
|
||||
}
|
||||
}, [pendingRequests]);
|
||||
|
||||
const renderPromise = async (): Promise<any> => {
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
renderReport(resolve);
|
||||
});
|
||||
toast.promise(promise, {
|
||||
pending: 'Generating report...',
|
||||
success: 'Report successfully generated',
|
||||
});
|
||||
};
|
||||
|
||||
const renderReport = async (cb: any) => {
|
||||
document.body.scrollIntoView();
|
||||
const doc = new jsPDF('p', 'mm', 'a4');
|
||||
const now = new Date().toISOString();
|
||||
|
||||
doc.addMetadata('Author', 'OpenReplay');
|
||||
doc.addMetadata('Title', 'OpenReplay Report');
|
||||
doc.addMetadata('Subject', 'OpenReplay Report');
|
||||
doc.addMetadata('Keywords', 'OpenReplay Report');
|
||||
doc.addMetadata('Creator', 'OpenReplay');
|
||||
doc.addMetadata('Producer', 'OpenReplay');
|
||||
doc.addMetadata('CreationDate', now);
|
||||
|
||||
const parentElement = document.getElementById('report') as HTMLElement;
|
||||
const pageHeight = 1200;
|
||||
const pagesCount = parentElement.offsetHeight / pageHeight;
|
||||
const pages: Array<any> = [];
|
||||
for (let i = 0; i < pagesCount; i++) {
|
||||
const page = document.createElement('div');
|
||||
page.classList.add('page');
|
||||
page.style.height = `${pageHeight}px`;
|
||||
page.style.whiteSpace = 'no-wrap !important';
|
||||
|
||||
const childrens = Array.from(parentElement.children).filter((child) => {
|
||||
const rect = child.getBoundingClientRect();
|
||||
const parentRect = parentElement.getBoundingClientRect();
|
||||
const top = rect.top - parentRect.top;
|
||||
return top >= i * pageHeight && top < (i + 1) * pageHeight;
|
||||
});
|
||||
if (childrens.length > 0) {
|
||||
pages.push(childrens);
|
||||
}
|
||||
}
|
||||
|
||||
const rportLayer = document.getElementById('report-layer');
|
||||
|
||||
pages.forEach(async (page, index) => {
|
||||
const pageDiv = document.createElement('div');
|
||||
pageDiv.classList.add('grid', 'gap-4', 'grid-cols-4', 'items-start', 'pb-10', 'auto-rows-min', 'printable-report');
|
||||
pageDiv.id = `page-${index}`;
|
||||
pageDiv.style.backgroundColor = '#f6f6f6';
|
||||
pageDiv.style.gridAutoRows = 'min-content';
|
||||
pageDiv.style.padding = '50px';
|
||||
pageDiv.style.height = '490mm';
|
||||
|
||||
if (index > 0) {
|
||||
pageDiv.style.paddingTop = '100px';
|
||||
}
|
||||
|
||||
if (index === 0) {
|
||||
const header = document.getElementById('report-header')?.cloneNode(true) as HTMLElement;
|
||||
header.classList.add('col-span-4');
|
||||
header.style.display = 'block';
|
||||
pageDiv.appendChild(header);
|
||||
}
|
||||
page.forEach((child: any) => {
|
||||
pageDiv.appendChild(child.cloneNode(true));
|
||||
});
|
||||
rportLayer?.appendChild(pageDiv);
|
||||
});
|
||||
|
||||
setTimeout(async () => {
|
||||
for (let i = 0; i < pages.length; i++) {
|
||||
const pageDiv = document.getElementById(`page-${i}`) as HTMLElement;
|
||||
const pageImage = await convertElementToImage(pageDiv);
|
||||
doc.addImage(pageImage, 'PNG', 0, 0, 210, 0);
|
||||
if (i === pages.length - 1) {
|
||||
addFooters(doc);
|
||||
doc.save(fileNameFormat(dashboard.name + '_Report_' + Date.now(), '.pdf'));
|
||||
rportLayer!.innerHTML = '';
|
||||
cb();
|
||||
} else {
|
||||
doc.addPage();
|
||||
}
|
||||
}
|
||||
}, 100);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="mb-2" id="report-header" style={{ display: 'none' }}>
|
||||
<div className="flex items-end justify-between" style={{ margin: '-50px', padding: '25px 50px', backgroundColor: 'white' }}>
|
||||
<div className="flex items-center">
|
||||
<img src="/assets/logo.svg" style={{ height: '30px' }} />
|
||||
<div className="text-lg color-gray-medium ml-2 mt-1">REPORT</div>
|
||||
</div>
|
||||
<div style={{ whiteSpace: 'nowrap' }}>
|
||||
<span className="font-semibold">Project:</span> {site && site.name}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-end mt-20 justify-between">
|
||||
<div className="text-2xl font-semibold">{dashboard && dashboard.name}</div>
|
||||
<div className="font-semibold">
|
||||
{period && period.range.start.format('MMM Do YY') + ' - ' + period.range.end.format('MMM Do YY')}
|
||||
</div>
|
||||
</div>
|
||||
{dashboard && dashboard.description && <div className="color-gray-medum whitespace-pre-wrap my-2">{dashboard.description}</div>}
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="report-layer"
|
||||
style={{
|
||||
position: 'fixed',
|
||||
top: '0',
|
||||
left: '0',
|
||||
zIndex: '-1',
|
||||
opacity: '0',
|
||||
}}
|
||||
></div>
|
||||
<WrappedComponent {...props} renderReport={renderPromise} rendering={rendering} />
|
||||
</>
|
||||
);
|
||||
const addFooters = (doc: any) => {
|
||||
const pageCount = doc.internal.getNumberOfPages();
|
||||
for (var i = 1; i <= pageCount; i++) {
|
||||
doc.setPage(i);
|
||||
doc.setFontSize(8);
|
||||
doc.setTextColor(136, 136, 136);
|
||||
doc.text('Page ' + String(i) + ' of ' + String(pageCount), 200, 290, null, null, 'right');
|
||||
doc.addImage('/assets/img/logo-open-replay-grey.png', 'png', 10, 288, 20, 0);
|
||||
}
|
||||
};
|
||||
|
||||
return connect((state: any) => ({
|
||||
site: state.getIn(['site', 'instance']),
|
||||
}))(ComponentWithReport);
|
||||
const renderPromise = async (): Promise<any> => {
|
||||
forceVisible();
|
||||
setRendering(true);
|
||||
toast.info(TEXT_GENERATING, {
|
||||
autoClose: false,
|
||||
isLoading: true,
|
||||
});
|
||||
};
|
||||
|
||||
const processReport = () => {
|
||||
document.body.scrollIntoView();
|
||||
const doc = new jsPDF('p', 'mm', 'a4');
|
||||
const now = new Date().toISOString();
|
||||
|
||||
doc.addMetadata('Author', 'OpenReplay');
|
||||
doc.addMetadata('Title', 'OpenReplay Report');
|
||||
doc.addMetadata('Subject', 'OpenReplay Report');
|
||||
doc.addMetadata('Keywords', 'OpenReplay Report');
|
||||
doc.addMetadata('Creator', 'OpenReplay');
|
||||
doc.addMetadata('Producer', 'OpenReplay');
|
||||
doc.addMetadata('CreationDate', now);
|
||||
|
||||
const parentElement = document.getElementById('report') as HTMLElement;
|
||||
const pageHeight = 1200;
|
||||
const pagesCount = parentElement.offsetHeight / pageHeight;
|
||||
const pages: Array<any> = [];
|
||||
for (let i = 0; i < pagesCount; i++) {
|
||||
const page = document.createElement('div');
|
||||
page.classList.add('page');
|
||||
page.style.height = `${pageHeight}px`;
|
||||
page.style.whiteSpace = 'no-wrap !important';
|
||||
|
||||
const childrens = Array.from(parentElement.children).filter((child) => {
|
||||
const rect = child.getBoundingClientRect();
|
||||
const parentRect = parentElement.getBoundingClientRect();
|
||||
const top = rect.top - parentRect.top;
|
||||
return top >= i * pageHeight && top < (i + 1) * pageHeight;
|
||||
});
|
||||
if (childrens.length > 0) {
|
||||
pages.push(childrens);
|
||||
}
|
||||
}
|
||||
|
||||
const rportLayer = document.getElementById('report-layer');
|
||||
|
||||
pages.forEach(async (page, index) => {
|
||||
const pageDiv = document.createElement('div');
|
||||
pageDiv.classList.add(
|
||||
'grid',
|
||||
'gap-4',
|
||||
'grid-cols-4',
|
||||
'items-start',
|
||||
'pb-10',
|
||||
'auto-rows-min',
|
||||
'printable-report'
|
||||
);
|
||||
pageDiv.id = `page-${index}`;
|
||||
pageDiv.style.backgroundColor = '#f6f6f6';
|
||||
pageDiv.style.gridAutoRows = 'min-content';
|
||||
pageDiv.style.padding = '50px';
|
||||
pageDiv.style.height = '490mm';
|
||||
|
||||
if (index > 0) {
|
||||
pageDiv.style.paddingTop = '100px';
|
||||
}
|
||||
|
||||
if (index === 0) {
|
||||
const header = document.getElementById('report-header')?.cloneNode(true) as HTMLElement;
|
||||
header.classList.add('col-span-4');
|
||||
header.style.display = 'block';
|
||||
pageDiv.appendChild(header);
|
||||
}
|
||||
page.forEach((child: any) => {
|
||||
pageDiv.appendChild(child.cloneNode(true));
|
||||
});
|
||||
rportLayer?.appendChild(pageDiv);
|
||||
});
|
||||
|
||||
setTimeout(async () => {
|
||||
for (let i = 0; i < pages.length; i++) {
|
||||
const pageDiv = document.getElementById(`page-${i}`) as HTMLElement;
|
||||
const pageImage = await convertElementToImage(pageDiv);
|
||||
doc.addImage(pageImage, 'PNG', 0, 0, 210, 0);
|
||||
if (i === pages.length - 1) {
|
||||
addFooters(doc);
|
||||
doc.save(fileNameFormat(dashboard.name + '_Report_' + Date.now(), '.pdf'));
|
||||
rportLayer!.innerHTML = '';
|
||||
setRendering(false);
|
||||
toast.dismiss();
|
||||
toast.success(TEXT_SUCCESS);
|
||||
} else {
|
||||
doc.addPage();
|
||||
}
|
||||
}
|
||||
}, 100);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="mb-2" id="report-header" style={{ display: 'none' }}>
|
||||
<div
|
||||
className="flex items-end justify-between"
|
||||
style={{ margin: '-50px', padding: '25px 50px', backgroundColor: 'white' }}
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<img src="/assets/logo.svg" style={{ height: '30px' }} />
|
||||
<div className="text-lg color-gray-medium ml-2 mt-1">REPORT</div>
|
||||
</div>
|
||||
<div style={{ whiteSpace: 'nowrap' }}>
|
||||
<span className="font-semibold">Project:</span> {site && site.name}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-end mt-20 justify-between">
|
||||
<div className="text-2xl font-semibold">{dashboard && dashboard.name}</div>
|
||||
<div className="font-semibold">
|
||||
{period &&
|
||||
period.range.start.format('MMM Do YY') +
|
||||
' - ' +
|
||||
period.range.end.format('MMM Do YY')}
|
||||
</div>
|
||||
</div>
|
||||
{dashboard && dashboard.description && (
|
||||
<div className="color-gray-medum whitespace-pre-wrap my-2">{dashboard.description}</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="report-layer"
|
||||
style={{
|
||||
position: 'fixed',
|
||||
top: '0',
|
||||
left: '0',
|
||||
zIndex: '-1',
|
||||
opacity: '0',
|
||||
}}
|
||||
></div>
|
||||
<WrappedComponent {...props} renderReport={renderPromise} rendering={rendering} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
return connect((state: any) => ({
|
||||
site: state.getIn(['site', 'instance']),
|
||||
}))(ComponentWithReport);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ export default class DashboardStore {
|
|||
drillDownPeriod: Record<string, any> = Period({ rangeName: LAST_7_DAYS });
|
||||
startTimestamp: number = 0;
|
||||
endTimestamp: number = 0;
|
||||
pendingReuqests: number = 0;
|
||||
|
||||
// Metrics
|
||||
metricsPage: number = 1;
|
||||
|
|
@ -421,6 +422,7 @@ export default class DashboardStore {
|
|||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pendingReuqests += 1
|
||||
return metricService
|
||||
.getMetricChartData(metric, params, isWidget)
|
||||
.then((data: any) => {
|
||||
|
|
@ -498,6 +500,10 @@ export default class DashboardStore {
|
|||
})
|
||||
.catch((err: any) => {
|
||||
reject(err);
|
||||
}).finally(() => {
|
||||
setTimeout(() => {
|
||||
this.pendingReuqests = this.pendingReuqests - 1
|
||||
}, 100)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -269,9 +269,9 @@ export const positionOfTheNumber = (min, max, value, length) => {
|
|||
return position;
|
||||
};
|
||||
|
||||
export const convertElementToImage = async (el) => {
|
||||
export const convertElementToImage = async (el: HTMLElement) => {
|
||||
// const fontEmbedCss = await htmlToImage.getFontEmbedCSS(el);
|
||||
const image = await htmlToImage.toPng(el, {
|
||||
const image = await htmlToImage.toJpeg(el, {
|
||||
pixelRatio: 2,
|
||||
// fontEmbedCss,
|
||||
filter: function (node) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue