Merge pull request #3395 from ethereum/sol2uml-download-matomo
Add download Button and Matomo Integration to Sol2Uml pluginwaittest2
commit
a9eb0e5f41
@ -0,0 +1,4 @@ |
|||||||
|
{ |
||||||
|
"solUml.pngDownload": "Download as PNG", |
||||||
|
"solUml.pdfDownload": "Download as PDF" |
||||||
|
} |
@ -0,0 +1,4 @@ |
|||||||
|
{ |
||||||
|
"solUml.PngDownload": "sfg", |
||||||
|
"solUml.PdfDownload": "sdf" |
||||||
|
} |
@ -0,0 +1,143 @@ |
|||||||
|
import { CustomTooltip } from '@remix-ui/helper' |
||||||
|
import React, { Fragment, Ref } from 'react' |
||||||
|
import { Dropdown } from 'react-bootstrap' |
||||||
|
import { UmlFileType } from '../utilities/UmlDownloadStrategy' |
||||||
|
|
||||||
|
const _paq = (window._paq = window._paq || []) |
||||||
|
|
||||||
|
export const Markup = React.forwardRef( |
||||||
|
( |
||||||
|
{ |
||||||
|
children, |
||||||
|
onClick, |
||||||
|
icon, |
||||||
|
className = "", |
||||||
|
}: { |
||||||
|
children: React.ReactNode |
||||||
|
onClick: (e) => void |
||||||
|
icon: string |
||||||
|
className: string |
||||||
|
}, |
||||||
|
ref: Ref<HTMLButtonElement> |
||||||
|
) => ( |
||||||
|
<button |
||||||
|
ref={ref} |
||||||
|
onClick={(e) => { |
||||||
|
e.preventDefault() |
||||||
|
onClick(e) |
||||||
|
}} |
||||||
|
className={className.replace("dropdown-toggle", "")} |
||||||
|
> |
||||||
|
<i className={icon}></i> |
||||||
|
</button> |
||||||
|
) |
||||||
|
) |
||||||
|
|
||||||
|
export const UmlCustomMenu = React.forwardRef( |
||||||
|
( |
||||||
|
{ |
||||||
|
children, |
||||||
|
style, |
||||||
|
className, |
||||||
|
"aria-labelledby": labeledBy, |
||||||
|
}: { |
||||||
|
children: React.ReactNode |
||||||
|
style?: React.CSSProperties |
||||||
|
className: string |
||||||
|
"aria-labelledby"?: string |
||||||
|
}, |
||||||
|
ref: Ref<HTMLDivElement> |
||||||
|
) => { |
||||||
|
const height = window.innerHeight * 0.6 |
||||||
|
return ( |
||||||
|
<div |
||||||
|
ref={ref} |
||||||
|
style={style} |
||||||
|
className={className} |
||||||
|
aria-labelledby={labeledBy} |
||||||
|
> |
||||||
|
<ul |
||||||
|
className="overflow-auto list-unstyled mb-0" |
||||||
|
style={{ maxHeight: height + "px" }} |
||||||
|
> |
||||||
|
{children} |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
) |
||||||
|
|
||||||
|
interface UmlDownloadProps { |
||||||
|
download: (fileType: UmlFileType) => void |
||||||
|
} |
||||||
|
|
||||||
|
export default function UmlDownload(props: UmlDownloadProps) { |
||||||
|
return ( |
||||||
|
<Fragment> |
||||||
|
<Dropdown id="solUmlMenuDropdown"> |
||||||
|
<Dropdown.Toggle |
||||||
|
icon="far fa-arrow-to-bottom uml-btn-icon" |
||||||
|
as={Markup} |
||||||
|
className="badge badge-info remixui_no-shadow p-2 rounded-circle mr-2" |
||||||
|
></Dropdown.Toggle> |
||||||
|
<Dropdown.Menu as={UmlCustomMenu} className="custom-dropdown-items"> |
||||||
|
<Dropdown.Item |
||||||
|
onClick={() => { |
||||||
|
_paq.push([ |
||||||
|
"trackEvent", |
||||||
|
"solidityumlgen", |
||||||
|
"download", |
||||||
|
"downloadAsPng", |
||||||
|
]); |
||||||
|
props.download("png") |
||||||
|
}} |
||||||
|
> |
||||||
|
<CustomTooltip |
||||||
|
placement="left-start" |
||||||
|
tooltipId="solUmlgenDownloadAsPngTooltip" |
||||||
|
tooltipClasses="text-nowrap" |
||||||
|
tooltipText={"Download UML diagram as a PNG file"} |
||||||
|
> |
||||||
|
<div data-id="umlPngDownload"> |
||||||
|
<span |
||||||
|
id="umlPngDownloadBtn" |
||||||
|
data-id="umlPngDownload" |
||||||
|
className="far fa-image pl-2" |
||||||
|
></span> |
||||||
|
<span className="pl-1">Download as PNG</span> |
||||||
|
</div> |
||||||
|
</CustomTooltip> |
||||||
|
</Dropdown.Item> |
||||||
|
<Dropdown.Divider /> |
||||||
|
<Dropdown.Item |
||||||
|
onClick={() => { |
||||||
|
_paq.push([ |
||||||
|
"trackEvent", |
||||||
|
"solUmlgen", |
||||||
|
"download", |
||||||
|
"downloadAsPdf", |
||||||
|
]); |
||||||
|
props.download("pdf") |
||||||
|
}} |
||||||
|
> |
||||||
|
<CustomTooltip |
||||||
|
placement="left-start" |
||||||
|
tooltipId="solUmlgenDownloadAsPdfTooltip" |
||||||
|
tooltipClasses="text-nowrap" |
||||||
|
tooltipText={"Download UML diagram as a PDF file"} |
||||||
|
> |
||||||
|
<div data-id="umlPdfDownload"> |
||||||
|
<span |
||||||
|
id="umlPdfDownloadBtn" |
||||||
|
data-id="umlPdfDownload" |
||||||
|
className="far fa-file-pdf pl-2" |
||||||
|
></span> |
||||||
|
<span className="pl-2">Download as PDF</span> |
||||||
|
</div> |
||||||
|
</CustomTooltip> |
||||||
|
</Dropdown.Item> |
||||||
|
</Dropdown.Menu> |
||||||
|
</Dropdown> |
||||||
|
</Fragment> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,86 @@ |
|||||||
|
interface IUmlDownloadStrategy { |
||||||
|
download (uml: string, fileName: string): void |
||||||
|
} |
||||||
|
|
||||||
|
export type UmlFileType = 'pdf' | 'png' |
||||||
|
|
||||||
|
class PdfUmlDownloadStrategy implements IUmlDownloadStrategy { |
||||||
|
|
||||||
|
public download (uml: string, fileName: string): void { |
||||||
|
const svg = new Blob([uml], { type: 'image/svg+xml;charset=utf-8' }) |
||||||
|
const Url = window.URL || window.webkitURL |
||||||
|
const url = Url.createObjectURL(svg) |
||||||
|
const img = document.createElement('img') |
||||||
|
let doc |
||||||
|
img.onload = async () => { |
||||||
|
const canvas = document.createElement('canvas') |
||||||
|
canvas.width = img.naturalWidth |
||||||
|
canvas.height = img.naturalHeight |
||||||
|
const ctx = canvas.getContext('2d') |
||||||
|
const scale = window.devicePixelRatio*1 |
||||||
|
canvas.style.width = `${Math.round(img.naturalWidth/scale)}`.concat('px') |
||||||
|
canvas.style.height = `${Math.round(img.naturalHeight/scale)}`.concat('px') |
||||||
|
canvas.style.margin = '0' |
||||||
|
canvas.style.padding = '0' |
||||||
|
ctx.scale(window.devicePixelRatio, window.devicePixelRatio) |
||||||
|
ctx.drawImage(img, 0, 0, Math.round(img.naturalWidth/scale), Math.round(img.naturalHeight/scale)) |
||||||
|
if (doc === null || doc === undefined) { |
||||||
|
const { default: jsPDF } = await import('jspdf') |
||||||
|
doc = new jsPDF('landscape', 'px', [img.naturalHeight, img.naturalWidth], true) |
||||||
|
} |
||||||
|
const pageWidth = doc.internal.pageSize.getWidth() |
||||||
|
const pageHeight = doc.internal.pageSize.getHeight() |
||||||
|
doc.addImage(canvas.toDataURL('image/png',0.5), 'PNG', 0, 0, pageWidth, pageHeight) |
||||||
|
doc.save(fileName.split('/')[1].split('.')[0].concat('.pdf')) |
||||||
|
} |
||||||
|
img.src = url |
||||||
|
doc = null |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class ImageUmlDownloadStrategy implements IUmlDownloadStrategy { |
||||||
|
public download (uml: string, fileName: string): void { |
||||||
|
const svg = new Blob([uml], { type: 'image/svg+xml;charset=utf-8' }) |
||||||
|
const Url = window.URL || window.webkitURL |
||||||
|
const url = Url.createObjectURL(svg) |
||||||
|
const img = document.createElement('img') |
||||||
|
img.onload = () => { |
||||||
|
const canvas = document.createElement('canvas') |
||||||
|
canvas.width = img.naturalWidth |
||||||
|
canvas.height = img.naturalHeight |
||||||
|
const ctx = canvas.getContext('2d') |
||||||
|
const scale = window.devicePixelRatio*1 |
||||||
|
canvas.style.width = `${Math.round(img.naturalWidth/scale)}`.concat('px') |
||||||
|
canvas.style.height = `${Math.round(img.naturalHeight/scale)}`.concat('px') |
||||||
|
canvas.style.margin = '0' |
||||||
|
canvas.style.padding = '0' |
||||||
|
ctx.scale(window.devicePixelRatio, window.devicePixelRatio) |
||||||
|
ctx.drawImage(img, 0, 0, Math.round(img.naturalWidth/scale), Math.round(img.naturalHeight/scale)) |
||||||
|
const png = canvas.toDataURL('image/png') |
||||||
|
const a = document.createElement('a') |
||||||
|
a.download = fileName.split('/')[1].split('.')[0].concat('.png') |
||||||
|
a.href = png |
||||||
|
a.click() |
||||||
|
} |
||||||
|
img.src = url |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export class UmlDownloadContext { |
||||||
|
private strategy: IUmlDownloadStrategy |
||||||
|
|
||||||
|
private setStrategy (strategy: IUmlDownloadStrategy): void { |
||||||
|
this.strategy = strategy |
||||||
|
} |
||||||
|
|
||||||
|
public download (uml: string, fileName: string, fileType: UmlFileType ): void { |
||||||
|
if (fileType === 'pdf') { |
||||||
|
this.setStrategy(new PdfUmlDownloadStrategy()) |
||||||
|
} else if (fileType === 'png') { |
||||||
|
this.setStrategy(new ImageUmlDownloadStrategy()) |
||||||
|
} else { |
||||||
|
throw new Error('Invalid file type') |
||||||
|
} |
||||||
|
this.strategy.download(uml, fileName) |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue