refactor(Dashboard): Fetch dashboard screenshot via dedicated endpoint (#29272)
This commit is contained in:
parent
6dbfe2aab9
commit
1e412a8711
|
|
@ -16,7 +16,6 @@
|
||||||
specific language governing permissions and limitations
|
specific language governing permissions and limitations
|
||||||
under the License.
|
under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
# CODE OF CONDUCT
|
# CODE OF CONDUCT
|
||||||
|
|
||||||
*The following is copied for your convenience from <https://www.apache.org/foundation/policies/conduct.html>. If there's a discrepancy between the two, let us know or submit a PR to fix it.*
|
*The following is copied for your convenience from <https://www.apache.org/foundation/policies/conduct.html>. If there's a discrepancy between the two, let us know or submit a PR to fix it.*
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,6 @@
|
||||||
"core-js": "^3.37.1",
|
"core-js": "^3.37.1",
|
||||||
"d3-scale": "^2.1.2",
|
"d3-scale": "^2.1.2",
|
||||||
"dom-to-image-more": "^3.2.0",
|
"dom-to-image-more": "^3.2.0",
|
||||||
"dom-to-pdf": "^0.3.1",
|
|
||||||
"emotion-rgba": "0.0.12",
|
"emotion-rgba": "0.0.12",
|
||||||
"fast-glob": "^3.2.7",
|
"fast-glob": "^3.2.7",
|
||||||
"fs-extra": "^10.0.0",
|
"fs-extra": "^10.0.0",
|
||||||
|
|
@ -16065,11 +16064,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
|
||||||
"integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw=="
|
"integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/raf": {
|
|
||||||
"version": "3.4.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/raf/-/raf-3.4.2.tgz",
|
|
||||||
"integrity": "sha512-sM4HyDVlDFl4goOXPF+g9nNHJFZQGot+HgySjM4cRjqXzjdatcEvYrtG4Ia8XumR9T6k8G2tW9B7hnUj51Uf0A=="
|
|
||||||
},
|
|
||||||
"node_modules/@types/range-parser": {
|
"node_modules/@types/range-parser": {
|
||||||
"version": "1.2.4",
|
"version": "1.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz",
|
||||||
|
|
@ -19800,6 +19794,7 @@
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
|
||||||
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
|
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
|
||||||
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"atob": "bin/atob.js"
|
"atob": "bin/atob.js"
|
||||||
},
|
},
|
||||||
|
|
@ -20651,14 +20646,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/base16/-/base16-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/base16/-/base16-1.0.0.tgz",
|
||||||
"integrity": "sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ=="
|
"integrity": "sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ=="
|
||||||
},
|
},
|
||||||
"node_modules/base64-arraybuffer": {
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/base64-js": {
|
"node_modules/base64-js": {
|
||||||
"version": "1.5.1",
|
"version": "1.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||||
|
|
@ -21093,17 +21080,6 @@
|
||||||
"node-int64": "^0.4.0"
|
"node-int64": "^0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/btoa": {
|
|
||||||
"version": "1.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz",
|
|
||||||
"integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==",
|
|
||||||
"bin": {
|
|
||||||
"btoa": "bin/btoa.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.4.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/buf-compare": {
|
"node_modules/buf-compare": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/buf-compare/-/buf-compare-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/buf-compare/-/buf-compare-1.0.1.tgz",
|
||||||
|
|
@ -21663,29 +21639,6 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/canvg": {
|
|
||||||
"version": "3.0.10",
|
|
||||||
"resolved": "https://registry.npmjs.org/canvg/-/canvg-3.0.10.tgz",
|
|
||||||
"integrity": "sha512-qwR2FRNO9NlzTeKIPIKpnTY6fqwuYSequ8Ru8c0YkYU7U0oW+hLUvWadLvAu1Rl72OMNiFhoLu4f8eUjQ7l/+Q==",
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/runtime": "^7.12.5",
|
|
||||||
"@types/raf": "^3.4.0",
|
|
||||||
"core-js": "^3.8.3",
|
|
||||||
"raf": "^3.4.1",
|
|
||||||
"regenerator-runtime": "^0.13.7",
|
|
||||||
"rgbcolor": "^1.0.1",
|
|
||||||
"stackblur-canvas": "^2.0.0",
|
|
||||||
"svg-pathdata": "^6.0.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/canvg/node_modules/regenerator-runtime": {
|
|
||||||
"version": "0.13.11",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
|
|
||||||
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
|
|
||||||
},
|
|
||||||
"node_modules/capture-exit": {
|
"node_modules/capture-exit": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz",
|
||||||
|
|
@ -23523,14 +23476,6 @@
|
||||||
"isobject": "^3.0.1"
|
"isobject": "^3.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/css-line-break": {
|
|
||||||
"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": {
|
|
||||||
"utrie": "^1.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/css-loader": {
|
"node_modules/css-loader": {
|
||||||
"version": "6.8.1",
|
"version": "6.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.8.1.tgz",
|
||||||
|
|
@ -25652,25 +25597,11 @@
|
||||||
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
|
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/dom-to-image": {
|
|
||||||
"version": "2.6.0",
|
|
||||||
"resolved": "git+ssh://git@github.com/dmapper/dom-to-image.git#a7c386a8ea813930f05449ac71ab4be0c262dff3",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/dom-to-image-more": {
|
"node_modules/dom-to-image-more": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/dom-to-image-more/-/dom-to-image-more-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/dom-to-image-more/-/dom-to-image-more-3.2.0.tgz",
|
||||||
"integrity": "sha512-2bGQTB6m17MBseVhIjShwZqqqCyVS9GgTykWqvVXMqr56fSgHhXnEvZfZkaSuHJYW3ICZQ3sZwAu+UY5tfsF9Q=="
|
"integrity": "sha512-2bGQTB6m17MBseVhIjShwZqqqCyVS9GgTykWqvVXMqr56fSgHhXnEvZfZkaSuHJYW3ICZQ3sZwAu+UY5tfsF9Q=="
|
||||||
},
|
},
|
||||||
"node_modules/dom-to-pdf": {
|
|
||||||
"version": "0.3.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/dom-to-pdf/-/dom-to-pdf-0.3.2.tgz",
|
|
||||||
"integrity": "sha512-eHLQ/IK+2PQlRjybQ9UHYwpiTd/YZFKqGFyRCjVvi6CPlH58drWQnxf7HBCVRUyAjOtI3RG0kvLidPhC7dOhcQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"dom-to-image": "git+https://github.com/dmapper/dom-to-image.git",
|
|
||||||
"jspdf": "^2.5.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/dom-walk": {
|
"node_modules/dom-walk": {
|
||||||
"version": "0.1.1",
|
"version": "0.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz",
|
||||||
|
|
@ -25701,12 +25632,6 @@
|
||||||
"url": "https://github.com/fb55/domhandler?sponsor=1"
|
"url": "https://github.com/fb55/domhandler?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/dompurify": {
|
|
||||||
"version": "2.3.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.3.tgz",
|
|
||||||
"integrity": "sha512-dqnqRkPMAjOZE0FogZ+ceJNM2dZ3V/yNOuFB7+39qpO93hHhfRpHw3heYQC7DPK9FqbQTfBKUJhiSfz4MvXYwg==",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"node_modules/domutils": {
|
"node_modules/domutils": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
|
||||||
|
|
@ -28672,11 +28597,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/fetch-retry/-/fetch-retry-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/fetch-retry/-/fetch-retry-6.0.0.tgz",
|
||||||
"integrity": "sha512-BUFj1aMubgib37I3v4q78fYo63Po7t4HUPTpQ6/QE6yK6cIQrP+W43FYToeTEyg5m2Y7eFUtijUuAv/PDlWuag=="
|
"integrity": "sha512-BUFj1aMubgib37I3v4q78fYo63Po7t4HUPTpQ6/QE6yK6cIQrP+W43FYToeTEyg5m2Y7eFUtijUuAv/PDlWuag=="
|
||||||
},
|
},
|
||||||
"node_modules/fflate": {
|
|
||||||
"version": "0.4.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.4.8.tgz",
|
|
||||||
"integrity": "sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA=="
|
|
||||||
},
|
|
||||||
"node_modules/figures": {
|
"node_modules/figures": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
|
||||||
|
|
@ -32618,18 +32538,6 @@
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/html2canvas": {
|
|
||||||
"version": "1.4.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz",
|
|
||||||
"integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
|
|
||||||
"dependencies": {
|
|
||||||
"css-line-break": "^2.1.0",
|
|
||||||
"text-segmentation": "^1.0.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/htmlparser2": {
|
"node_modules/htmlparser2": {
|
||||||
"version": "8.0.2",
|
"version": "8.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
|
||||||
|
|
@ -39492,23 +39400,6 @@
|
||||||
"node": "*"
|
"node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/jspdf": {
|
|
||||||
"version": "2.5.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/jspdf/-/jspdf-2.5.1.tgz",
|
|
||||||
"integrity": "sha512-hXObxz7ZqoyhxET78+XR34Xu2qFGrJJ2I2bE5w4SM8eFaFEkW2xcGRVUss360fYelwRSid/jT078kbNvmoW0QA==",
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/runtime": "^7.14.0",
|
|
||||||
"atob": "^2.1.2",
|
|
||||||
"btoa": "^1.2.1",
|
|
||||||
"canvg": "^3.0.6",
|
|
||||||
"fflate": "^0.4.8",
|
|
||||||
"html2canvas": "^1.0.0-rc.5"
|
|
||||||
},
|
|
||||||
"optionalDependencies": {
|
|
||||||
"core-js": "^3.6.0",
|
|
||||||
"dompurify": "^2.2.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/jsprim": {
|
"node_modules/jsprim": {
|
||||||
"version": "1.4.2",
|
"version": "1.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
|
||||||
|
|
@ -56514,14 +56405,6 @@
|
||||||
"integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==",
|
"integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/rgbcolor": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.8.15"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/rimraf": {
|
"node_modules/rimraf": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||||
|
|
@ -58073,14 +57956,6 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/stackblur-canvas": {
|
|
||||||
"version": "2.6.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.6.0.tgz",
|
|
||||||
"integrity": "sha512-8S1aIA+UoF6erJYnglGPug6MaHYGo1Ot7h5fuXx4fUPvcvQfcdw2o/ppCse63+eZf8PPidSu4v1JnmEVtEDnpg==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.1.14"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/static-eval": {
|
"node_modules/static-eval": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.1.0.tgz",
|
||||||
|
|
@ -58744,14 +58619,6 @@
|
||||||
"integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==",
|
"integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/svg-pathdata": {
|
|
||||||
"version": "6.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-6.0.3.tgz",
|
|
||||||
"integrity": "sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/svgo": {
|
"node_modules/svgo": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/svgo/-/svgo-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/svgo/-/svgo-3.2.0.tgz",
|
||||||
|
|
@ -59189,14 +59056,6 @@
|
||||||
"node": ">=0.10"
|
"node": ">=0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"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": {
|
"node_modules/text-table": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||||
|
|
@ -60627,14 +60486,6 @@
|
||||||
"node": ">= 0.4.0"
|
"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": {
|
"node_modules/uuid": {
|
||||||
"version": "3.4.0",
|
"version": "3.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||||
|
|
@ -81093,11 +80944,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
|
||||||
"integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw=="
|
"integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw=="
|
||||||
},
|
},
|
||||||
"@types/raf": {
|
|
||||||
"version": "3.4.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/raf/-/raf-3.4.2.tgz",
|
|
||||||
"integrity": "sha512-sM4HyDVlDFl4goOXPF+g9nNHJFZQGot+HgySjM4cRjqXzjdatcEvYrtG4Ia8XumR9T6k8G2tW9B7hnUj51Uf0A=="
|
|
||||||
},
|
|
||||||
"@types/range-parser": {
|
"@types/range-parser": {
|
||||||
"version": "1.2.4",
|
"version": "1.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz",
|
||||||
|
|
@ -84053,7 +83899,8 @@
|
||||||
"atob": {
|
"atob": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
|
||||||
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
|
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"atomic-sleep": {
|
"atomic-sleep": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
|
|
@ -84715,11 +84562,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/base16/-/base16-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/base16/-/base16-1.0.0.tgz",
|
||||||
"integrity": "sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ=="
|
"integrity": "sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ=="
|
||||||
},
|
},
|
||||||
"base64-arraybuffer": {
|
|
||||||
"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": {
|
"base64-js": {
|
||||||
"version": "1.5.1",
|
"version": "1.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||||
|
|
@ -85058,11 +84900,6 @@
|
||||||
"node-int64": "^0.4.0"
|
"node-int64": "^0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"btoa": {
|
|
||||||
"version": "1.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz",
|
|
||||||
"integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g=="
|
|
||||||
},
|
|
||||||
"buf-compare": {
|
"buf-compare": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/buf-compare/-/buf-compare-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/buf-compare/-/buf-compare-1.0.1.tgz",
|
||||||
|
|
@ -85446,28 +85283,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001639.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001639.tgz",
|
||||||
"integrity": "sha512-eFHflNTBIlFwP2AIKaYuBQN/apnUoKNhBdza8ZnW/h2di4LCZ4xFqYlxUxo+LQ76KFI1PGcC1QDxMbxTZpSCAg=="
|
"integrity": "sha512-eFHflNTBIlFwP2AIKaYuBQN/apnUoKNhBdza8ZnW/h2di4LCZ4xFqYlxUxo+LQ76KFI1PGcC1QDxMbxTZpSCAg=="
|
||||||
},
|
},
|
||||||
"canvg": {
|
|
||||||
"version": "3.0.10",
|
|
||||||
"resolved": "https://registry.npmjs.org/canvg/-/canvg-3.0.10.tgz",
|
|
||||||
"integrity": "sha512-qwR2FRNO9NlzTeKIPIKpnTY6fqwuYSequ8Ru8c0YkYU7U0oW+hLUvWadLvAu1Rl72OMNiFhoLu4f8eUjQ7l/+Q==",
|
|
||||||
"requires": {
|
|
||||||
"@babel/runtime": "^7.12.5",
|
|
||||||
"@types/raf": "^3.4.0",
|
|
||||||
"core-js": "^3.8.3",
|
|
||||||
"raf": "^3.4.1",
|
|
||||||
"regenerator-runtime": "^0.13.7",
|
|
||||||
"rgbcolor": "^1.0.1",
|
|
||||||
"stackblur-canvas": "^2.0.0",
|
|
||||||
"svg-pathdata": "^6.0.3"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"regenerator-runtime": {
|
|
||||||
"version": "0.13.11",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
|
|
||||||
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"capture-exit": {
|
"capture-exit": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz",
|
||||||
|
|
@ -86877,14 +86692,6 @@
|
||||||
"isobject": "^3.0.1"
|
"isobject": "^3.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"css-line-break": {
|
|
||||||
"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": {
|
|
||||||
"utrie": "^1.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"css-loader": {
|
"css-loader": {
|
||||||
"version": "6.8.1",
|
"version": "6.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.8.1.tgz",
|
||||||
|
|
@ -88526,24 +88333,11 @@
|
||||||
"entities": "^4.2.0"
|
"entities": "^4.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dom-to-image": {
|
|
||||||
"version": "git+ssh://git@github.com/dmapper/dom-to-image.git#a7c386a8ea813930f05449ac71ab4be0c262dff3",
|
|
||||||
"from": "dom-to-image@git+https://github.com/dmapper/dom-to-image.git"
|
|
||||||
},
|
|
||||||
"dom-to-image-more": {
|
"dom-to-image-more": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/dom-to-image-more/-/dom-to-image-more-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/dom-to-image-more/-/dom-to-image-more-3.2.0.tgz",
|
||||||
"integrity": "sha512-2bGQTB6m17MBseVhIjShwZqqqCyVS9GgTykWqvVXMqr56fSgHhXnEvZfZkaSuHJYW3ICZQ3sZwAu+UY5tfsF9Q=="
|
"integrity": "sha512-2bGQTB6m17MBseVhIjShwZqqqCyVS9GgTykWqvVXMqr56fSgHhXnEvZfZkaSuHJYW3ICZQ3sZwAu+UY5tfsF9Q=="
|
||||||
},
|
},
|
||||||
"dom-to-pdf": {
|
|
||||||
"version": "0.3.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/dom-to-pdf/-/dom-to-pdf-0.3.2.tgz",
|
|
||||||
"integrity": "sha512-eHLQ/IK+2PQlRjybQ9UHYwpiTd/YZFKqGFyRCjVvi6CPlH58drWQnxf7HBCVRUyAjOtI3RG0kvLidPhC7dOhcQ==",
|
|
||||||
"requires": {
|
|
||||||
"dom-to-image": "git+https://github.com/dmapper/dom-to-image.git",
|
|
||||||
"jspdf": "^2.5.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dom-walk": {
|
"dom-walk": {
|
||||||
"version": "0.1.1",
|
"version": "0.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz",
|
||||||
|
|
@ -88562,12 +88356,6 @@
|
||||||
"domelementtype": "^2.3.0"
|
"domelementtype": "^2.3.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dompurify": {
|
|
||||||
"version": "2.3.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.3.tgz",
|
|
||||||
"integrity": "sha512-dqnqRkPMAjOZE0FogZ+ceJNM2dZ3V/yNOuFB7+39qpO93hHhfRpHw3heYQC7DPK9FqbQTfBKUJhiSfz4MvXYwg==",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"domutils": {
|
"domutils": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
|
||||||
|
|
@ -90854,11 +90642,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/fetch-retry/-/fetch-retry-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/fetch-retry/-/fetch-retry-6.0.0.tgz",
|
||||||
"integrity": "sha512-BUFj1aMubgib37I3v4q78fYo63Po7t4HUPTpQ6/QE6yK6cIQrP+W43FYToeTEyg5m2Y7eFUtijUuAv/PDlWuag=="
|
"integrity": "sha512-BUFj1aMubgib37I3v4q78fYo63Po7t4HUPTpQ6/QE6yK6cIQrP+W43FYToeTEyg5m2Y7eFUtijUuAv/PDlWuag=="
|
||||||
},
|
},
|
||||||
"fflate": {
|
|
||||||
"version": "0.4.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.4.8.tgz",
|
|
||||||
"integrity": "sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA=="
|
|
||||||
},
|
|
||||||
"figures": {
|
"figures": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
|
||||||
|
|
@ -93759,15 +93542,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"html2canvas": {
|
|
||||||
"version": "1.4.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz",
|
|
||||||
"integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
|
|
||||||
"requires": {
|
|
||||||
"css-line-break": "^2.1.0",
|
|
||||||
"text-segmentation": "^1.0.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"htmlparser2": {
|
"htmlparser2": {
|
||||||
"version": "8.0.2",
|
"version": "8.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
|
||||||
|
|
@ -98769,21 +98543,6 @@
|
||||||
"through": ">=2.2.7 <3"
|
"through": ">=2.2.7 <3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jspdf": {
|
|
||||||
"version": "2.5.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/jspdf/-/jspdf-2.5.1.tgz",
|
|
||||||
"integrity": "sha512-hXObxz7ZqoyhxET78+XR34Xu2qFGrJJ2I2bE5w4SM8eFaFEkW2xcGRVUss360fYelwRSid/jT078kbNvmoW0QA==",
|
|
||||||
"requires": {
|
|
||||||
"@babel/runtime": "^7.14.0",
|
|
||||||
"atob": "^2.1.2",
|
|
||||||
"btoa": "^1.2.1",
|
|
||||||
"canvg": "^3.0.6",
|
|
||||||
"core-js": "^3.6.0",
|
|
||||||
"dompurify": "^2.2.0",
|
|
||||||
"fflate": "^0.4.8",
|
|
||||||
"html2canvas": "^1.0.0-rc.5"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"jsprim": {
|
"jsprim": {
|
||||||
"version": "1.4.2",
|
"version": "1.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
|
||||||
|
|
@ -110459,11 +110218,6 @@
|
||||||
"integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==",
|
"integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"rgbcolor": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw=="
|
|
||||||
},
|
|
||||||
"rimraf": {
|
"rimraf": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||||
|
|
@ -111693,11 +111447,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"stackblur-canvas": {
|
|
||||||
"version": "2.6.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.6.0.tgz",
|
|
||||||
"integrity": "sha512-8S1aIA+UoF6erJYnglGPug6MaHYGo1Ot7h5fuXx4fUPvcvQfcdw2o/ppCse63+eZf8PPidSu4v1JnmEVtEDnpg=="
|
|
||||||
},
|
|
||||||
"static-eval": {
|
"static-eval": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.1.0.tgz",
|
||||||
|
|
@ -112189,11 +111938,6 @@
|
||||||
"integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==",
|
"integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"svg-pathdata": {
|
|
||||||
"version": "6.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-6.0.3.tgz",
|
|
||||||
"integrity": "sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw=="
|
|
||||||
},
|
|
||||||
"svgo": {
|
"svgo": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/svgo/-/svgo-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/svgo/-/svgo-3.2.0.tgz",
|
||||||
|
|
@ -112515,14 +112259,6 @@
|
||||||
"integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==",
|
"integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"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": {
|
"text-table": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||||
|
|
@ -113569,14 +113305,6 @@
|
||||||
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
|
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
|
||||||
"dev": true
|
"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": {
|
"uuid": {
|
||||||
"version": "3.4.0",
|
"version": "3.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,6 @@
|
||||||
"core-js": "^3.37.1",
|
"core-js": "^3.37.1",
|
||||||
"d3-scale": "^2.1.2",
|
"d3-scale": "^2.1.2",
|
||||||
"dom-to-image-more": "^3.2.0",
|
"dom-to-image-more": "^3.2.0",
|
||||||
"dom-to-pdf": "^0.3.1",
|
|
||||||
"emotion-rgba": "0.0.12",
|
"emotion-rgba": "0.0.12",
|
||||||
"fast-glob": "^3.2.7",
|
"fast-glob": "^3.2.7",
|
||||||
"fs-extra": "^10.0.0",
|
"fs-extra": "^10.0.0",
|
||||||
|
|
|
||||||
|
|
@ -276,7 +276,7 @@ export class HeaderActionsDropdown extends PureComponent {
|
||||||
pdfMenuItemTitle={t('Export to PDF')}
|
pdfMenuItemTitle={t('Export to PDF')}
|
||||||
imageMenuItemTitle={t('Download as Image')}
|
imageMenuItemTitle={t('Download as Image')}
|
||||||
dashboardTitle={dashboardTitle}
|
dashboardTitle={dashboardTitle}
|
||||||
addDangerToast={addDangerToast}
|
dashboardId={dashboardId}
|
||||||
/>
|
/>
|
||||||
</Menu.SubMenu>
|
</Menu.SubMenu>
|
||||||
{userCanShare && (
|
{userCanShare && (
|
||||||
|
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
import { SyntheticEvent } from 'react';
|
|
||||||
import { render, screen, waitFor } from 'spec/helpers/testing-library';
|
|
||||||
import userEvent from '@testing-library/user-event';
|
|
||||||
import { Menu } from 'src/components/Menu';
|
|
||||||
import downloadAsPdf from 'src/utils/downloadAsPdf';
|
|
||||||
import DownloadAsPdf from './DownloadAsPdf';
|
|
||||||
|
|
||||||
jest.mock('src/utils/downloadAsPdf', () => ({
|
|
||||||
__esModule: true,
|
|
||||||
default: jest.fn(() => (_e: SyntheticEvent) => {}),
|
|
||||||
}));
|
|
||||||
|
|
||||||
const createProps = () => ({
|
|
||||||
addDangerToast: jest.fn(),
|
|
||||||
text: 'Export as PDF',
|
|
||||||
dashboardTitle: 'Test Dashboard',
|
|
||||||
logEvent: jest.fn(),
|
|
||||||
});
|
|
||||||
|
|
||||||
const renderComponent = () => {
|
|
||||||
render(
|
|
||||||
<Menu>
|
|
||||||
<DownloadAsPdf {...createProps()} />
|
|
||||||
</Menu>,
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
test('Should call download pdf on click', async () => {
|
|
||||||
const props = createProps();
|
|
||||||
renderComponent();
|
|
||||||
await waitFor(() => {
|
|
||||||
expect(downloadAsPdf).toBeCalledTimes(0);
|
|
||||||
expect(props.addDangerToast).toBeCalledTimes(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('button', { name: 'Export as PDF' }));
|
|
||||||
|
|
||||||
await waitFor(() => {
|
|
||||||
expect(downloadAsPdf).toBeCalledTimes(1);
|
|
||||||
expect(props.addDangerToast).toBeCalledTimes(0);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Component is rendered with role="button"', async () => {
|
|
||||||
renderComponent();
|
|
||||||
const button = screen.getByRole('button', { name: 'Export as PDF' });
|
|
||||||
expect(button).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
import { SyntheticEvent } from 'react';
|
|
||||||
import { logging, t } from '@superset-ui/core';
|
|
||||||
import { Menu } from 'src/components/Menu';
|
|
||||||
import downloadAsPdf from 'src/utils/downloadAsPdf';
|
|
||||||
import { LOG_ACTIONS_DASHBOARD_DOWNLOAD_AS_PDF } from 'src/logger/LogUtils';
|
|
||||||
|
|
||||||
export default function DownloadAsPdf({
|
|
||||||
text,
|
|
||||||
logEvent,
|
|
||||||
dashboardTitle,
|
|
||||||
addDangerToast,
|
|
||||||
...rest
|
|
||||||
}: {
|
|
||||||
text: string;
|
|
||||||
addDangerToast: Function;
|
|
||||||
dashboardTitle: string;
|
|
||||||
logEvent?: Function;
|
|
||||||
}) {
|
|
||||||
const SCREENSHOT_NODE_SELECTOR = '.dashboard';
|
|
||||||
const onDownloadPdf = async (e: SyntheticEvent) => {
|
|
||||||
try {
|
|
||||||
downloadAsPdf(SCREENSHOT_NODE_SELECTOR, dashboardTitle, true)(e);
|
|
||||||
} catch (error) {
|
|
||||||
logging.error(error);
|
|
||||||
addDangerToast(t('Sorry, something went wrong. Try again later.'));
|
|
||||||
}
|
|
||||||
logEvent?.(LOG_ACTIONS_DASHBOARD_DOWNLOAD_AS_PDF);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Menu.Item key="download-pdf" {...rest}>
|
|
||||||
<div onClick={onDownloadPdf} role="button" tabIndex={0}>
|
|
||||||
{text}
|
|
||||||
</div>
|
|
||||||
</Menu.Item>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -20,15 +20,17 @@ import { render, screen } from 'spec/helpers/testing-library';
|
||||||
import DownloadMenuItems from '.';
|
import DownloadMenuItems from '.';
|
||||||
|
|
||||||
const createProps = () => ({
|
const createProps = () => ({
|
||||||
addDangerToast: jest.fn(),
|
|
||||||
pdfMenuItemTitle: 'Export to PDF',
|
pdfMenuItemTitle: 'Export to PDF',
|
||||||
imageMenuItemTitle: 'Download as Image',
|
imageMenuItemTitle: 'Download as Image',
|
||||||
dashboardTitle: 'Test Dashboard',
|
dashboardTitle: 'Test Dashboard',
|
||||||
logEvent: jest.fn(),
|
logEvent: jest.fn(),
|
||||||
|
dashboardId: '123',
|
||||||
});
|
});
|
||||||
|
|
||||||
const renderComponent = () => {
|
const renderComponent = () => {
|
||||||
render(<DownloadMenuItems {...createProps()} />);
|
render(<DownloadMenuItems {...createProps()} />, {
|
||||||
|
useRedux: true,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
test('Should render menu items', () => {
|
test('Should render menu items', () => {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,198 @@
|
||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { render, screen, waitFor } from 'spec/helpers/testing-library';
|
||||||
|
import userEvent from '@testing-library/user-event';
|
||||||
|
import { Menu } from 'src/components/Menu';
|
||||||
|
import fetchMock from 'fetch-mock';
|
||||||
|
import { logging } from '@superset-ui/core';
|
||||||
|
import { DownloadScreenshotFormat } from './types';
|
||||||
|
import DownloadScreenshot from './DownloadScreenshot';
|
||||||
|
|
||||||
|
const mockAddDangerToast = jest.fn();
|
||||||
|
const mockLogEvent = jest.fn();
|
||||||
|
const mockAddSuccessToast = jest.fn();
|
||||||
|
const mockAddInfoToast = jest.fn();
|
||||||
|
|
||||||
|
jest.spyOn(logging, 'error').mockImplementation(() => {});
|
||||||
|
|
||||||
|
jest.mock('src/components/MessageToasts/withToasts', () => ({
|
||||||
|
useToasts: () => ({
|
||||||
|
addDangerToast: mockAddDangerToast,
|
||||||
|
addSuccessToast: mockAddSuccessToast,
|
||||||
|
addInfoToast: mockAddInfoToast,
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const defaultProps = () => ({
|
||||||
|
text: 'Download',
|
||||||
|
dashboardId: '123',
|
||||||
|
format: DownloadScreenshotFormat.PDF,
|
||||||
|
logEvent: mockLogEvent,
|
||||||
|
});
|
||||||
|
|
||||||
|
const renderComponent = () => {
|
||||||
|
render(
|
||||||
|
<Menu>
|
||||||
|
<DownloadScreenshot {...defaultProps()} />
|
||||||
|
</Menu>,
|
||||||
|
{
|
||||||
|
useRedux: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('DownloadScreenshot component', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
jest.useRealTimers();
|
||||||
|
fetchMock.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
jest.restoreAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('renders correctly with the given text', () => {
|
||||||
|
renderComponent();
|
||||||
|
expect(screen.getByText('Download')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('button renders with role="button"', async () => {
|
||||||
|
renderComponent();
|
||||||
|
const button = screen.getByRole('button', { name: 'Download' });
|
||||||
|
expect(button).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('displays error message when API call fails', async () => {
|
||||||
|
const props = defaultProps();
|
||||||
|
|
||||||
|
fetchMock.post(
|
||||||
|
`glob:*/api/v1/dashboard/${props.dashboardId}/cache_dashboard_screenshot`,
|
||||||
|
{
|
||||||
|
status: 400,
|
||||||
|
body: {},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
renderComponent();
|
||||||
|
|
||||||
|
userEvent.click(screen.getByRole('button', { name: 'Download' }));
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(mockAddDangerToast).toHaveBeenCalledWith(
|
||||||
|
'The screenshot could not be downloaded. Please, try again later.',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('displays success message when API call succeeds', async () => {
|
||||||
|
const props = defaultProps();
|
||||||
|
fetchMock.post(
|
||||||
|
`glob:*/api/v1/dashboard/${props.dashboardId}/cache_dashboard_screenshot`,
|
||||||
|
{
|
||||||
|
status: 200,
|
||||||
|
body: {
|
||||||
|
image_url: 'mocked_image_url',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
fetchMock.get('glob:*/mocked_image_url?download_format=pdf', {
|
||||||
|
status: 200,
|
||||||
|
body: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
renderComponent();
|
||||||
|
|
||||||
|
userEvent.click(screen.getByRole('button', { name: 'Download' }));
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(mockAddInfoToast).toHaveBeenCalledWith(
|
||||||
|
'The screenshot is being generated. Please, do not leave the page.',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('throws error when no image URL is provided', async () => {
|
||||||
|
const props = defaultProps();
|
||||||
|
fetchMock.post(
|
||||||
|
`glob:*/api/v1/dashboard/${props.dashboardId}/cache_dashboard_screenshot`,
|
||||||
|
{
|
||||||
|
status: 200,
|
||||||
|
body: {
|
||||||
|
image_url: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
renderComponent();
|
||||||
|
|
||||||
|
// Simulate the user clicking the download button
|
||||||
|
userEvent.click(screen.getByRole('button', { name: 'Download' }));
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(mockAddDangerToast).toHaveBeenCalledWith(
|
||||||
|
'The screenshot could not be downloaded. Please, try again later.',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('displays success message when image retrieval succeeds', async () => {
|
||||||
|
const props = defaultProps();
|
||||||
|
const imageUrl = 'glob:*/mocked_image_url?download_format=pdf';
|
||||||
|
fetchMock.post(
|
||||||
|
`glob:*/api/v1/dashboard/${props.dashboardId}/cache_dashboard_screenshot`,
|
||||||
|
{
|
||||||
|
status: 200,
|
||||||
|
body: {
|
||||||
|
image_url: 'mocked_image_url',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
fetchMock.get(imageUrl, {
|
||||||
|
status: 200,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'image/png',
|
||||||
|
},
|
||||||
|
body: new Blob([], { type: 'image/png' }),
|
||||||
|
});
|
||||||
|
|
||||||
|
global.URL.createObjectURL = jest.fn(() => 'mockedObjectURL');
|
||||||
|
global.URL.revokeObjectURL = jest.fn();
|
||||||
|
|
||||||
|
// Render the component
|
||||||
|
renderComponent();
|
||||||
|
|
||||||
|
// Simulate the user clicking the download button
|
||||||
|
userEvent.click(screen.getByRole('button', { name: 'Download' }));
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(fetchMock.calls(imageUrl).length).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Wait for the successful image retrieval message
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(mockAddSuccessToast).toHaveBeenCalledWith(
|
||||||
|
'The screenshot is now being downloaded.',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,145 @@
|
||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { logging, t, SupersetClient } from '@superset-ui/core';
|
||||||
|
import { Menu } from 'src/components/Menu';
|
||||||
|
import {
|
||||||
|
LOG_ACTIONS_DASHBOARD_DOWNLOAD_AS_IMAGE,
|
||||||
|
LOG_ACTIONS_DASHBOARD_DOWNLOAD_AS_PDF,
|
||||||
|
} from 'src/logger/LogUtils';
|
||||||
|
import { RootState } from 'src/dashboard/types';
|
||||||
|
import { useSelector } from 'react-redux';
|
||||||
|
import { useToasts } from 'src/components/MessageToasts/withToasts';
|
||||||
|
import { last } from 'lodash';
|
||||||
|
import { DownloadScreenshotFormat } from './types';
|
||||||
|
|
||||||
|
const RETRY_INTERVAL = 3000;
|
||||||
|
const MAX_RETRIES = 30;
|
||||||
|
|
||||||
|
export default function DownloadScreenshot({
|
||||||
|
text,
|
||||||
|
logEvent,
|
||||||
|
dashboardId,
|
||||||
|
format,
|
||||||
|
...rest
|
||||||
|
}: {
|
||||||
|
text: string;
|
||||||
|
dashboardId: string;
|
||||||
|
logEvent?: Function;
|
||||||
|
format: string;
|
||||||
|
}) {
|
||||||
|
const anchor = useSelector(
|
||||||
|
(state: RootState) => last(state.dashboardState.activeTabs) || undefined,
|
||||||
|
);
|
||||||
|
const { addDangerToast, addSuccessToast, addInfoToast } = useToasts();
|
||||||
|
|
||||||
|
const onDownloadScreenshot = () => {
|
||||||
|
let retries = 0;
|
||||||
|
|
||||||
|
// this function checks if the image is ready
|
||||||
|
const checkImageReady = (imageUrl: string) =>
|
||||||
|
fetch(`${imageUrl}?download_format=${format}`)
|
||||||
|
.then(response => {
|
||||||
|
if (response.status === 404) {
|
||||||
|
throw new Error('Image not ready');
|
||||||
|
}
|
||||||
|
return response.blob();
|
||||||
|
})
|
||||||
|
.then(blob => {
|
||||||
|
const url = window.URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = `screenshot.${format}`;
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
document.body.removeChild(a);
|
||||||
|
window.URL.revokeObjectURL(url);
|
||||||
|
});
|
||||||
|
|
||||||
|
// this is the functions that handles the retries
|
||||||
|
const fetchImageWithRetry = (imageUrl: string) => {
|
||||||
|
checkImageReady(imageUrl)
|
||||||
|
.then(() => {
|
||||||
|
addSuccessToast(t('The screenshot is now being downloaded.'));
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
// we check how many retries have been made
|
||||||
|
if (retries < MAX_RETRIES) {
|
||||||
|
retries += 1;
|
||||||
|
addInfoToast(
|
||||||
|
t(
|
||||||
|
'The screenshot is being generated. Please, do not leave the page.',
|
||||||
|
),
|
||||||
|
{
|
||||||
|
noDuplicate: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
setTimeout(() => fetchImageWithRetry(imageUrl), RETRY_INTERVAL);
|
||||||
|
} else {
|
||||||
|
addDangerToast(
|
||||||
|
t(
|
||||||
|
'The screenshot could not be downloaded. Please, try again later.',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
logging.error(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
SupersetClient.post({
|
||||||
|
endpoint: `/api/v1/dashboard/${dashboardId}/cache_dashboard_screenshot`,
|
||||||
|
jsonPayload: {
|
||||||
|
anchor,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(({ json }) => {
|
||||||
|
const imageUrl = json?.image_url;
|
||||||
|
if (!imageUrl) {
|
||||||
|
throw new Error('No image URL in response');
|
||||||
|
}
|
||||||
|
addInfoToast(
|
||||||
|
t(
|
||||||
|
'The screenshot is being generated. Please, do not leave the page.',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
fetchImageWithRetry(imageUrl);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
logging.error(error);
|
||||||
|
addDangerToast(
|
||||||
|
t('The screenshot could not be downloaded. Please, try again later.'),
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
logEvent?.(
|
||||||
|
format === DownloadScreenshotFormat.PNG
|
||||||
|
? LOG_ACTIONS_DASHBOARD_DOWNLOAD_AS_IMAGE
|
||||||
|
: LOG_ACTIONS_DASHBOARD_DOWNLOAD_AS_PDF,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Menu.Item key={format} {...rest}>
|
||||||
|
<div onClick={onDownloadScreenshot} role="button" tabIndex={0}>
|
||||||
|
{text}
|
||||||
|
</div>
|
||||||
|
</Menu.Item>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -17,41 +17,40 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import { Menu } from 'src/components/Menu';
|
import { Menu } from 'src/components/Menu';
|
||||||
import DownloadAsImage from './DownloadAsImage';
|
import DownloadScreenshot from './DownloadScreenshot';
|
||||||
import DownloadAsPdf from './DownloadAsPdf';
|
import { DownloadScreenshotFormat } from './types';
|
||||||
|
|
||||||
export interface DownloadMenuItemProps {
|
export interface DownloadMenuItemProps {
|
||||||
pdfMenuItemTitle: string;
|
pdfMenuItemTitle: string;
|
||||||
imageMenuItemTitle: string;
|
imageMenuItemTitle: string;
|
||||||
addDangerToast: Function;
|
|
||||||
dashboardTitle: string;
|
dashboardTitle: string;
|
||||||
logEvent?: Function;
|
logEvent?: Function;
|
||||||
|
dashboardId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DownloadMenuItems = (props: DownloadMenuItemProps) => {
|
const DownloadMenuItems = (props: DownloadMenuItemProps) => {
|
||||||
const {
|
const {
|
||||||
pdfMenuItemTitle,
|
pdfMenuItemTitle,
|
||||||
imageMenuItemTitle,
|
imageMenuItemTitle,
|
||||||
addDangerToast,
|
|
||||||
dashboardTitle,
|
|
||||||
logEvent,
|
logEvent,
|
||||||
|
dashboardId,
|
||||||
...rest
|
...rest
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu selectable={false}>
|
<Menu selectable={false}>
|
||||||
<DownloadAsPdf
|
<DownloadScreenshot
|
||||||
text={pdfMenuItemTitle}
|
text={pdfMenuItemTitle}
|
||||||
addDangerToast={addDangerToast}
|
dashboardId={dashboardId}
|
||||||
dashboardTitle={dashboardTitle}
|
|
||||||
logEvent={logEvent}
|
logEvent={logEvent}
|
||||||
|
format={DownloadScreenshotFormat.PDF}
|
||||||
{...rest}
|
{...rest}
|
||||||
/>
|
/>
|
||||||
<DownloadAsImage
|
<DownloadScreenshot
|
||||||
text={imageMenuItemTitle}
|
text={imageMenuItemTitle}
|
||||||
addDangerToast={addDangerToast}
|
dashboardId={dashboardId}
|
||||||
dashboardTitle={dashboardTitle}
|
|
||||||
logEvent={logEvent}
|
logEvent={logEvent}
|
||||||
|
format={DownloadScreenshotFormat.PNG}
|
||||||
{...rest}
|
{...rest}
|
||||||
/>
|
/>
|
||||||
</Menu>
|
</Menu>
|
||||||
|
|
|
||||||
|
|
@ -16,21 +16,8 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
declare module 'dom-to-pdf' {
|
|
||||||
interface Image {
|
|
||||||
type: string;
|
|
||||||
quality: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Options {
|
export enum DownloadScreenshotFormat {
|
||||||
margin: number;
|
PDF = 'pdf',
|
||||||
filename: string;
|
PNG = 'png',
|
||||||
image: Image;
|
|
||||||
html2canvas: object;
|
|
||||||
excludeClassNames?: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
function domToPdf(elementToPrint: Element, options?: Options): Promise<any>;
|
|
||||||
|
|
||||||
export default domToPdf;
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,74 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
import { SyntheticEvent } from 'react';
|
|
||||||
import domToPdf from 'dom-to-pdf';
|
|
||||||
import { kebabCase } from 'lodash';
|
|
||||||
import { logging, t } from '@superset-ui/core';
|
|
||||||
import { addWarningToast } from 'src/components/MessageToasts/actions';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* generate a consistent file stem from a description and date
|
|
||||||
*
|
|
||||||
* @param description title or description of content of file
|
|
||||||
* @param date date when file was generated
|
|
||||||
*/
|
|
||||||
const generateFileStem = (description: string, date = new Date()) =>
|
|
||||||
`${kebabCase(description)}-${date.toISOString().replace(/[: ]/g, '-')}`;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an event handler for turning an element into an image
|
|
||||||
*
|
|
||||||
* @param selector css selector of the parent element which should be turned into image
|
|
||||||
* @param description name or a short description of what is being printed.
|
|
||||||
* Value will be normalized, and a date as well as a file extension will be added.
|
|
||||||
* @param isExactSelector if false, searches for the closest ancestor that matches selector.
|
|
||||||
* @returns event handler
|
|
||||||
*/
|
|
||||||
export default function downloadAsPdf(
|
|
||||||
selector: string,
|
|
||||||
description: string,
|
|
||||||
isExactSelector = false,
|
|
||||||
) {
|
|
||||||
return (event: SyntheticEvent) => {
|
|
||||||
const elementToPrint = isExactSelector
|
|
||||||
? document.querySelector(selector)
|
|
||||||
: event.currentTarget.closest(selector);
|
|
||||||
|
|
||||||
if (!elementToPrint) {
|
|
||||||
return addWarningToast(
|
|
||||||
t('PDF download failed, please refresh and try again.'),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const options = {
|
|
||||||
margin: 10,
|
|
||||||
filename: `${generateFileStem(description)}.pdf`,
|
|
||||||
image: { type: 'jpeg', quality: 1 },
|
|
||||||
html2canvas: { scale: 2 },
|
|
||||||
excludeClassNames: ['header-controls'],
|
|
||||||
};
|
|
||||||
return domToPdf(elementToPrint, options)
|
|
||||||
.then(() => {
|
|
||||||
// nothing to be done
|
|
||||||
})
|
|
||||||
.catch((e: Error) => {
|
|
||||||
logging.error('PDF generation failed', e);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -107,12 +107,12 @@ def cache_dashboard_thumbnail(
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=too-many-arguments
|
# pylint: disable=too-many-arguments
|
||||||
@celery_app.task(name="cache_dashboard_screenshot", soft_time_limit=60)
|
@celery_app.task(name="cache_dashboard_screenshot", soft_time_limit=300)
|
||||||
def cache_dashboard_screenshot(
|
def cache_dashboard_screenshot(
|
||||||
current_user: Optional[str],
|
current_user: Optional[str],
|
||||||
dashboard_id: int,
|
dashboard_id: int,
|
||||||
dashboard_url: str,
|
dashboard_url: str,
|
||||||
force: bool = False,
|
force: bool = True,
|
||||||
thumb_size: Optional[WindowSize] = None,
|
thumb_size: Optional[WindowSize] = None,
|
||||||
window_size: Optional[WindowSize] = None,
|
window_size: Optional[WindowSize] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue