mirror of
https://github.com/nocodb/nocodb.git
synced 2026-04-30 07:06:47 +00:00
feat: Added barcode download btn
This commit is contained in:
@@ -6,13 +6,14 @@ const props = defineProps({
|
||||
barcodeValue: { type: String, required: true },
|
||||
barcodeFormat: { type: String, required: true },
|
||||
customStyle: { type: Object, required: false },
|
||||
showDownload: { type: Boolean, required: false, default: false },
|
||||
})
|
||||
|
||||
const emit = defineEmits(['onClickBarcode'])
|
||||
|
||||
const isGallery = inject(IsGalleryInj, ref(false))
|
||||
|
||||
const barcodeSvgRef = ref<HTMLElement>()
|
||||
const barcodeSvgRef = ref<SVGGraphicsElement>()
|
||||
const errorForCurrentInput = ref(false)
|
||||
|
||||
const generate = () => {
|
||||
@@ -34,6 +35,79 @@ const generate = () => {
|
||||
}
|
||||
}
|
||||
|
||||
function copyStylesInline(destinationNode: any, sourceNode: any) {
|
||||
const containerElements = ['svg', 'g']
|
||||
for (let cd = 0; cd < destinationNode.childNodes.length; cd++) {
|
||||
const child = destinationNode.childNodes[cd]
|
||||
if (containerElements.includes(child.tagName)) {
|
||||
copyStylesInline(child, sourceNode.childNodes[cd])
|
||||
continue
|
||||
}
|
||||
|
||||
const style = sourceNode.childNodes[cd].currentStyle || window.getComputedStyle(sourceNode.childNodes[cd])
|
||||
if (style === 'undefined' || style == null) continue
|
||||
for (let st = 0; st < style.length; st++) {
|
||||
child.style.setProperty(style[st], style.getPropertyValue(style[st]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function triggerDownload(imgURI: string, fileName: string) {
|
||||
const evt = new MouseEvent('click', {
|
||||
view: window,
|
||||
bubbles: false,
|
||||
cancelable: true,
|
||||
})
|
||||
const a = document.createElement('a')
|
||||
a.setAttribute('download', fileName)
|
||||
a.setAttribute('href', imgURI)
|
||||
a.setAttribute('target', '_blank')
|
||||
a.dispatchEvent(evt)
|
||||
}
|
||||
|
||||
function _downloadSvg(svg: SVGGraphicsElement, fileName: string) {
|
||||
const copy = svg.cloneNode(true)
|
||||
|
||||
copyStylesInline(copy, svg)
|
||||
|
||||
const canvas = document.createElement('canvas')
|
||||
const bbox = svg.getBBox()
|
||||
canvas.width = bbox.width
|
||||
canvas.height = bbox.height
|
||||
|
||||
const ctx = canvas.getContext('2d')!
|
||||
ctx.clearRect(0, 0, bbox.width, bbox.height)
|
||||
|
||||
const data = new XMLSerializer().serializeToString(copy)
|
||||
const DOMURL = window.URL || window.webkitURL || window
|
||||
const img = new Image()
|
||||
const svgBlob = new Blob([data], { type: 'image/svg+xml;charset=utf-8' })
|
||||
const url = DOMURL.createObjectURL(svgBlob)
|
||||
|
||||
img.onload = function () {
|
||||
ctx.drawImage(img, 0, 0)
|
||||
DOMURL.revokeObjectURL(url)
|
||||
if (typeof navigator !== 'undefined' && navigator.msSaveOrOpenBlob) {
|
||||
const blob = canvas.msToBlob()
|
||||
navigator.msSaveOrOpenBlob(blob, fileName)
|
||||
} else {
|
||||
const imgURI = canvas.toDataURL('image/png').replace('image/png', 'image/octet-stream')
|
||||
triggerDownload(imgURI, fileName)
|
||||
}
|
||||
console.log(canvas)
|
||||
|
||||
// TODO: Somehow canvas dom element is getting deleted
|
||||
// document.removeChild(canvas)
|
||||
}
|
||||
img.src = url
|
||||
}
|
||||
|
||||
const downloadSvg = () => {
|
||||
if (!barcodeSvgRef.value) return
|
||||
|
||||
_downloadSvg(barcodeSvgRef.value, `${props.barcodeValue}.png`)
|
||||
}
|
||||
|
||||
const onBarcodeClick = (ev: MouseEvent) => {
|
||||
if (isGallery.value) return
|
||||
ev.stopPropagation()
|
||||
@@ -45,15 +119,25 @@ onMounted(generate)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<svg
|
||||
v-show="!errorForCurrentInput"
|
||||
ref="barcodeSvgRef"
|
||||
:class="{
|
||||
'w-full': !isGallery,
|
||||
'w-auto': isGallery,
|
||||
}"
|
||||
data-testid="barcode"
|
||||
@click="onBarcodeClick"
|
||||
></svg>
|
||||
<slot v-if="errorForCurrentInput" name="barcodeRenderError" />
|
||||
<div class="relative">
|
||||
<svg
|
||||
v-show="!errorForCurrentInput"
|
||||
ref="barcodeSvgRef"
|
||||
:class="{
|
||||
'w-full': !isGallery,
|
||||
'w-auto': isGallery,
|
||||
}"
|
||||
data-testid="barcode"
|
||||
@click="onBarcodeClick"
|
||||
></svg>
|
||||
<slot v-if="errorForCurrentInput" name="barcodeRenderError" />
|
||||
<NcTooltip class="!absolute bottom-0 right-0">
|
||||
<template #title>
|
||||
{{ $t('labels.clickToDownload') }}
|
||||
</template>
|
||||
<NcButton v-if="props.showDownload" size="small" type="secondary" @click="downloadSvg">
|
||||
<GeneralIcon icon="download" class="w-4 h-4" />
|
||||
</NcButton>
|
||||
</NcTooltip>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user