detect fields
This commit is contained in:
@@ -156,6 +156,7 @@ safeRegisterElement('template-builder', class extends HTMLElement {
|
||||
withPhone: this.dataset.withPhone === 'true',
|
||||
withVerification: ['true', 'false'].includes(this.dataset.withVerification) ? this.dataset.withVerification === 'true' : null,
|
||||
withLogo: this.dataset.withLogo !== 'false',
|
||||
withFieldsDetection: this.dataset.withFieldsDetection === 'true',
|
||||
editable: this.dataset.editable !== 'false',
|
||||
authenticityToken: document.querySelector('meta[name="csrf-token"]')?.content,
|
||||
withPayment: this.dataset.withPayment === 'true',
|
||||
|
||||
@@ -449,6 +449,7 @@
|
||||
:default-required-fields="defaultRequiredFields"
|
||||
:field-types="fieldTypes"
|
||||
:with-sticky-submitters="withStickySubmitters"
|
||||
:with-fields-detection="withFieldsDetection"
|
||||
:with-signature-id="withSignatureId"
|
||||
:with-prefillable="withPrefillable"
|
||||
:only-defined-fields="onlyDefinedFields"
|
||||
@@ -618,6 +619,11 @@ export default {
|
||||
required: false,
|
||||
default: true
|
||||
},
|
||||
withFieldsDetection: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
withAddPageButton: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
|
||||
@@ -208,6 +208,34 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div
|
||||
v-if="withFieldsDetection && editable && fields.length < 2"
|
||||
class="mt-2"
|
||||
>
|
||||
<button
|
||||
class="btn w-full"
|
||||
:class="{ 'bg-base-300': fieldPagesLoaded !== null }"
|
||||
@click="fieldPagesLoaded !== null ? null : detectFields()"
|
||||
>
|
||||
<template v-if="fieldPagesLoaded !== null">
|
||||
<IconInnerShadowTop
|
||||
width="22"
|
||||
class="animate-spin"
|
||||
/>
|
||||
<span class="hidden md:inline">
|
||||
{{ fieldPagesLoaded }} / {{ numberOfPages }} {{ t('processing_') }}
|
||||
</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<IconListSearch width="22" />
|
||||
<span
|
||||
class="hidden md:inline"
|
||||
>
|
||||
{{ t('autodetect_fields') }}
|
||||
</span>
|
||||
</template>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
v-show="fields.length < 4 && editable && withHelp && showTourStartForm"
|
||||
class="rounded py-2 px-4 w-full border border-dashed border-base-300"
|
||||
@@ -231,7 +259,7 @@
|
||||
import Field from './field'
|
||||
import FieldType from './field_type'
|
||||
import FieldSubmitter from './field_submitter'
|
||||
import { IconLock, IconCirclePlus } from '@tabler/icons-vue'
|
||||
import { IconLock, IconCirclePlus, IconInnerShadowTop, IconListSearch } from '@tabler/icons-vue'
|
||||
import IconDrag from './icon_drag'
|
||||
|
||||
export default {
|
||||
@@ -240,11 +268,13 @@ export default {
|
||||
Field,
|
||||
FieldType,
|
||||
IconCirclePlus,
|
||||
IconListSearch,
|
||||
IconInnerShadowTop,
|
||||
FieldSubmitter,
|
||||
IconDrag,
|
||||
IconLock
|
||||
},
|
||||
inject: ['save', 'backgroundColor', 'withPhone', 'withVerification', 'withPayment', 't', 'fieldsDragFieldRef'],
|
||||
inject: ['save', 'backgroundColor', 'withPhone', 'withVerification', 'withPayment', 't', 'fieldsDragFieldRef', 'baseFetch'],
|
||||
props: {
|
||||
fields: {
|
||||
type: Array,
|
||||
@@ -255,6 +285,11 @@ export default {
|
||||
required: false,
|
||||
default: null
|
||||
},
|
||||
withFieldsDetection: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
withSignatureId: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
@@ -331,12 +366,18 @@ export default {
|
||||
emits: ['add-field', 'set-draw', 'set-draw-type', 'set-drag', 'drag-end', 'scroll-to-area', 'change-submitter', 'set-drag-placeholder'],
|
||||
data () {
|
||||
return {
|
||||
fieldPagesLoaded: null,
|
||||
defaultFieldsSearch: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
fieldNames: FieldType.computed.fieldNames,
|
||||
fieldIcons: FieldType.computed.fieldIcons,
|
||||
numberOfPages () {
|
||||
return this.template.documents.reduce((acc, doc) => {
|
||||
return acc + doc.metadata?.pdf?.number_of_pages || doc.preview_images.length
|
||||
}, 0)
|
||||
},
|
||||
isShowFieldSearch () {
|
||||
if (this.withFieldsSearch === false) {
|
||||
return false
|
||||
@@ -389,6 +430,61 @@ export default {
|
||||
|
||||
this.$emit('set-drag', field)
|
||||
},
|
||||
detectFields () {
|
||||
const fields = []
|
||||
|
||||
this.fieldPagesLoaded = 0
|
||||
|
||||
this.baseFetch(`/templates/${this.template.id}/detect_fields`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then(async (response) => {
|
||||
const reader = response.body.getReader()
|
||||
const decoder = new TextDecoder('utf-8')
|
||||
let buffer = ''
|
||||
|
||||
while (true) {
|
||||
const { value, done } = await reader.read()
|
||||
|
||||
if (done) break
|
||||
|
||||
buffer += decoder.decode(value, { stream: true })
|
||||
|
||||
const lines = buffer.split('\n\n')
|
||||
|
||||
buffer = lines.pop()
|
||||
|
||||
for (const line of lines) {
|
||||
if (line.startsWith('data: ')) {
|
||||
const jsonStr = line.replace(/^data: /, '')
|
||||
const data = JSON.parse(jsonStr)
|
||||
|
||||
if (data.completed) {
|
||||
this.fieldPagesLoaded = null
|
||||
this.template.fields = fields
|
||||
|
||||
break
|
||||
} else if (data.fields) {
|
||||
data.fields.forEach((f) => {
|
||||
f.submitter_uuid = this.template.submitters[0].uuid
|
||||
})
|
||||
|
||||
this.fieldPagesLoaded += 1
|
||||
|
||||
fields.push(...data.fields)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}).catch(error => {
|
||||
console.error('Error in streaming message: ', error)
|
||||
}).finally(() => {
|
||||
this.fieldPagesLoaded = null
|
||||
this.isFieldsLoading = false
|
||||
})
|
||||
},
|
||||
setDragPlaceholder (event) {
|
||||
this.$emit('set-drag-placeholder', {
|
||||
offsetX: event.offsetX,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
const en = {
|
||||
view: 'View',
|
||||
autodetect_fields: 'Autodetect fields',
|
||||
payment_link: 'Payment link',
|
||||
strikeout: 'Strikeout',
|
||||
draw_strikethrough_the_document: 'Draw strikethrough the document',
|
||||
|
||||
Reference in New Issue
Block a user