google drive file picker
This commit is contained in:
@@ -118,7 +118,8 @@ class TemplatesController < ApplicationController
|
|||||||
def template_params
|
def template_params
|
||||||
params.require(:template).permit(
|
params.require(:template).permit(
|
||||||
:name,
|
:name,
|
||||||
{ schema: [[:attachment_uuid, :name, { conditions: [%i[field_uuid value action operation]] }]],
|
{ schema: [[:attachment_uuid, :google_drive_file_id, :name,
|
||||||
|
{ conditions: [%i[field_uuid value action operation]] }]],
|
||||||
submitters: [%i[name uuid is_requester linked_to_uuid invite_by_uuid optional_invite_by_uuid email order]],
|
submitters: [%i[name uuid is_requester linked_to_uuid invite_by_uuid optional_invite_by_uuid email order]],
|
||||||
fields: [[:uuid, :submitter_uuid, :name, :type,
|
fields: [[:uuid, :submitter_uuid, :name, :type,
|
||||||
:required, :readonly, :default_value,
|
:required, :readonly, :default_value,
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ import ShowOnValue from './elements/show_on_value'
|
|||||||
import CustomValidation from './elements/custom_validation'
|
import CustomValidation from './elements/custom_validation'
|
||||||
import ToggleClasses from './elements/toggle_classes'
|
import ToggleClasses from './elements/toggle_classes'
|
||||||
import AutosizeField from './elements/autosize_field'
|
import AutosizeField from './elements/autosize_field'
|
||||||
|
import GoogleDriveFilePicker from './elements/google_drive_file_picker'
|
||||||
|
import OpenModal from './elements/open_modal'
|
||||||
|
|
||||||
import * as TurboInstantClick from './lib/turbo_instant_click'
|
import * as TurboInstantClick from './lib/turbo_instant_click'
|
||||||
|
|
||||||
@@ -136,6 +138,8 @@ safeRegisterElement('show-on-value', ShowOnValue)
|
|||||||
safeRegisterElement('custom-validation', CustomValidation)
|
safeRegisterElement('custom-validation', CustomValidation)
|
||||||
safeRegisterElement('toggle-classes', ToggleClasses)
|
safeRegisterElement('toggle-classes', ToggleClasses)
|
||||||
safeRegisterElement('autosize-field', AutosizeField)
|
safeRegisterElement('autosize-field', AutosizeField)
|
||||||
|
safeRegisterElement('google-drive-file-picker', GoogleDriveFilePicker)
|
||||||
|
safeRegisterElement('open-modal', OpenModal)
|
||||||
|
|
||||||
safeRegisterElement('template-builder', class extends HTMLElement {
|
safeRegisterElement('template-builder', class extends HTMLElement {
|
||||||
connectedCallback () {
|
connectedCallback () {
|
||||||
@@ -160,6 +164,7 @@ safeRegisterElement('template-builder', class extends HTMLElement {
|
|||||||
withSendButton: this.dataset.withSendButton !== 'false',
|
withSendButton: this.dataset.withSendButton !== 'false',
|
||||||
withSignYourselfButton: this.dataset.withSignYourselfButton !== 'false',
|
withSignYourselfButton: this.dataset.withSignYourselfButton !== 'false',
|
||||||
withConditions: this.dataset.withConditions === 'true',
|
withConditions: this.dataset.withConditions === 'true',
|
||||||
|
withGoogleDrive: this.dataset.withGoogleDrive === 'true',
|
||||||
withReplaceAndCloneUpload: true,
|
withReplaceAndCloneUpload: true,
|
||||||
currencies: (this.dataset.currencies || '').split(',').filter(Boolean),
|
currencies: (this.dataset.currencies || '').split(',').filter(Boolean),
|
||||||
acceptFileTypes: this.dataset.acceptFileTypes,
|
acceptFileTypes: this.dataset.acceptFileTypes,
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
export default class extends HTMLElement {
|
||||||
|
connectedCallback () {
|
||||||
|
const iframeTemplate = this.querySelector('template')
|
||||||
|
|
||||||
|
this.observer = new IntersectionObserver((entries) => {
|
||||||
|
if (entries.some(e => e.isIntersecting)) {
|
||||||
|
iframeTemplate.parentElement.prepend(iframeTemplate.content)
|
||||||
|
|
||||||
|
this.observer.disconnect()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.observer.observe(this)
|
||||||
|
|
||||||
|
window.addEventListener('message', this.messageHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
messageHandler = (event) => {
|
||||||
|
if (event.data.type === 'google-drive-files-picked') {
|
||||||
|
this.form.querySelectorAll('input[name="google_drive_file_ids[]"]').forEach(el => el.remove())
|
||||||
|
|
||||||
|
const files = event.data.files || []
|
||||||
|
|
||||||
|
files.forEach((file) => {
|
||||||
|
const input = document.createElement('input')
|
||||||
|
input.type = 'hidden'
|
||||||
|
input.name = 'google_drive_file_ids[]'
|
||||||
|
input.value = file.id
|
||||||
|
this.form.appendChild(input)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.form.querySelector('button[type="submit"]').click()
|
||||||
|
this.loader.classList.remove('hidden')
|
||||||
|
} else if (event.data.type === 'google-drive-picker-loaded') {
|
||||||
|
this.loader.classList.add('hidden')
|
||||||
|
this.form.classList.remove('hidden')
|
||||||
|
} else if (event.data.type === 'google-drive-picker-request-oauth') {
|
||||||
|
document.getElementById(this.dataset.oauthButtonId).classList.remove('hidden')
|
||||||
|
this.classList.add('hidden')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnectedCallback () {
|
||||||
|
this.observer?.unobserve(this)
|
||||||
|
window.removeEventListener('message', this.messageHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
get form () {
|
||||||
|
return this.querySelector('form')
|
||||||
|
}
|
||||||
|
|
||||||
|
get loader () {
|
||||||
|
return document.getElementById('google_drive_loader')
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
export default class extends HTMLElement {
|
||||||
|
connectedCallback () {
|
||||||
|
const src = this.getAttribute('src')
|
||||||
|
const link = document.createElement('a')
|
||||||
|
|
||||||
|
link.href = src
|
||||||
|
link.setAttribute('data-turbo-frame', 'modal')
|
||||||
|
link.style.display = 'none'
|
||||||
|
|
||||||
|
this.appendChild(link)
|
||||||
|
|
||||||
|
link.click()
|
||||||
|
|
||||||
|
window.history.replaceState({}, document.title, window.location.pathname)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -260,8 +260,12 @@
|
|||||||
:style="{ backgroundColor }"
|
:style="{ backgroundColor }"
|
||||||
>
|
>
|
||||||
<Upload
|
<Upload
|
||||||
v-if="sortedDocuments.length && editable && withUploadButton"
|
v-if="editable && withUploadButton"
|
||||||
|
v-show="sortedDocuments.length"
|
||||||
|
ref="upload"
|
||||||
:accept-file-types="acceptFileTypes"
|
:accept-file-types="acceptFileTypes"
|
||||||
|
:authenticity-token="authenticityToken"
|
||||||
|
:with-google-drive="withGoogleDrive"
|
||||||
:template-id="template.id"
|
:template-id="template.id"
|
||||||
@success="updateFromUpload"
|
@success="updateFromUpload"
|
||||||
/>
|
/>
|
||||||
@@ -297,6 +301,8 @@
|
|||||||
v-if="withUploadButton"
|
v-if="withUploadButton"
|
||||||
:template-id="template.id"
|
:template-id="template.id"
|
||||||
:accept-file-types="acceptFileTypes"
|
:accept-file-types="acceptFileTypes"
|
||||||
|
:with-google-drive="withGoogleDrive"
|
||||||
|
@click-google-drive="$refs.upload.openGoogleDriveModal()"
|
||||||
@success="updateFromUpload"
|
@success="updateFromUpload"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
@@ -368,6 +374,8 @@
|
|||||||
v-if="withUploadButton"
|
v-if="withUploadButton"
|
||||||
:template-id="template.id"
|
:template-id="template.id"
|
||||||
:accept-file-types="acceptFileTypes"
|
:accept-file-types="acceptFileTypes"
|
||||||
|
:authenticity-token="authenticityToken"
|
||||||
|
:with-google-drive="withGoogleDrive"
|
||||||
@success="updateFromUpload"
|
@success="updateFromUpload"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
@@ -766,6 +774,11 @@ export default {
|
|||||||
required: false,
|
required: false,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
withGoogleDrive: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
onlyDefinedFields: {
|
onlyDefinedFields: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
@@ -1757,8 +1770,9 @@ export default {
|
|||||||
},
|
},
|
||||||
onDocumentReplace (data) {
|
onDocumentReplace (data) {
|
||||||
const { replaceSchemaItem, schema, documents } = data
|
const { replaceSchemaItem, schema, documents } = data
|
||||||
|
const { google_drive_file_id, ...cleanedReplaceSchemaItem } = replaceSchemaItem
|
||||||
|
|
||||||
this.template.schema.splice(this.template.schema.indexOf(replaceSchemaItem), 1, { ...replaceSchemaItem, ...schema[0] })
|
this.template.schema.splice(this.template.schema.indexOf(replaceSchemaItem), 1, { ...cleanedReplaceSchemaItem, ...schema[0] })
|
||||||
this.template.documents.push(...documents)
|
this.template.documents.push(...documents)
|
||||||
|
|
||||||
if (data.fields) {
|
if (data.fields) {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
:contenteditable="editable"
|
:contenteditable="editable"
|
||||||
style="min-width: 2px"
|
style="min-width: 2px"
|
||||||
:class="iconInline ? 'inline' : 'block'"
|
:class="iconInline ? 'inline' : 'block'"
|
||||||
class="peer outline-none focus:block"
|
class="peer outline-none"
|
||||||
@paste.prevent="onPaste"
|
@paste.prevent="onPaste"
|
||||||
@keydown.enter.prevent="blurContenteditable"
|
@keydown.enter.prevent="blurContenteditable"
|
||||||
@focus="$emit('focus', $event)"
|
@focus="$emit('focus', $event)"
|
||||||
@@ -26,10 +26,10 @@
|
|||||||
*
|
*
|
||||||
</span>
|
</span>
|
||||||
<IconPencil
|
<IconPencil
|
||||||
class="cursor-pointer flex-none opacity-0 group-hover/contenteditable-container:opacity-100 group-hover/contenteditable:opacity-100 align-middle peer-focus:hidden"
|
class="cursor-pointer flex-none opacity-0 group-hover/contenteditable-container:opacity-100 group-hover/contenteditable:opacity-100 align-middle"
|
||||||
:style="iconInline ? {} : { right: -(1.1 * iconWidth) + 'px' }"
|
:style="iconInline ? {} : { right: -(1.1 * iconWidth) + 'px' }"
|
||||||
:title="t('edit')"
|
:title="t('edit')"
|
||||||
:class="{ invisible: !editable, 'ml-1': !withRequired, 'absolute': !iconInline, 'inline align-bottom': iconInline }"
|
:class="{ invisible: !editable, 'ml-1': !withRequired, 'absolute': !iconInline, 'inline align-bottom': iconInline, 'peer-focus:hidden': hideIcon, 'peer-focus:invisible': !hideIcon }"
|
||||||
:width="iconWidth"
|
:width="iconWidth"
|
||||||
:stroke-width="iconStrokeWidth"
|
:stroke-width="iconStrokeWidth"
|
||||||
@click="[focusContenteditable(), selectOnEditClick && selectContent()]"
|
@click="[focusContenteditable(), selectOnEditClick && selectContent()]"
|
||||||
@@ -62,6 +62,11 @@ export default {
|
|||||||
required: false,
|
required: false,
|
||||||
default: 30
|
default: 30
|
||||||
},
|
},
|
||||||
|
hideIcon: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
withRequired: {
|
withRequired: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
:for="inputId"
|
:for="inputId"
|
||||||
:class="{ 'opacity-50': isLoading, 'hover:bg-base-200/50': withHoverClass && !isDragEntering, 'bg-base-200/50 border-base-content/30': isDragEntering }"
|
:class="{ 'opacity-50': isLoading, 'hover:bg-base-200/50': withHoverClass && !isDragEntering, 'bg-base-200/50 border-base-content/30': isDragEntering }"
|
||||||
>
|
>
|
||||||
<div class="absolute top-0 right-0 left-0 bottom-0 flex items-center justify-center pointer-events-none">
|
<div class="absolute top-0 right-0 left-0 bottom-0 flex items-center justify-center">
|
||||||
<div class="flex flex-col items-center">
|
<div class="flex flex-col items-center pointer-events-none">
|
||||||
<IconInnerShadowTop
|
<IconInnerShadowTop
|
||||||
v-if="isLoading"
|
v-if="isLoading"
|
||||||
class="animate-spin"
|
class="animate-spin"
|
||||||
@@ -40,6 +40,15 @@
|
|||||||
>
|
>
|
||||||
<span class="font-medium">{{ t('click_to_upload') }}</span> {{ t('or_drag_and_drop_files') }}
|
<span class="font-medium">{{ t('click_to_upload') }}</span> {{ t('or_drag_and_drop_files') }}
|
||||||
</div>
|
</div>
|
||||||
|
<button
|
||||||
|
v-if="withGoogleDrive"
|
||||||
|
class="flex items-center text-sm mt-2 pointer-events-auto"
|
||||||
|
@click.stop.prevent="$emit('click-google-drive')"
|
||||||
|
>
|
||||||
|
<span>{{ t('or_add_from') }}</span>
|
||||||
|
<IconBrandGoogleDrive class="w-4 h-4 inline-block ml-1" />
|
||||||
|
<span class="ml-1 font-medium hover:underline">Google Drive</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form
|
<form
|
||||||
@@ -62,7 +71,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Upload from './upload'
|
import Upload from './upload'
|
||||||
import { IconCloudUpload, IconFilePlus, IconFileSymlink, IconFiles, IconInnerShadowTop } from '@tabler/icons-vue'
|
import { IconCloudUpload, IconFilePlus, IconFileSymlink, IconFiles, IconInnerShadowTop, IconBrandGoogleDrive } from '@tabler/icons-vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'FileDropzone',
|
name: 'FileDropzone',
|
||||||
@@ -71,7 +80,8 @@ export default {
|
|||||||
IconCloudUpload,
|
IconCloudUpload,
|
||||||
IconInnerShadowTop,
|
IconInnerShadowTop,
|
||||||
IconFileSymlink,
|
IconFileSymlink,
|
||||||
IconFiles
|
IconFiles,
|
||||||
|
IconBrandGoogleDrive
|
||||||
},
|
},
|
||||||
inject: ['baseFetch', 't'],
|
inject: ['baseFetch', 't'],
|
||||||
props: {
|
props: {
|
||||||
@@ -99,6 +109,11 @@ export default {
|
|||||||
required: false,
|
required: false,
|
||||||
default: true
|
default: true
|
||||||
},
|
},
|
||||||
|
withGoogleDrive: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
@@ -110,7 +125,7 @@ export default {
|
|||||||
default: 'image/*, application/pdf, application/zip'
|
default: 'image/*, application/pdf, application/zip'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: ['success', 'error', 'loading'],
|
emits: ['success', 'error', 'loading', 'click-google-drive'],
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
|
|||||||
@@ -125,7 +125,7 @@
|
|||||||
@update:model-value="$emit('name-change', selectedSubmitter)"
|
@update:model-value="$emit('name-change', selectedSubmitter)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span class="flex items-center transition-all duration-75 group-hover:border border-base-content/20 border-dashed w-6 h-6 flex justify-center items-center rounded">
|
<span class="flex items-center transition-all duration-75 group-hover:border border-base-content/20 border-dashed w-6 h-6 justify-center rounded">
|
||||||
<component
|
<component
|
||||||
:is="editable ? 'IconPlus' : 'IconChevronDown'"
|
:is="editable ? 'IconPlus' : 'IconChevronDown'"
|
||||||
width="18"
|
width="18"
|
||||||
|
|||||||
@@ -0,0 +1,102 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="dropdown"
|
||||||
|
:class="{ 'dropdown-open': isLoading }"
|
||||||
|
>
|
||||||
|
<label tabindex="0">
|
||||||
|
<IconBrandGoogleDrive class="w-5 h-5 inline-block mr-1 cursor-pointer" />
|
||||||
|
</label>
|
||||||
|
<ul
|
||||||
|
tabindex="0"
|
||||||
|
:style="{ backgroundColor }"
|
||||||
|
class="dropdown-content z-[1] shadow menu rounded-box"
|
||||||
|
>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
:href="`https://drive.google.com/file/d/${googleDriveFileId}/view?usp=sharing`"
|
||||||
|
data-turbo="false"
|
||||||
|
target="_blank"
|
||||||
|
class="flex items-center"
|
||||||
|
>
|
||||||
|
<IconExternalLink class="w-4 h-4 flex-shrink-0" />
|
||||||
|
<span>{{ t('view') }}</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<form
|
||||||
|
ref="form"
|
||||||
|
class="flex items-center"
|
||||||
|
@submit.prevent="upload({ path: uploadUrl })"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
:id="inputId"
|
||||||
|
ref="input"
|
||||||
|
:value="googleDriveFileId"
|
||||||
|
type="hidden"
|
||||||
|
name="google_drive_file_ids[]"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
:disabled="isLoading"
|
||||||
|
class="flex items-center w-full space-x-2"
|
||||||
|
>
|
||||||
|
<IconRefresh
|
||||||
|
class="w-4 h-4 flex-shrink-0"
|
||||||
|
:class="{ 'animate-spin': isLoading }"
|
||||||
|
/>
|
||||||
|
<span>{{ message }}</span>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Upload from './upload'
|
||||||
|
import { IconRefresh, IconBrandGoogleDrive, IconExternalLink } from '@tabler/icons-vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'GoogleDriveDocumentSettings',
|
||||||
|
components: {
|
||||||
|
IconRefresh,
|
||||||
|
IconBrandGoogleDrive,
|
||||||
|
IconExternalLink
|
||||||
|
},
|
||||||
|
inject: ['baseFetch', 't', 'backgroundColor'],
|
||||||
|
props: {
|
||||||
|
templateId: {
|
||||||
|
type: [Number, String],
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
googleDriveFileId: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emits: ['success'],
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
isLoading: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
inputId () {
|
||||||
|
return 'el' + Math.random().toString(32).split('.')[1]
|
||||||
|
},
|
||||||
|
uploadUrl () {
|
||||||
|
return `/templates/${this.templateId}/google_drive_documents`
|
||||||
|
},
|
||||||
|
message () {
|
||||||
|
if (this.isLoading) {
|
||||||
|
return this.t('syncing')
|
||||||
|
} else {
|
||||||
|
return this.t('sync')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
upload: Upload.methods.upload
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
const en = {
|
const en = {
|
||||||
|
view: 'View',
|
||||||
payment_link: 'Payment link',
|
payment_link: 'Payment link',
|
||||||
strikeout: 'Strikeout',
|
strikeout: 'Strikeout',
|
||||||
draw_strikethrough_the_document: 'Draw strikethrough the document',
|
draw_strikethrough_the_document: 'Draw strikethrough the document',
|
||||||
@@ -176,10 +177,14 @@ const en = {
|
|||||||
and: 'and',
|
and: 'and',
|
||||||
or: 'or',
|
or: 'or',
|
||||||
start_a_quick_tour_to_learn_how_to_create_an_send_your_first_document: 'Start a quick tour to learn how to create an send your first document',
|
start_a_quick_tour_to_learn_how_to_create_an_send_your_first_document: 'Start a quick tour to learn how to create an send your first document',
|
||||||
start_tour: 'Start Tour'
|
start_tour: 'Start Tour',
|
||||||
|
or_add_from: 'Or add from',
|
||||||
|
sync: 'Sync',
|
||||||
|
syncing: 'Syncing...'
|
||||||
}
|
}
|
||||||
|
|
||||||
const es = {
|
const es = {
|
||||||
|
view: 'Vista',
|
||||||
payment_link: 'Enlace de pago',
|
payment_link: 'Enlace de pago',
|
||||||
strikeout: 'Tachar',
|
strikeout: 'Tachar',
|
||||||
draw_strikethrough_the_document: 'Dibujar una línea de tachado en el documento',
|
draw_strikethrough_the_document: 'Dibujar una línea de tachado en el documento',
|
||||||
@@ -357,10 +362,14 @@ const es = {
|
|||||||
and: 'y',
|
and: 'y',
|
||||||
or: 'o',
|
or: 'o',
|
||||||
start_a_quick_tour_to_learn_how_to_create_an_send_your_first_document: 'Inicia una guía rápida para aprender a crear y enviar tu primer documento.',
|
start_a_quick_tour_to_learn_how_to_create_an_send_your_first_document: 'Inicia una guía rápida para aprender a crear y enviar tu primer documento.',
|
||||||
start_tour: 'Iniciar guía'
|
start_tour: 'Iniciar guía',
|
||||||
|
or_add_from: 'O agregar desde',
|
||||||
|
sync: 'Sincronizar',
|
||||||
|
syncing: 'Sincronizando...'
|
||||||
}
|
}
|
||||||
|
|
||||||
const it = {
|
const it = {
|
||||||
|
view: 'Vista',
|
||||||
payment_link: 'Link di pagamento',
|
payment_link: 'Link di pagamento',
|
||||||
strikeout: 'Barrato',
|
strikeout: 'Barrato',
|
||||||
draw_strikethrough_the_document: 'Disegna una linea barrata sul documento',
|
draw_strikethrough_the_document: 'Disegna una linea barrata sul documento',
|
||||||
@@ -538,10 +547,14 @@ const it = {
|
|||||||
and: 'e',
|
and: 'e',
|
||||||
or: 'o',
|
or: 'o',
|
||||||
start_a_quick_tour_to_learn_how_to_create_an_send_your_first_document: 'Inizia un tour rapido per imparare a creare e inviare il tuo primo documento.',
|
start_a_quick_tour_to_learn_how_to_create_an_send_your_first_document: 'Inizia un tour rapido per imparare a creare e inviare il tuo primo documento.',
|
||||||
start_tour: 'Inizia il tour'
|
start_tour: 'Inizia il tour',
|
||||||
|
or_add_from: 'O aggiungi da',
|
||||||
|
sync: 'Sincronizza',
|
||||||
|
syncing: 'Sincronizzazione...'
|
||||||
}
|
}
|
||||||
|
|
||||||
const pt = {
|
const pt = {
|
||||||
|
view: 'Visualizar',
|
||||||
payment_link: 'Link de pagamento',
|
payment_link: 'Link de pagamento',
|
||||||
strikeout: 'Tachado',
|
strikeout: 'Tachado',
|
||||||
draw_strikethrough_the_document: 'Desenhe uma linha de tachado no documento',
|
draw_strikethrough_the_document: 'Desenhe uma linha de tachado no documento',
|
||||||
@@ -719,10 +732,14 @@ const pt = {
|
|||||||
and: 'e',
|
and: 'e',
|
||||||
or: 'ou',
|
or: 'ou',
|
||||||
start_a_quick_tour_to_learn_how_to_create_an_send_your_first_document: 'Comece um tour rápido para aprender a criar e enviar seu primeiro documento.',
|
start_a_quick_tour_to_learn_how_to_create_an_send_your_first_document: 'Comece um tour rápido para aprender a criar e enviar seu primeiro documento.',
|
||||||
start_tour: 'Iniciar tour'
|
start_tour: 'Iniciar tour',
|
||||||
|
or_add_from: 'Ou adicionar de',
|
||||||
|
sync: 'Sincronizar',
|
||||||
|
syncing: 'Sincronizando...'
|
||||||
}
|
}
|
||||||
|
|
||||||
const fr = {
|
const fr = {
|
||||||
|
view: 'Vue',
|
||||||
payment_link: 'Lien de paiement',
|
payment_link: 'Lien de paiement',
|
||||||
strikeout: 'Barrer',
|
strikeout: 'Barrer',
|
||||||
draw_strikethrough_the_document: 'Tracer une ligne de suppression sur le document',
|
draw_strikethrough_the_document: 'Tracer une ligne de suppression sur le document',
|
||||||
@@ -900,10 +917,14 @@ const fr = {
|
|||||||
and: 'et',
|
and: 'et',
|
||||||
or: 'ou',
|
or: 'ou',
|
||||||
start_a_quick_tour_to_learn_how_to_create_an_send_your_first_document: 'Lancez une visite rapide pour apprendre à créer et envoyer votre premier document.',
|
start_a_quick_tour_to_learn_how_to_create_an_send_your_first_document: 'Lancez une visite rapide pour apprendre à créer et envoyer votre premier document.',
|
||||||
start_tour: 'Démarrer'
|
start_tour: 'Démarrer',
|
||||||
|
or_add_from: 'Ou ajouter depuis',
|
||||||
|
sync: 'Synchroniser',
|
||||||
|
syncing: 'Synchronisation...'
|
||||||
}
|
}
|
||||||
|
|
||||||
const de = {
|
const de = {
|
||||||
|
view: 'Ansicht',
|
||||||
payment_link: 'Zahlungslink',
|
payment_link: 'Zahlungslink',
|
||||||
strikeout: 'Streichung',
|
strikeout: 'Streichung',
|
||||||
draw_strikethrough_the_document: 'Ziehe eine Streichung auf das Dokument',
|
draw_strikethrough_the_document: 'Ziehe eine Streichung auf das Dokument',
|
||||||
@@ -1081,10 +1102,14 @@ const de = {
|
|||||||
and: 'und',
|
and: 'und',
|
||||||
or: 'oder',
|
or: 'oder',
|
||||||
start_a_quick_tour_to_learn_how_to_create_an_send_your_first_document: 'Starte eine kurze Tour, um zu lernen, wie du dein erstes Dokument erstellst und versendest.',
|
start_a_quick_tour_to_learn_how_to_create_an_send_your_first_document: 'Starte eine kurze Tour, um zu lernen, wie du dein erstes Dokument erstellst und versendest.',
|
||||||
start_tour: 'Starten'
|
start_tour: 'Starten',
|
||||||
|
or_add_from: 'Oder hinzufügen von',
|
||||||
|
sync: 'Synchronisieren',
|
||||||
|
syncing: 'Synchronisierung...'
|
||||||
}
|
}
|
||||||
|
|
||||||
const nl = {
|
const nl = {
|
||||||
|
view: 'Bekijken',
|
||||||
payment_link: 'Betaallink',
|
payment_link: 'Betaallink',
|
||||||
strikeout: 'Doorhalen',
|
strikeout: 'Doorhalen',
|
||||||
draw_strikethrough_the_document: 'Teken doorhaling in het document',
|
draw_strikethrough_the_document: 'Teken doorhaling in het document',
|
||||||
@@ -1262,7 +1287,10 @@ const nl = {
|
|||||||
and: 'en',
|
and: 'en',
|
||||||
or: 'of',
|
or: 'of',
|
||||||
start_a_quick_tour_to_learn_how_to_create_an_send_your_first_document: 'Start een korte rondleiding om te leren hoe u uw eerste document maakt en verzendt',
|
start_a_quick_tour_to_learn_how_to_create_an_send_your_first_document: 'Start een korte rondleiding om te leren hoe u uw eerste document maakt en verzendt',
|
||||||
start_tour: 'Rondleiding starten'
|
start_tour: 'Rondleiding starten',
|
||||||
|
or_add_from: 'Of toevoegen van',
|
||||||
|
sync: 'Synchroniseren',
|
||||||
|
syncing: 'Synchroniseren...'
|
||||||
}
|
}
|
||||||
|
|
||||||
export { en, es, it, pt, fr, de, nl }
|
export { en, es, it, pt, fr, de, nl }
|
||||||
|
|||||||
@@ -94,12 +94,19 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex pb-2 pt-1.5 document-preview-name">
|
<div class="flex items-center gap-1 pb-2 pt-1.5 document-preview-name">
|
||||||
|
<GoogleDriveDocumentSettings
|
||||||
|
v-if="item.google_drive_file_id"
|
||||||
|
:template-id="template.id"
|
||||||
|
:google-drive-file-id="item.google_drive_file_id"
|
||||||
|
@success="$emit('replace', { replaceSchemaItem: item, ...$event })"
|
||||||
|
/>
|
||||||
<Contenteditable
|
<Contenteditable
|
||||||
:model-value="item.name"
|
:model-value="item.name"
|
||||||
:icon-width="16"
|
:icon-width="16"
|
||||||
|
:icon-inline="true"
|
||||||
|
:hide-icon="false"
|
||||||
:editable="editable"
|
:editable="editable"
|
||||||
style="max-width: 95%"
|
|
||||||
class="mx-auto"
|
class="mx-auto"
|
||||||
@update:model-value="onUpdateName"
|
@update:model-value="onUpdateName"
|
||||||
/>
|
/>
|
||||||
@@ -123,6 +130,7 @@ import Upload from './upload'
|
|||||||
import { IconRouteAltLeft, IconSortDescending2 } from '@tabler/icons-vue'
|
import { IconRouteAltLeft, IconSortDescending2 } from '@tabler/icons-vue'
|
||||||
import ConditionsModal from './conditions_modal'
|
import ConditionsModal from './conditions_modal'
|
||||||
import ReplaceButton from './replace'
|
import ReplaceButton from './replace'
|
||||||
|
import GoogleDriveDocumentSettings from './google_drive_document_settings'
|
||||||
import Field from './field'
|
import Field from './field'
|
||||||
import FieldType from './field_type'
|
import FieldType from './field_type'
|
||||||
|
|
||||||
@@ -133,6 +141,7 @@ export default {
|
|||||||
IconRouteAltLeft,
|
IconRouteAltLeft,
|
||||||
ConditionsModal,
|
ConditionsModal,
|
||||||
ReplaceButton,
|
ReplaceButton,
|
||||||
|
GoogleDriveDocumentSettings,
|
||||||
IconSortDescending2
|
IconSortDescending2
|
||||||
},
|
},
|
||||||
inject: ['t'],
|
inject: ['t'],
|
||||||
|
|||||||
@@ -3,29 +3,155 @@
|
|||||||
<label
|
<label
|
||||||
id="add_document_button"
|
id="add_document_button"
|
||||||
:for="inputId"
|
:for="inputId"
|
||||||
class="btn btn-outline w-full add-document-button"
|
class="btn btn-outline w-full add-document-button px-0"
|
||||||
:class="{ 'btn-disabled': isLoading }"
|
:class="{ 'btn-disabled': isLoading }"
|
||||||
>
|
>
|
||||||
<IconInnerShadowTop
|
<div
|
||||||
v-if="isLoading"
|
class="flex items-center justify-between w-full h-full"
|
||||||
width="20"
|
>
|
||||||
class="animate-spin"
|
<span
|
||||||
/>
|
class="flex items-center space-x-2 w-full justify-center"
|
||||||
<IconUpload
|
:class="{ 'pl-3': withGoogleDrive }"
|
||||||
v-else
|
>
|
||||||
width="20"
|
<IconInnerShadowTop
|
||||||
/>
|
v-if="isLoading"
|
||||||
<span v-if="isLoading">
|
width="20"
|
||||||
{{ t('uploading_') }}
|
class="animate-spin"
|
||||||
</span>
|
/>
|
||||||
<span v-else>
|
<IconUpload
|
||||||
{{ t('add_document') }}
|
v-else
|
||||||
</span>
|
width="20"
|
||||||
|
/>
|
||||||
|
<span v-if="isLoading">
|
||||||
|
{{ t('uploading_') }}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
v-else
|
||||||
|
class="mr-1 whitespace-nowrap truncate"
|
||||||
|
>
|
||||||
|
{{ t('add_document') }}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
v-if="withGoogleDrive"
|
||||||
|
class="dropdown dropdown-end dropdown-top inline h-full"
|
||||||
|
style="width: 33px"
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
tabindex="0"
|
||||||
|
class="flex items-center h-full cursor-pointer"
|
||||||
|
>
|
||||||
|
<IconChevronDown class="w-5 h-5 flex-shrink-0" />
|
||||||
|
</label>
|
||||||
|
<ul
|
||||||
|
tabindex="0"
|
||||||
|
:style="{ backgroundColor }"
|
||||||
|
class="dropdown-content p-2 mt-2 shadow menu text-base mb-1 rounded-box text-right !text-base-content"
|
||||||
|
>
|
||||||
|
<li>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
@click="openGoogleDriveModal"
|
||||||
|
>
|
||||||
|
<IconBrandGoogleDrive class="w-5 h-5 flex-shrink-0" />
|
||||||
|
<span class="whitespace-nowrap text-sm normal-case font-medium">Google Drive</span>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</label>
|
</label>
|
||||||
|
<Teleport
|
||||||
|
v-if="showGoogleDriveModal"
|
||||||
|
:to="modalContainerEl"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="modal modal-open items-start !animate-none overflow-y-auto"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="absolute top-0 bottom-0 right-0 left-0"
|
||||||
|
@click.prevent="showGoogleDriveModal = false"
|
||||||
|
/>
|
||||||
|
<div class="modal-box pt-4 pb-6 px-6 mt-20 max-h-none w-full max-w-xl">
|
||||||
|
<div class="flex justify-between items-center border-b pb-2 mb-2 font-medium">
|
||||||
|
<span class="modal-title">
|
||||||
|
Google Drive
|
||||||
|
</span>
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
class="text-xl modal-close-button"
|
||||||
|
@click.prevent="showGoogleDriveModal = false"
|
||||||
|
>×</a>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<form
|
||||||
|
v-if="showGoogleDriveOauthButton"
|
||||||
|
method="post"
|
||||||
|
:action="googleDriveOauthPath"
|
||||||
|
@submit="isConnectGoogleDriveClicked = true"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="hidden"
|
||||||
|
name="authenticity_token"
|
||||||
|
:value="authenticityToken"
|
||||||
|
autocomplete="off"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
id="gdrive_oauth_button"
|
||||||
|
class="btn bg-white btn-outline w-full text-base font-medium mt-4"
|
||||||
|
data-turbo="false"
|
||||||
|
type="submit"
|
||||||
|
:disabled="isConnectGoogleDriveClicked"
|
||||||
|
>
|
||||||
|
<span v-if="isConnectGoogleDriveClicked">
|
||||||
|
<span class="flex items-center justify-center space-x-2">
|
||||||
|
<IconInnerShadowTop class="animate-spin" />
|
||||||
|
<span class="">Submitting...</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
v-else
|
||||||
|
>
|
||||||
|
<span class="flex items-center justify-center space-x-2">
|
||||||
|
<IconBrandGoogleDrive />
|
||||||
|
<span>Connect Google Drive</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
class="relative"
|
||||||
|
>
|
||||||
|
<iframe
|
||||||
|
class="border border-base-300 rounded-lg"
|
||||||
|
style="width: 100%; height: 440px; background: white;"
|
||||||
|
src="/template_google_drive"
|
||||||
|
/>
|
||||||
|
<div v-if="isLoadingGoogleDrive">
|
||||||
|
<div
|
||||||
|
class="bg-white absolute top-0 bottom-0 left-0 right-0 opacity-80 rounded-lg"
|
||||||
|
style="margin: 1px"
|
||||||
|
/>
|
||||||
|
<div class="absolute top-0 bottom-0 left-0 right-0 flex items-center justify-center">
|
||||||
|
<IconInnerShadowTop class="animate-spin" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Teleport>
|
||||||
<form
|
<form
|
||||||
ref="form"
|
ref="form"
|
||||||
class="hidden"
|
class="hidden"
|
||||||
>
|
>
|
||||||
|
<input
|
||||||
|
v-for="file in googleDriveFiles"
|
||||||
|
:key="file.id"
|
||||||
|
name="google_drive_file_ids[]"
|
||||||
|
:value="file.id"
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
:id="inputId"
|
:id="inputId"
|
||||||
ref="input"
|
ref="input"
|
||||||
@@ -40,20 +166,32 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { IconUpload, IconInnerShadowTop } from '@tabler/icons-vue'
|
import { IconUpload, IconInnerShadowTop, IconChevronDown, IconBrandGoogleDrive } from '@tabler/icons-vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'DocumentsUpload',
|
name: 'DocumentsUpload',
|
||||||
components: {
|
components: {
|
||||||
IconUpload,
|
IconUpload,
|
||||||
IconInnerShadowTop
|
IconInnerShadowTop,
|
||||||
|
IconChevronDown,
|
||||||
|
IconBrandGoogleDrive
|
||||||
},
|
},
|
||||||
inject: ['baseFetch', 't'],
|
inject: ['baseFetch', 't', 'backgroundColor'],
|
||||||
props: {
|
props: {
|
||||||
templateId: {
|
templateId: {
|
||||||
type: [Number, String],
|
type: [Number, String],
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
authenticityToken: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
withGoogleDrive: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
acceptFileTypes: {
|
acceptFileTypes: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
@@ -63,22 +201,85 @@ export default {
|
|||||||
emits: ['success', 'error'],
|
emits: ['success', 'error'],
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
isLoading: false
|
isLoading: false,
|
||||||
|
isConnectGoogleDriveClicked: false,
|
||||||
|
isLoadingGoogleDrive: false,
|
||||||
|
googleDriveFiles: [],
|
||||||
|
showGoogleDriveModal: false,
|
||||||
|
showGoogleDriveOauthButton: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
inputId () {
|
inputId () {
|
||||||
return 'el' + Math.random().toString(32).split('.')[1]
|
return 'el' + Math.random().toString(32).split('.')[1]
|
||||||
},
|
},
|
||||||
uploadUrl () {
|
queryParams () {
|
||||||
return `/templates/${this.templateId}/documents`
|
return new URLSearchParams(window.location.search)
|
||||||
|
},
|
||||||
|
googleDriveOauthPath () {
|
||||||
|
const params = {
|
||||||
|
access_type: 'offline',
|
||||||
|
include_granted_scopes: 'true',
|
||||||
|
prompt: 'consent',
|
||||||
|
scope: [
|
||||||
|
'https://www.googleapis.com/auth/userinfo.email',
|
||||||
|
'https://www.googleapis.com/auth/drive.file'
|
||||||
|
].join(' '),
|
||||||
|
state: new URLSearchParams({
|
||||||
|
redir: `/templates/${this.templateId}/edit?google_drive_open=1`
|
||||||
|
}).toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = new URLSearchParams(params).toString()
|
||||||
|
|
||||||
|
return `/auth/google_oauth2?${query}`
|
||||||
|
},
|
||||||
|
modalContainerEl () {
|
||||||
|
return this.$el.getRootNode().querySelector('#docuseal_modal_container')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
mounted () {
|
||||||
|
window.addEventListener('message', this.messageHandler)
|
||||||
|
|
||||||
|
if (this.queryParams.get('google_drive_open') === '1') {
|
||||||
|
this.openGoogleDriveModal()
|
||||||
|
|
||||||
|
window.history.replaceState({}, document.title, window.location.pathname)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeUnmount () {
|
||||||
|
window.removeEventListener('message', this.messageHandler)
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async upload () {
|
openGoogleDriveModal () {
|
||||||
|
this.showGoogleDriveModal = true
|
||||||
|
this.isLoadingGoogleDrive = true
|
||||||
|
},
|
||||||
|
messageHandler (event) {
|
||||||
|
if (event.data.type === 'google-drive-files-picked') {
|
||||||
|
this.googleDriveFiles = event.data.files || []
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.isLoadingGoogleDrive = true
|
||||||
|
|
||||||
|
this.upload({ path: `/templates/${this.templateId}/google_drive_documents` }).then((resp) => {
|
||||||
|
if (resp.ok) {
|
||||||
|
this.showGoogleDriveModal = false
|
||||||
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
this.isLoadingGoogleDrive = false
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else if (event.data.type === 'google-drive-picker-loaded') {
|
||||||
|
this.isLoadingGoogleDrive = false
|
||||||
|
} else if (event.data.type === 'google-drive-picker-request-oauth') {
|
||||||
|
this.showGoogleDriveOauthButton = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async upload ({ path } = {}) {
|
||||||
this.isLoading = true
|
this.isLoading = true
|
||||||
|
|
||||||
this.baseFetch(this.uploadUrl, {
|
return this.baseFetch(path || `/templates/${this.templateId}/documents`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Accept: 'application/json' },
|
headers: { Accept: 'application/json' },
|
||||||
body: new FormData(this.$refs.form)
|
body: new FormData(this.$refs.form)
|
||||||
@@ -111,6 +312,10 @@ export default {
|
|||||||
this.isLoading = false
|
this.isLoading = false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
} else if (data.status === 'google_drive_file_missing') {
|
||||||
|
alert(data.error)
|
||||||
|
this.$emit('error', data.error)
|
||||||
|
this.isLoading = false
|
||||||
} else {
|
} else {
|
||||||
this.$emit('error', data.error)
|
this.$emit('error', data.error)
|
||||||
this.isLoading = false
|
this.isLoading = false
|
||||||
@@ -122,6 +327,8 @@ export default {
|
|||||||
this.isLoading = false
|
this.isLoading = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return resp
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
this.isLoading = false
|
this.isLoading = false
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
<svg class="<%= local_assigns[:class] %>" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-brand-google-drive"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M12 10l-6 10l-3 -5l6 -10z" /><path d="M9 15h12l-3 5h-12" /><path d="M15 15l-6 -10h6l6 10z" /></svg>
|
||||||
|
After Width: | Height: | Size: 458 B |
@@ -19,6 +19,12 @@
|
|||||||
<%= stylesheet_pack_tag 'application', media: 'all' %>
|
<%= stylesheet_pack_tag 'application', media: 'all' %>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<% if params[:modal].present? %>
|
||||||
|
<% url_params = Rails.application.routes.recognize_path(params[:modal], method: :get) %>
|
||||||
|
<% if url_params[:action] == 'new' %>
|
||||||
|
<open-modal src="<%= params[:modal] %>"></open-modal>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
<turbo-frame id="modal"></turbo-frame>
|
<turbo-frame id="modal"></turbo-frame>
|
||||||
<turbo-frame id="drawer"></turbo-frame>
|
<turbo-frame id="drawer"></turbo-frame>
|
||||||
<%= render 'shared/navbar' %>
|
<%= render 'shared/navbar' %>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<%= svg_icon('cloud_upload', class: 'w-9 h-9') %>
|
<%= svg_icon('cloud_upload', class: 'w-9 h-9') %>
|
||||||
</span>
|
</span>
|
||||||
<div class="font-medium mb-1">
|
<div class="font-medium mb-1">
|
||||||
<%= t('upload_new_document') %>
|
<%= t('upload_a_new_document') %>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
<span class="flex flex-col items-center hidden" data-target="dashboard-dropzone.fileDropzoneLoading">
|
<span class="flex flex-col items-center hidden" data-target="dashboard-dropzone.fileDropzoneLoading">
|
||||||
|
|||||||
@@ -5,16 +5,23 @@
|
|||||||
<label for="file_dropzone_input" class="w-full block h-52 relative hover:bg-base-200/30 rounded-xl border-2 border-base-300 border-dashed" data-target="file-dropzone.area">
|
<label for="file_dropzone_input" class="w-full block h-52 relative hover:bg-base-200/30 rounded-xl border-2 border-base-300 border-dashed" data-target="file-dropzone.area">
|
||||||
<div class="absolute top-0 right-0 left-0 bottom-0 flex items-center justify-center p-2 pointer-events-none">
|
<div class="absolute top-0 right-0 left-0 bottom-0 flex items-center justify-center p-2 pointer-events-none">
|
||||||
<div class="flex flex-col items-center text-center">
|
<div class="flex flex-col items-center text-center">
|
||||||
<span data-target="file-dropzone.icon" class="flex flex-col items-center">
|
<span data-target="file-dropzone.icon" class="flex flex-col items-center <%= 'mb-5' if Docuseal.multitenant? %>">
|
||||||
<span>
|
<span>
|
||||||
<%= svg_icon('cloud_upload', class: 'w-10 h-10') %>
|
<%= svg_icon('cloud_upload', class: 'w-10 h-10') %>
|
||||||
</span>
|
</span>
|
||||||
<div class="font-medium mb-1">
|
<div class="font-medium mb-1">
|
||||||
<%= t('upload_new_document') %>
|
<%= t('upload_a_new_document') %>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-xs">
|
<div class="text-sm">
|
||||||
<%= t('click_to_upload_or_drag_and_drop_html') %>
|
<%= t('click_to_upload_or_drag_and_drop_html') %>
|
||||||
</div>
|
</div>
|
||||||
|
<% if Docuseal.multitenant? %>
|
||||||
|
<a class="flex absolute bottom-4 items-center text-sm mt-2 pointer-events-auto" href="<%= new_template_path(modal_tab: 'google_drive') %>" data-turbo-frame="modal">
|
||||||
|
<span><%= t('or_add_from') %></span>
|
||||||
|
<%= svg_icon('brand_gdrive', class: 'w-4 h-4 ml-1') %>
|
||||||
|
<span class="ml-1 font-medium hover:underline">Google Drive</span>
|
||||||
|
</a>
|
||||||
|
<% end %>
|
||||||
</span>
|
</span>
|
||||||
<span data-target="file-dropzone.loading" class="flex flex-col items-center hidden">
|
<span data-target="file-dropzone.loading" class="flex flex-col items-center hidden">
|
||||||
<%= svg_icon('loader', class: 'w-10 h-10 animate-spin') %>
|
<%= svg_icon('loader', class: 'w-10 h-10 animate-spin') %>
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<%= form_for @template, data: { turbo_frame: :_top }, html: { autocomplete: :off } do |f| %>
|
||||||
|
<% if @base_template %>
|
||||||
|
<%= hidden_field_tag :base_template_id, @base_template.id %>
|
||||||
|
<% end %>
|
||||||
|
<% if @base_template && (can?(:manage, :tenants) || true_user != current_user) && true_user.account.linked_accounts.active.accessible_by(current_ability).exists? %>
|
||||||
|
<div class="form-control -mb-2 mt-2">
|
||||||
|
<%= select_tag :account_id, options_for_select([true_user.account, *true_user.account.linked_accounts.active.accessible_by(current_ability)].uniq.map { |e| [e.name, e.id] }, current_account.id), required: true, class: 'base-select' %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<div class="form-control mt-4">
|
||||||
|
<%= f.text_field :name, required: true, placeholder: t('document_name'), class: 'base-input', dir: 'auto' %>
|
||||||
|
</div>
|
||||||
|
<div class="mt-3 mb-4 flex items-center justify-between">
|
||||||
|
<label for="folder_name" class="cursor-pointer">
|
||||||
|
<%= svg_icon('folder', class: 'w-6 h-6') %>
|
||||||
|
</label>
|
||||||
|
<folder-autocomplete class="flex justify-between w-full">
|
||||||
|
<set-value data-on="blur" data-value="<%= TemplateFolder::DEFAULT_NAME %>" data-empty-only="true" class="peer w-full whitespace-nowrap">
|
||||||
|
<input id="folder_name" placeholder="<%= t('folder_name') %>" type="text" class="w-full outline-none border-transparent focus:border-transparent focus:ring-0 bg-base-100 px-1" name="folder_name" value="<%= params[:folder_name].presence || @base_template&.folder&.full_name || TemplateFolder::DEFAULT_NAME %>" autocomplete="off">
|
||||||
|
</set-value>
|
||||||
|
<set-value data-on="click" data-value="" data-input-id="folder_name" class="peer-focus-within:hidden whitespace-nowrap">
|
||||||
|
<label for="folder_name" data-clear-on-focus="true" class="shrink-0 link mr-1.5 cursor-pointer">
|
||||||
|
<%= t('change_folder') %>
|
||||||
|
</label>
|
||||||
|
</set-value>
|
||||||
|
</folder-autocomplete>
|
||||||
|
</div>
|
||||||
|
<div class="form-control">
|
||||||
|
<%= f.button button_title(title: @base_template ? t('submit') : t('create'), disabled_with: t('creating')), class: 'base-button' %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
@@ -1,33 +1,3 @@
|
|||||||
<%= render 'shared/turbo_modal', title: @base_template ? t('clone_template') : t('new_document_template') do %>
|
<%= render 'shared/turbo_modal', title: @base_template ? t('clone_template') : t('new_document_template') do %>
|
||||||
<%= form_for @template, data: { turbo_frame: :_top }, html: { autocomplete: :off } do |f| %>
|
<%= render 'templates/file_form' %>
|
||||||
<% if @base_template %>
|
|
||||||
<%= hidden_field_tag :base_template_id, @base_template.id %>
|
|
||||||
<% end %>
|
|
||||||
<% if @base_template && (can?(:manage, :tenants) || true_user != current_user) && true_user.account.linked_accounts.active.accessible_by(current_ability).exists? %>
|
|
||||||
<div class="form-control -mb-2 mt-2">
|
|
||||||
<%= select_tag :account_id, options_for_select([true_user.account, *true_user.account.linked_accounts.active.accessible_by(current_ability)].uniq.map { |e| [e.name, e.id] }, current_account.id), required: true, class: 'base-select' %>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
<div class="form-control mt-6">
|
|
||||||
<%= f.text_field :name, required: true, placeholder: t('document_name'), class: 'base-input', dir: 'auto' %>
|
|
||||||
</div>
|
|
||||||
<div class="mt-3 mb-4 flex items-center justify-between">
|
|
||||||
<label for="folder_name" class="cursor-pointer">
|
|
||||||
<%= svg_icon('folder', class: 'w-6 h-6') %>
|
|
||||||
</label>
|
|
||||||
<folder-autocomplete class="flex justify-between w-full">
|
|
||||||
<set-value data-on="blur" data-value="<%= TemplateFolder::DEFAULT_NAME %>" data-empty-only="true" class="peer w-full whitespace-nowrap">
|
|
||||||
<input id="folder_name" placeholder="<%= t('folder_name') %>" type="text" class="w-full outline-none border-transparent focus:border-transparent focus:ring-0 bg-base-100 px-1" name="folder_name" value="<%= params[:folder_name].presence || @base_template&.folder&.full_name || TemplateFolder::DEFAULT_NAME %>" autocomplete="off">
|
|
||||||
</set-value>
|
|
||||||
<set-value data-on="click" data-value="" data-input-id="folder_name" class="peer-focus-within:hidden whitespace-nowrap">
|
|
||||||
<label for="folder_name" data-clear-on-focus="true" class="shrink-0 link mr-1.5 cursor-pointer">
|
|
||||||
<%= t('change_folder') %>
|
|
||||||
</label>
|
|
||||||
</set-value>
|
|
||||||
</folder-autocomplete>
|
|
||||||
</div>
|
|
||||||
<div class="form-control">
|
|
||||||
<%= f.button button_title(title: @base_template ? t('submit') : t('create'), disabled_with: t('creating')), class: 'base-button' %>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|||||||
+56
-7
@@ -20,6 +20,9 @@ en: &en
|
|||||||
language_ar: العربية
|
language_ar: العربية
|
||||||
language_ko: 한국어
|
language_ko: 한국어
|
||||||
language_ja: 日本語
|
language_ja: 日本語
|
||||||
|
add_from_google_drive: Add from Google Drive
|
||||||
|
or_add_from: Or add from
|
||||||
|
upload_a_new_document: Upload a New Document
|
||||||
hi_there: Hi there
|
hi_there: Hi there
|
||||||
pro: Pro
|
pro: Pro
|
||||||
thanks: Thanks
|
thanks: Thanks
|
||||||
@@ -240,7 +243,7 @@ en: &en
|
|||||||
upload_signed_pdf_file_to_validate_its_signature_: 'Upload signed PDF file to validate its signature:'
|
upload_signed_pdf_file_to_validate_its_signature_: 'Upload signed PDF file to validate its signature:'
|
||||||
analyzing: Analyzing
|
analyzing: Analyzing
|
||||||
verify_signed_pdf: Verify Signed PDF
|
verify_signed_pdf: Verify Signed PDF
|
||||||
click_to_upload_or_drag_and_drop_html: '<span class="font-medium">Click to upload</span> or drag and drop'
|
click_to_upload_or_drag_and_drop_html: 'Click to upload or drag and drop'
|
||||||
click_to_upload_or_drag_and_drop_files_html: '<span class="font-medium">Click to upload</span> or drag and drop files'
|
click_to_upload_or_drag_and_drop_files_html: '<span class="font-medium">Click to upload</span> or drag and drop files'
|
||||||
signing_certificates: Signing Certificates
|
signing_certificates: Signing Certificates
|
||||||
upload_cert: Upload Cert
|
upload_cert: Upload Cert
|
||||||
@@ -830,6 +833,10 @@ en: &en
|
|||||||
require_a_jwt_authorization_to_preview_embedded_forms_ensuring_only_authorized_users_can_view_them: Require a JWT authorization to preview embedded forms, ensuring only authorized users can view them.
|
require_a_jwt_authorization_to_preview_embedded_forms_ensuring_only_authorized_users_can_view_them: Require a JWT authorization to preview embedded forms, ensuring only authorized users can view them.
|
||||||
make_all_newly_created_templates_private_to_their_creator_by_default: Make all newly created templates private to their creator by default.
|
make_all_newly_created_templates_private_to_their_creator_by_default: Make all newly created templates private to their creator by default.
|
||||||
make_the_recipients_signing_order_always_enforced_so_that_the_second_signer_can_start_signing_their_part_only_after_the_first_signer_has_completed_signing: Make the recipients signing order always enforced, so that the second signer can start signing their part only after the first signer has completed signing.
|
make_the_recipients_signing_order_always_enforced_so_that_the_second_signer_can_start_signing_their_part_only_after_the_first_signer_has_completed_signing: Make the recipients signing order always enforced, so that the second signer can start signing their part only after the first signer has completed signing.
|
||||||
|
the_file_is_missing_make_sure_you_have_access_to_it_on_google_drive: The file is missing. Make sure you have access to it on Google Drive.
|
||||||
|
connect_google_drive: Connect Google Drive
|
||||||
|
google_drive_has_been_connected: Google Drive has been connected
|
||||||
|
unable_to_identify_reset_your_password_to_sign_in: Unable to identify. Reset your password to sign in.
|
||||||
submission_sources:
|
submission_sources:
|
||||||
api: API
|
api: API
|
||||||
bulk: Bulk Send
|
bulk: Bulk Send
|
||||||
@@ -936,6 +943,9 @@ en: &en
|
|||||||
range_without_total: "%{from}-%{to} events"
|
range_without_total: "%{from}-%{to} events"
|
||||||
|
|
||||||
es: &es
|
es: &es
|
||||||
|
add_from_google_drive: Agregar desde Google Drive
|
||||||
|
or_add_from: O agregar desde
|
||||||
|
upload_a_new_document: Subir nuevo documento
|
||||||
use_direct_file_attachment_links_in_the_documents: Usar enlaces directos de archivos adjuntos en los documentos
|
use_direct_file_attachment_links_in_the_documents: Usar enlaces directos de archivos adjuntos en los documentos
|
||||||
enabled: Habilitado
|
enabled: Habilitado
|
||||||
disabled: Deshabilitado
|
disabled: Deshabilitado
|
||||||
@@ -1155,7 +1165,7 @@ es: &es
|
|||||||
upload_signed_pdf_file_to_validate_its_signature_: 'Sube el archivo PDF firmado para validar su firma:'
|
upload_signed_pdf_file_to_validate_its_signature_: 'Sube el archivo PDF firmado para validar su firma:'
|
||||||
analyzing: Analizando
|
analyzing: Analizando
|
||||||
verify_signed_pdf: Verificar PDF firmado
|
verify_signed_pdf: Verificar PDF firmado
|
||||||
click_to_upload_or_drag_and_drop_html: '<span class="font-medium">Haz clic para subir</span> o arrastra y suelta'
|
click_to_upload_or_drag_and_drop_html: 'Haz clic para subir o arrastra y suelta'
|
||||||
click_to_upload_or_drag_and_drop_files_html: '<span class="font-medium">Haz clic para subir</span> o arrastra y suelta archivos'
|
click_to_upload_or_drag_and_drop_files_html: '<span class="font-medium">Haz clic para subir</span> o arrastra y suelta archivos'
|
||||||
signing_certificates: Certificados de firma
|
signing_certificates: Certificados de firma
|
||||||
upload_cert: Subir certificado
|
upload_cert: Subir certificado
|
||||||
@@ -1744,6 +1754,10 @@ es: &es
|
|||||||
require_a_jwt_authorization_to_preview_embedded_forms_ensuring_only_authorized_users_can_view_them: Requerir autorización JWT para previsualizar formularios incrustados, garantizando que solo los usuarios autorizados puedan verlos.
|
require_a_jwt_authorization_to_preview_embedded_forms_ensuring_only_authorized_users_can_view_them: Requerir autorización JWT para previsualizar formularios incrustados, garantizando que solo los usuarios autorizados puedan verlos.
|
||||||
make_all_newly_created_templates_private_to_their_creator_by_default: Hacer que todas las plantillas creadas sean privadas para su creador por defecto.
|
make_all_newly_created_templates_private_to_their_creator_by_default: Hacer que todas las plantillas creadas sean privadas para su creador por defecto.
|
||||||
make_the_recipients_signing_order_always_enforced_so_that_the_second_signer_can_start_signing_their_part_only_after_the_first_signer_has_completed_signing: Hacer que el orden de firma de los destinatarios se aplique siempre, de modo que el segundo firmante pueda comenzar a firmar solo después de que el primero haya completado la firma.
|
make_the_recipients_signing_order_always_enforced_so_that_the_second_signer_can_start_signing_their_part_only_after_the_first_signer_has_completed_signing: Hacer que el orden de firma de los destinatarios se aplique siempre, de modo que el segundo firmante pueda comenzar a firmar solo después de que el primero haya completado la firma.
|
||||||
|
the_file_is_missing_make_sure_you_have_access_to_it_on_google_drive: El archivo falta. Asegúrate de tener acceso a él en Google Drive.
|
||||||
|
connect_google_drive: Conectar Google Drive
|
||||||
|
google_drive_has_been_connected: Google Drive se ha conectado
|
||||||
|
unable_to_identify_reset_your_password_to_sign_in: No se pudo identificar. Restablece tu contraseña para iniciar sesión.
|
||||||
submission_sources:
|
submission_sources:
|
||||||
api: API
|
api: API
|
||||||
bulk: Envío masivo
|
bulk: Envío masivo
|
||||||
@@ -1850,6 +1864,9 @@ es: &es
|
|||||||
range_without_total: "%{from}-%{to} eventos"
|
range_without_total: "%{from}-%{to} eventos"
|
||||||
|
|
||||||
it: &it
|
it: &it
|
||||||
|
add_from_google_drive: Aggiungi da Google Drive
|
||||||
|
or_add_from: Oppure aggiungi da
|
||||||
|
upload_a_new_document: Carica nuovo documento
|
||||||
use_direct_file_attachment_links_in_the_documents: Usa i link diretti per gli allegati nei documenti
|
use_direct_file_attachment_links_in_the_documents: Usa i link diretti per gli allegati nei documenti
|
||||||
click_here_to_send_a_reset_password_email_html: '<label class="link" for="resend_password_button">Clicca qui</label> per inviare una email per reimpostare la password.'
|
click_here_to_send_a_reset_password_email_html: '<label class="link" for="resend_password_button">Clicca qui</label> per inviare una email per reimpostare la password.'
|
||||||
enabled: Abilitato
|
enabled: Abilitato
|
||||||
@@ -2069,7 +2086,7 @@ it: &it
|
|||||||
upload_signed_pdf_file_to_validate_its_signature_: 'Carica il file PDF firmato per validarne la firma:'
|
upload_signed_pdf_file_to_validate_its_signature_: 'Carica il file PDF firmato per validarne la firma:'
|
||||||
analyzing: Analisi in corso
|
analyzing: Analisi in corso
|
||||||
verify_signed_pdf: Verifica PDF firmato
|
verify_signed_pdf: Verifica PDF firmato
|
||||||
click_to_upload_or_drag_and_drop_html: '<span class="font-medium">Clicca per caricare</span> o trascina e rilascia'
|
click_to_upload_or_drag_and_drop_html: 'Clicca per caricare o trascina e rilascia'
|
||||||
click_to_upload_or_drag_and_drop_files_html: '<span class="font-medium">Clicca per caricare</span> o trascina e rilascia i file'
|
click_to_upload_or_drag_and_drop_files_html: '<span class="font-medium">Clicca per caricare</span> o trascina e rilascia i file'
|
||||||
signing_certificates: Certificati di firma
|
signing_certificates: Certificati di firma
|
||||||
upload_cert: Carica certificato
|
upload_cert: Carica certificato
|
||||||
@@ -2659,6 +2676,10 @@ it: &it
|
|||||||
require_a_jwt_authorization_to_preview_embedded_forms_ensuring_only_authorized_users_can_view_them: "Richiedere un'autorizzazione JWT per visualizzare in anteprima i moduli incorporati, garantendo che solo gli utenti autorizzati possano vederli."
|
require_a_jwt_authorization_to_preview_embedded_forms_ensuring_only_authorized_users_can_view_them: "Richiedere un'autorizzazione JWT per visualizzare in anteprima i moduli incorporati, garantendo che solo gli utenti autorizzati possano vederli."
|
||||||
make_all_newly_created_templates_private_to_their_creator_by_default: Rendere tutte le nuove template private per il creatore per impostazione predefinita.
|
make_all_newly_created_templates_private_to_their_creator_by_default: Rendere tutte le nuove template private per il creatore per impostazione predefinita.
|
||||||
make_the_recipients_signing_order_always_enforced_so_that_the_second_signer_can_start_signing_their_part_only_after_the_first_signer_has_completed_signing: "Rendere sempre obbligatorio l'ordine di firma dei destinatari, in modo che il secondo firmatario possa iniziare solo dopo che il primo ha completato la firma."
|
make_the_recipients_signing_order_always_enforced_so_that_the_second_signer_can_start_signing_their_part_only_after_the_first_signer_has_completed_signing: "Rendere sempre obbligatorio l'ordine di firma dei destinatari, in modo che il secondo firmatario possa iniziare solo dopo che il primo ha completato la firma."
|
||||||
|
the_file_is_missing_make_sure_you_have_access_to_it_on_google_drive: Il file è mancante. Assicurati di avere accesso a esso su Google Drive.
|
||||||
|
connect_google_drive: Connetti Google Drive
|
||||||
|
google_drive_has_been_connected: Google Drive è stato connesso
|
||||||
|
unable_to_identify_reset_your_password_to_sign_in: Impossibile identificare. Reimposta la password per accedere.
|
||||||
submission_sources:
|
submission_sources:
|
||||||
api: API
|
api: API
|
||||||
bulk: Invio massivo
|
bulk: Invio massivo
|
||||||
@@ -2765,6 +2786,9 @@ it: &it
|
|||||||
range_without_total: "%{from}-%{to} eventi"
|
range_without_total: "%{from}-%{to} eventi"
|
||||||
|
|
||||||
fr: &fr
|
fr: &fr
|
||||||
|
add_from_google_drive: Ajouter depuis Google Drive
|
||||||
|
or_add_from: Ou ajouter depuis
|
||||||
|
upload_a_new_document: Télécharger un nouveau document
|
||||||
use_direct_file_attachment_links_in_the_documents: Utiliser des liens directs pour les pièces jointes dans les documents
|
use_direct_file_attachment_links_in_the_documents: Utiliser des liens directs pour les pièces jointes dans les documents
|
||||||
click_here_to_send_a_reset_password_email_html: '<label class="link" for="resend_password_button">Cliquez ici</label> pour envoyer un e-mail de réinitialisation du mot de passe.'
|
click_here_to_send_a_reset_password_email_html: '<label class="link" for="resend_password_button">Cliquez ici</label> pour envoyer un e-mail de réinitialisation du mot de passe.'
|
||||||
enabled: Activé
|
enabled: Activé
|
||||||
@@ -2986,7 +3010,7 @@ fr: &fr
|
|||||||
upload_signed_pdf_file_to_validate_its_signature_: 'Téléchargez le fichier PDF signé pour valider sa signature:'
|
upload_signed_pdf_file_to_validate_its_signature_: 'Téléchargez le fichier PDF signé pour valider sa signature:'
|
||||||
analyzing: Analyse en cours
|
analyzing: Analyse en cours
|
||||||
verify_signed_pdf: Vérifier le PDF signé
|
verify_signed_pdf: Vérifier le PDF signé
|
||||||
click_to_upload_or_drag_and_drop_html: '<span class="font-medium">Cliquez pour télécharger</span> ou glissez-déposez'
|
click_to_upload_or_drag_and_drop_html: 'Cliquez pour télécharger ou glissez-déposez'
|
||||||
click_to_upload_or_drag_and_drop_files_html: '<span class="font-medium">Cliquez pour télécharger</span> ou glissez-déposez des fichiers'
|
click_to_upload_or_drag_and_drop_files_html: '<span class="font-medium">Cliquez pour télécharger</span> ou glissez-déposez des fichiers'
|
||||||
signing_certificates: Certificats de signature
|
signing_certificates: Certificats de signature
|
||||||
upload_cert: Télécharger un certificat
|
upload_cert: Télécharger un certificat
|
||||||
@@ -3577,6 +3601,10 @@ fr: &fr
|
|||||||
require_a_jwt_authorization_to_preview_embedded_forms_ensuring_only_authorized_users_can_view_them: Exiger une autorisation JWT pour prévisualiser les formulaires intégrés, garantissant que seuls les utilisateurs autorisés puissent les voir.
|
require_a_jwt_authorization_to_preview_embedded_forms_ensuring_only_authorized_users_can_view_them: Exiger une autorisation JWT pour prévisualiser les formulaires intégrés, garantissant que seuls les utilisateurs autorisés puissent les voir.
|
||||||
make_all_newly_created_templates_private_to_their_creator_by_default: Rendre toutes les nouvelles modèles privées à leur créateur par défaut.
|
make_all_newly_created_templates_private_to_their_creator_by_default: Rendre toutes les nouvelles modèles privées à leur créateur par défaut.
|
||||||
make_the_recipients_signing_order_always_enforced_so_that_the_second_signer_can_start_signing_their_part_only_after_the_first_signer_has_completed_signing: "Rendre l'ordre de signature des destinataires toujours obligatoire, de sorte que le deuxième signataire ne puisse commencer qu'après que le premier a terminé."
|
make_the_recipients_signing_order_always_enforced_so_that_the_second_signer_can_start_signing_their_part_only_after_the_first_signer_has_completed_signing: "Rendre l'ordre de signature des destinataires toujours obligatoire, de sorte que le deuxième signataire ne puisse commencer qu'après que le premier a terminé."
|
||||||
|
the_file_is_missing_make_sure_you_have_access_to_it_on_google_drive: Le fichier est manquant. Assurez-vous d’y avoir accès sur Google Drive.
|
||||||
|
connect_google_drive: Connecter Google Drive
|
||||||
|
google_drive_has_been_connected: Google Drive a été connecté
|
||||||
|
unable_to_identify_reset_your_password_to_sign_in: "Impossible d'identifier. Réinitialisez votre mot de passe pour vous connecter."
|
||||||
submission_sources:
|
submission_sources:
|
||||||
api: API
|
api: API
|
||||||
bulk: Envoi en masse
|
bulk: Envoi en masse
|
||||||
@@ -3683,6 +3711,9 @@ fr: &fr
|
|||||||
range_without_total: "%{from} à %{to} événements"
|
range_without_total: "%{from} à %{to} événements"
|
||||||
|
|
||||||
pt: &pt
|
pt: &pt
|
||||||
|
add_from_google_drive: Adicionar do Google Drive
|
||||||
|
or_add_from: Ou adicionar de
|
||||||
|
upload_a_new_document: Enviar novo documento
|
||||||
use_direct_file_attachment_links_in_the_documents: Usar links diretos de anexos de arquivos nos documentos
|
use_direct_file_attachment_links_in_the_documents: Usar links diretos de anexos de arquivos nos documentos
|
||||||
click_here_to_send_a_reset_password_email_html: '<label class="link" for="resend_password_button">Clique aqui</label> para enviar um e-mail de redefinição de senha.'
|
click_here_to_send_a_reset_password_email_html: '<label class="link" for="resend_password_button">Clique aqui</label> para enviar um e-mail de redefinição de senha.'
|
||||||
enabled: Ativado
|
enabled: Ativado
|
||||||
@@ -3903,7 +3934,7 @@ pt: &pt
|
|||||||
upload_signed_pdf_file_to_validate_its_signature_: 'Envie o arquivo PDF assinado para validar a assinatura:'
|
upload_signed_pdf_file_to_validate_its_signature_: 'Envie o arquivo PDF assinado para validar a assinatura:'
|
||||||
analyzing: Analisando
|
analyzing: Analisando
|
||||||
verify_signed_pdf: Verificar PDF assinado
|
verify_signed_pdf: Verificar PDF assinado
|
||||||
click_to_upload_or_drag_and_drop_html: '<span class="font-medium">Clique para enviar</span> ou arraste e solte'
|
click_to_upload_or_drag_and_drop_html: 'Clique para enviar ou arraste e solte'
|
||||||
click_to_upload_or_drag_and_drop_files_html: '<span class="font-medium">Clique para enviar</span> ou arraste e solte os arquivos'
|
click_to_upload_or_drag_and_drop_files_html: '<span class="font-medium">Clique para enviar</span> ou arraste e solte os arquivos'
|
||||||
signing_certificates: Certificados de assinatura
|
signing_certificates: Certificados de assinatura
|
||||||
upload_cert: Enviar certificado
|
upload_cert: Enviar certificado
|
||||||
@@ -4493,6 +4524,10 @@ pt: &pt
|
|||||||
require_a_jwt_authorization_to_preview_embedded_forms_ensuring_only_authorized_users_can_view_them: Exigir autorização JWT para visualizar formulários incorporados, garantindo que apenas usuários autorizados possam vê-los.
|
require_a_jwt_authorization_to_preview_embedded_forms_ensuring_only_authorized_users_can_view_them: Exigir autorização JWT para visualizar formulários incorporados, garantindo que apenas usuários autorizados possam vê-los.
|
||||||
make_all_newly_created_templates_private_to_their_creator_by_default: Tornar todos os modelos recém-criados privados para seu criador por padrão.
|
make_all_newly_created_templates_private_to_their_creator_by_default: Tornar todos os modelos recém-criados privados para seu criador por padrão.
|
||||||
make_the_recipients_signing_order_always_enforced_so_that_the_second_signer_can_start_signing_their_part_only_after_the_first_signer_has_completed_signing: Tornar a ordem de assinatura dos destinatários sempre obrigatória, para que o segundo signatário só possa assinar após o primeiro concluir.
|
make_the_recipients_signing_order_always_enforced_so_that_the_second_signer_can_start_signing_their_part_only_after_the_first_signer_has_completed_signing: Tornar a ordem de assinatura dos destinatários sempre obrigatória, para que o segundo signatário só possa assinar após o primeiro concluir.
|
||||||
|
the_file_is_missing_make_sure_you_have_access_to_it_on_google_drive: O arquivo está faltando. Certifique-se de ter acesso a ele no Google Drive.
|
||||||
|
connect_google_drive: Conectar Google Drive
|
||||||
|
google_drive_has_been_connected: O Google Drive foi conectado
|
||||||
|
unable_to_identify_reset_your_password_to_sign_in: Não foi possível identificar. Redefina sua senha para fazer login.
|
||||||
submission_sources:
|
submission_sources:
|
||||||
api: API
|
api: API
|
||||||
bulk: Envio em massa
|
bulk: Envio em massa
|
||||||
@@ -4599,6 +4634,9 @@ pt: &pt
|
|||||||
range_without_total: "%{from}-%{to} eventos"
|
range_without_total: "%{from}-%{to} eventos"
|
||||||
|
|
||||||
de: &de
|
de: &de
|
||||||
|
add_from_google_drive: Aus Google Drive hinzufügen
|
||||||
|
or_add_from: Oder hinzufügen von
|
||||||
|
upload_a_new_document: Neues Dokument hochladen
|
||||||
use_direct_file_attachment_links_in_the_documents: Verwenden Sie direkte Dateianhang-Links in den Dokumenten
|
use_direct_file_attachment_links_in_the_documents: Verwenden Sie direkte Dateianhang-Links in den Dokumenten
|
||||||
click_here_to_send_a_reset_password_email_html: '<label class="link" for="resend_password_button">Klicken Sie hier</label>, um eine E-Mail zum Zurücksetzen des Passworts zu senden.'
|
click_here_to_send_a_reset_password_email_html: '<label class="link" for="resend_password_button">Klicken Sie hier</label>, um eine E-Mail zum Zurücksetzen des Passworts zu senden.'
|
||||||
enabled: Aktiviert
|
enabled: Aktiviert
|
||||||
@@ -4819,7 +4857,7 @@ de: &de
|
|||||||
upload_signed_pdf_file_to_validate_its_signature_: 'Signierte PDF-Datei hochladen, um ihre Signatur zu validieren:'
|
upload_signed_pdf_file_to_validate_its_signature_: 'Signierte PDF-Datei hochladen, um ihre Signatur zu validieren:'
|
||||||
analyzing: Analysieren
|
analyzing: Analysieren
|
||||||
verify_signed_pdf: Signiertes PDF verifizieren
|
verify_signed_pdf: Signiertes PDF verifizieren
|
||||||
click_to_upload_or_drag_and_drop_html: '<span class="font-medium">Klicke, um hochzuladen</span> oder ziehe und lasse fallen'
|
click_to_upload_or_drag_and_drop_html: 'Klicke, um hochzuladen oder ziehe und lasse fallen'
|
||||||
click_to_upload_or_drag_and_drop_files_html: '<span class="font-medium">Klicke, um Dateien hochzuladen</span> oder ziehe und lasse sie fallen'
|
click_to_upload_or_drag_and_drop_files_html: '<span class="font-medium">Klicke, um Dateien hochzuladen</span> oder ziehe und lasse sie fallen'
|
||||||
signing_certificates: Signaturzertifikate
|
signing_certificates: Signaturzertifikate
|
||||||
upload_cert: Zertifikat hochladen
|
upload_cert: Zertifikat hochladen
|
||||||
@@ -5407,6 +5445,10 @@ de: &de
|
|||||||
require_a_jwt_authorization_to_preview_embedded_forms_ensuring_only_authorized_users_can_view_them: JWT-Autorisierung erforderlich, um eingebettete Formulare anzuzeigen, sodass nur autorisierte Benutzer sie sehen können.
|
require_a_jwt_authorization_to_preview_embedded_forms_ensuring_only_authorized_users_can_view_them: JWT-Autorisierung erforderlich, um eingebettete Formulare anzuzeigen, sodass nur autorisierte Benutzer sie sehen können.
|
||||||
make_all_newly_created_templates_private_to_their_creator_by_default: Alle neu erstellten Vorlagen standardmäßig für ihren Ersteller privat machen.
|
make_all_newly_created_templates_private_to_their_creator_by_default: Alle neu erstellten Vorlagen standardmäßig für ihren Ersteller privat machen.
|
||||||
make_the_recipients_signing_order_always_enforced_so_that_the_second_signer_can_start_signing_their_part_only_after_the_first_signer_has_completed_signing: Die Unterzeichnungsreihenfolge der Empfänger immer erzwingen, sodass der zweite Unterzeichner erst nach Abschluss der Unterschrift durch den ersten beginnen kann.
|
make_the_recipients_signing_order_always_enforced_so_that_the_second_signer_can_start_signing_their_part_only_after_the_first_signer_has_completed_signing: Die Unterzeichnungsreihenfolge der Empfänger immer erzwingen, sodass der zweite Unterzeichner erst nach Abschluss der Unterschrift durch den ersten beginnen kann.
|
||||||
|
the_file_is_missing_make_sure_you_have_access_to_it_on_google_drive: Die Datei fehlt. Stellen Sie sicher, dass Sie Zugriff darauf in Google Drive haben.
|
||||||
|
connect_google_drive: Google Drive verbinden
|
||||||
|
google_drive_has_been_connected: Google Drive wurde verbunden
|
||||||
|
unable_to_identify_reset_your_password_to_sign_in: Identifizierung nicht möglich. Setzen Sie Ihr Passwort zurück, um sich anzumelden.
|
||||||
submission_sources:
|
submission_sources:
|
||||||
api: API
|
api: API
|
||||||
bulk: Massenversand
|
bulk: Massenversand
|
||||||
@@ -5877,6 +5919,9 @@ he:
|
|||||||
your_email_could_not_be_reached_this_may_happen_if_there_was_a_typo_in_your_address_or_if_your_mailbox_is_not_available_please_contact_support_email_to_log_in: לא ניתן היה לגשת לדוא"ל שלך. ייתכן שזה קרה עקב שגיאת כתיב בכתובת או אם תיבת הדואר אינה זמינה. אנא פנה ל־support@docuseal.com כדי להתחבר.
|
your_email_could_not_be_reached_this_may_happen_if_there_was_a_typo_in_your_address_or_if_your_mailbox_is_not_available_please_contact_support_email_to_log_in: לא ניתן היה לגשת לדוא"ל שלך. ייתכן שזה קרה עקב שגיאת כתיב בכתובת או אם תיבת הדואר אינה זמינה. אנא פנה ל־support@docuseal.com כדי להתחבר.
|
||||||
|
|
||||||
nl: &nl
|
nl: &nl
|
||||||
|
add_from_google_drive: Toevoegen vanuit Google Drive
|
||||||
|
or_add_from: Of toevoegen vanuit
|
||||||
|
upload_a_new_document: Nieuw document uploaden
|
||||||
hi_there: Hallo
|
hi_there: Hallo
|
||||||
pro: Pro
|
pro: Pro
|
||||||
thanks: Bedankt
|
thanks: Bedankt
|
||||||
@@ -6098,7 +6143,7 @@ nl: &nl
|
|||||||
upload_signed_pdf_file_to_validate_its_signature_: 'Upload een ondertekend PDF-bestand om de handtekening te valideren:'
|
upload_signed_pdf_file_to_validate_its_signature_: 'Upload een ondertekend PDF-bestand om de handtekening te valideren:'
|
||||||
analyzing: Analyseren
|
analyzing: Analyseren
|
||||||
verify_signed_pdf: Ondertekende PDF verifiëren
|
verify_signed_pdf: Ondertekende PDF verifiëren
|
||||||
click_to_upload_or_drag_and_drop_html: <span class="font-medium">Klik om te uploaden</span> of sleep bestanden hierheen
|
click_to_upload_or_drag_and_drop_html: Klik om te uploaden of sleep bestanden hierheen
|
||||||
click_to_upload_or_drag_and_drop_files_html: <span class="font-medium">Klik om te uploaden</span> of sleep bestanden
|
click_to_upload_or_drag_and_drop_files_html: <span class="font-medium">Klik om te uploaden</span> of sleep bestanden
|
||||||
signing_certificates: Ondertekeningscertificaten
|
signing_certificates: Ondertekeningscertificaten
|
||||||
upload_cert: Certificaat uploaden
|
upload_cert: Certificaat uploaden
|
||||||
@@ -6684,6 +6729,10 @@ nl: &nl
|
|||||||
require_a_jwt_authorization_to_preview_embedded_forms_ensuring_only_authorized_users_can_view_them: JWT-autorisatie vereisen om ingesloten formulieren te bekijken, zodat alleen geautoriseerde gebruikers ze kunnen zien.
|
require_a_jwt_authorization_to_preview_embedded_forms_ensuring_only_authorized_users_can_view_them: JWT-autorisatie vereisen om ingesloten formulieren te bekijken, zodat alleen geautoriseerde gebruikers ze kunnen zien.
|
||||||
make_all_newly_created_templates_private_to_their_creator_by_default: Maak alle nieuw aangemaakte sjablonen standaard privé voor hun maker.
|
make_all_newly_created_templates_private_to_their_creator_by_default: Maak alle nieuw aangemaakte sjablonen standaard privé voor hun maker.
|
||||||
make_the_recipients_signing_order_always_enforced_so_that_the_second_signer_can_start_signing_their_part_only_after_the_first_signer_has_completed_signing: Zorg dat de volgorde van ondertekenen altijd wordt afgedwongen, zodat de tweede ondertekenaar pas kan beginnen nadat de eerste ondertekenaar heeft voltooid.
|
make_the_recipients_signing_order_always_enforced_so_that_the_second_signer_can_start_signing_their_part_only_after_the_first_signer_has_completed_signing: Zorg dat de volgorde van ondertekenen altijd wordt afgedwongen, zodat de tweede ondertekenaar pas kan beginnen nadat de eerste ondertekenaar heeft voltooid.
|
||||||
|
the_file_is_missing_make_sure_you_have_access_to_it_on_google_drive: Het bestand ontbreekt. Zorg ervoor dat je er toegang toe hebt op Google Drive.
|
||||||
|
connect_google_drive: Verbind Google Drive
|
||||||
|
google_drive_has_been_connected: Google Drive is verbonden
|
||||||
|
unable_to_identify_reset_your_password_to_sign_in: Kan niet worden geïdentificeerd. Stel je wachtwoord opnieuw in om in te loggen.
|
||||||
submission_sources:
|
submission_sources:
|
||||||
api: API
|
api: API
|
||||||
bulk: Bulkverzending
|
bulk: Bulkverzending
|
||||||
|
|||||||
Reference in New Issue
Block a user