From df24d0004865a3232318cefb93ce0a786c4be43a Mon Sep 17 00:00:00 2001 From: Kheir Eddine Farfar Date: Mon, 3 Apr 2023 17:31:17 +0200 Subject: [PATCH] fix(Comparison): fix export comparison as PDF --- package-lock.json | 116 +++++++++--------- package.json | 2 +- .../Comparison/Export/GeneratePdf.js | 19 +-- src/components/Comparison/Table/Rows/Row.js | 2 +- src/components/Comparison/Table/Rows/Rows.js | 7 +- src/components/Comparison/styled.js | 4 +- .../ContributionEditor/EditorTable.js | 2 +- 7 files changed, 74 insertions(+), 78 deletions(-) diff --git a/package-lock.json b/package-lock.json index eba47cdee..8558d2720 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,6 @@ "@jonkoops/matomo-tracker-react": "^0.7.0", "@reduxjs/toolkit": "^1.9.0", "@tippyjs/react": "^4.2.6", - "@trainiac/html2canvas": "^1.0.0", "@webscopeio/react-textarea-autocomplete": "^4.9.2", "@xobotyi/scrollbar-width": "^1.9.5", "array-move": "^3.0.1", @@ -36,6 +35,7 @@ "greeting-time": "^1.0.0", "handsontable": "^11.0.1", "he": "^1.2.0", + "html2canvas": "^1.4.1", "immutability-helper": "^3.0.2", "indefinite": "^2.4.2", "intro.js": "^6.0.0", @@ -4131,29 +4131,6 @@ "node": ">= 6" } }, - "node_modules/@trainiac/html2canvas": { - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "css-line-break": "1.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@trainiac/html2canvas/node_modules/base64-arraybuffer": { - "version": "0.2.0", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/@trainiac/html2canvas/node_modules/css-line-break": { - "version": "1.1.1", - "license": "MIT", - "dependencies": { - "base64-arraybuffer": "^0.2.0" - } - }, "node_modules/@trysound/sax": { "version": "0.2.0", "dev": true, @@ -6107,8 +6084,9 @@ "license": "MIT" }, "node_modules/base64-arraybuffer": { - "version": "0.2.0", - "optional": true, + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", "engines": { "node": ">= 0.6.0" } @@ -7326,11 +7304,11 @@ } }, "node_modules/css-line-break": { - "version": "1.1.1", - "license": "MIT", - "optional": true, + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz", + "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", "dependencies": { - "base64-arraybuffer": "^0.2.0" + "utrie": "^1.0.2" } }, "node_modules/css-loader": { @@ -10456,11 +10434,12 @@ } }, "node_modules/html2canvas": { - "version": "1.0.0-rc.7", - "license": "MIT", - "optional": true, + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz", + "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==", "dependencies": { - "css-line-break": "1.1.1" + "css-line-break": "^2.1.0", + "text-segmentation": "^1.0.3" }, "engines": { "node": ">=8.0.0" @@ -19828,6 +19807,14 @@ "node": ">=8" } }, + "node_modules/text-segmentation": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", + "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", + "dependencies": { + "utrie": "^1.0.2" + } + }, "node_modules/text-table": { "version": "0.2.0", "dev": true, @@ -20340,6 +20327,14 @@ "node": ">= 0.4.0" } }, + "node_modules/utrie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz", + "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", + "dependencies": { + "base64-arraybuffer": "^1.0.2" + } + }, "node_modules/uuid": { "version": "8.3.2", "dev": true, @@ -24041,23 +24036,6 @@ "version": "1.1.2", "dev": true }, - "@trainiac/html2canvas": { - "version": "1.0.0", - "requires": { - "css-line-break": "1.1.1" - }, - "dependencies": { - "base64-arraybuffer": { - "version": "0.2.0" - }, - "css-line-break": { - "version": "1.1.1", - "requires": { - "base64-arraybuffer": "^0.2.0" - } - } - } - }, "@trysound/sax": { "version": "0.2.0", "dev": true @@ -25497,8 +25475,9 @@ "version": "1.0.0" }, "base64-arraybuffer": { - "version": "0.2.0", - "optional": true + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==" }, "base64-js": { "version": "1.5.1" @@ -26245,10 +26224,11 @@ } }, "css-line-break": { - "version": "1.1.1", - "optional": true, + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz", + "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", "requires": { - "base64-arraybuffer": "^0.2.0" + "utrie": "^1.0.2" } }, "css-loader": { @@ -28289,10 +28269,12 @@ } }, "html2canvas": { - "version": "1.0.0-rc.7", - "optional": true, + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz", + "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==", "requires": { - "css-line-break": "1.1.1" + "css-line-break": "^2.1.0", + "text-segmentation": "^1.0.3" } }, "htmlparser2": { @@ -34389,6 +34371,14 @@ "minimatch": "^3.0.4" } }, + "text-segmentation": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", + "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", + "requires": { + "utrie": "^1.0.2" + } + }, "text-table": { "version": "0.2.0", "dev": true @@ -34711,6 +34701,14 @@ "version": "1.0.1", "dev": true }, + "utrie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz", + "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", + "requires": { + "base64-arraybuffer": "^1.0.2" + } + }, "uuid": { "version": "8.3.2", "dev": true diff --git a/package.json b/package.json index bc6dd65f8..4d35da387 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,6 @@ "@jonkoops/matomo-tracker-react": "^0.7.0", "@reduxjs/toolkit": "^1.9.0", "@tippyjs/react": "^4.2.6", - "@trainiac/html2canvas": "^1.0.0", "@webscopeio/react-textarea-autocomplete": "^4.9.2", "@xobotyi/scrollbar-width": "^1.9.5", "array-move": "^3.0.1", @@ -32,6 +31,7 @@ "greeting-time": "^1.0.0", "handsontable": "^11.0.1", "he": "^1.2.0", + "html2canvas": "^1.4.1", "immutability-helper": "^3.0.2", "indefinite": "^2.4.2", "intro.js": "^6.0.0", diff --git a/src/components/Comparison/Export/GeneratePdf.js b/src/components/Comparison/Export/GeneratePdf.js index bedaf3167..a362a9950 100644 --- a/src/components/Comparison/Export/GeneratePdf.js +++ b/src/components/Comparison/Export/GeneratePdf.js @@ -1,5 +1,6 @@ -import html2canvas from '@trainiac/html2canvas'; +import html2canvas from 'html2canvas'; import { DropdownItem } from 'reactstrap'; +import { sumBy } from 'lodash'; import PropTypes from 'prop-types'; // FIXME: svg icons look ugly while exporting, so hide them before generating the PDF @@ -10,8 +11,8 @@ const GeneratePdf = props => { const header = document.getElementById(props.id).getElementsByClassName('header')[0]; const headerHeightMm = header.offsetHeight; const headerWidthMm = header.offsetWidth; - let body = document.getElementById(props.id).getElementsByClassName('comparisonBody')[0]; - const bodyHeightMm = body.offsetHeight; + const allRows = Array.from(document.getElementById(props.id).getElementsByClassName('comparisonRow')); + const bodyHeightMm = sumBy(allRows, 'offsetHeight'); // Header const canvasHeader = await html2canvas(header); @@ -27,11 +28,13 @@ const GeneratePdf = props => { pdf.addImage(imgData, 'PNG', 5, 5); // Body - // There is issue (Unable to find element in cloned iframe) if we don't select the body again! - body = document.getElementById(props.id).getElementsByClassName('comparisonBody')[0]; - const canvas = await html2canvas(body); - const imgData2 = canvas.toDataURL('image/png'); - pdf.addImage(imgData2, 'PNG', 5, headerHeightMm + 5); + const promises = allRows.map(row => html2canvas(row)); + const allCanvasRows = await Promise.all(promises); + allCanvasRows.map((can, i) => { + const imgData2 = can.toDataURL('image/png'); + return pdf.addImage(imgData2, 'PNG', 5, headerHeightMm + sumBy(allRows.slice(0, i), 'offsetHeight')); + }); + pdf.save('ORKG Comparison exported.pdf'); }; diff --git a/src/components/Comparison/Table/Rows/Row.js b/src/components/Comparison/Table/Rows/Row.js index be1bf15c3..2b7819156 100644 --- a/src/components/Comparison/Table/Rows/Row.js +++ b/src/components/Comparison/Table/Rows/Row.js @@ -11,7 +11,7 @@ const Row = ({ row, index }) => { {providedDraggable => (
{ )} > {providedDroppable => ( -
+
{rows.map((row, index) => { prepareRow(row); return ; diff --git a/src/components/Comparison/styled.js b/src/components/Comparison/styled.js index 09f2d89db..8c86b1e8b 100644 --- a/src/components/Comparison/styled.js +++ b/src/components/Comparison/styled.js @@ -145,7 +145,7 @@ export const ReactTableWrapper = styled.div` } } - .comparisonBody .tr:last-child .td > div > div:first-child { + .comparisonRow .tr:last-child .td > div > div:first-child { // border-radius: 0 0 0 ${props => props.theme.borderRadius} !important; } @@ -158,7 +158,7 @@ export const ReactTableWrapper = styled.div` } } - .comparisonBody { + .comparisonRow { position: relative; z-index: 0; } diff --git a/src/components/ContributionEditor/EditorTable.js b/src/components/ContributionEditor/EditorTable.js index 2c207a5d7..8b681842c 100644 --- a/src/components/ContributionEditor/EditorTable.js +++ b/src/components/ContributionEditor/EditorTable.js @@ -58,7 +58,7 @@ const EditorTable = ({ scrollContainerBody }) => { {/* paddingBottom for the 'add value' bottom, which is positioned partially below the table */}
-
+
{rows.map(row => { prepareRow(row);