add ability to toggle textarea

pull/133/head
DocuSeal 2 years ago
parent 698031cfc0
commit 49b9064d9f

@ -47,6 +47,10 @@ select:required:invalid {
@apply border-base-content/20; @apply border-base-content/20;
} }
.base-textarea {
@apply textarea textarea-bordered bg-white rounded-3xl;
}
.btn { .btn {
@apply no-animation; @apply no-animation;
} }

@ -110,9 +110,10 @@
<span v-else-if="field.type === 'date'"> <span v-else-if="field.type === 'date'">
{{ formattedDate }} {{ formattedDate }}
</span> </span>
<span v-else> <span
{{ modelValue }} v-else
</span> class="whitespace-pre-wrap"
>{{ modelValue }}</span>
</div> </div>
</div> </div>
</template> </template>

@ -58,32 +58,12 @@
> >
<div class="md:mt-4"> <div class="md:mt-4">
<div v-if="['cells', 'text'].includes(currentField.type)"> <div v-if="['cells', 'text'].includes(currentField.type)">
<label <TextStep
v-if="currentField.name" :key="currentField.uuid"
:for="currentField.uuid" v-model="values[currentField.uuid]"
class="label text-2xl mb-2" :field="currentField"
>{{ currentField.name }} @focus="$refs.areas.scrollIntoField(currentField)"
<template v-if="!currentField.required">({{ t('optional') }})</template>
</label>
<div
v-else
class="py-1"
/> />
<div>
<input
:id="currentField.uuid"
v-model="values[currentField.uuid]"
class="base-input !text-2xl w-full"
:required="currentField.required"
:pattern="currentField.validation?.pattern"
:oninvalid="currentField.validation?.message ? `this.setCustomValidity(${JSON.stringify(currentField.validation.message)})` : ''"
:oninput="currentField.validation?.message ? `this.setCustomValidity('')` : ''"
:placeholder="`${t('type_here')}...${currentField.required ? '' : ` (${t('optional')})`}`"
type="text"
:name="`values[${currentField.uuid}]`"
@focus="$refs.areas.scrollIntoField(currentField)"
>
</div>
</div> </div>
<div v-else-if="currentField.type === 'date'"> <div v-else-if="currentField.type === 'date'">
<div class="flex justify-between items-center w-full mb-2"> <div class="flex justify-between items-center w-full mb-2">
@ -363,6 +343,7 @@ import InitialsStep from './initials_step'
import AttachmentStep from './attachment_step' import AttachmentStep from './attachment_step'
import MultiSelectStep from './multi_select_step' import MultiSelectStep from './multi_select_step'
import PhoneStep from './phone_step' import PhoneStep from './phone_step'
import TextStep from './text_step'
import FormCompleted from './completed' import FormCompleted from './completed'
import { IconInnerShadowTop, IconArrowsDiagonal, IconArrowsDiagonalMinimize2, IconCalendarCheck } from '@tabler/icons-vue' import { IconInnerShadowTop, IconArrowsDiagonal, IconArrowsDiagonalMinimize2, IconCalendarCheck } from '@tabler/icons-vue'
import { t } from './i18n' import { t } from './i18n'
@ -378,6 +359,7 @@ export default {
MultiSelectStep, MultiSelectStep,
IconInnerShadowTop, IconInnerShadowTop,
IconArrowsDiagonal, IconArrowsDiagonal,
TextStep,
PhoneStep, PhoneStep,
IconCalendarCheck, IconCalendarCheck,
IconArrowsDiagonalMinimize2, IconArrowsDiagonalMinimize2,

@ -31,6 +31,7 @@ const en = {
verification_code_has_been_resent: 'Verification code has been re-sent via SMS', verification_code_has_been_resent: 'Verification code has been re-sent via SMS',
please_fill_all_required_fields: 'Please fill all required fields', please_fill_all_required_fields: 'Please fill all required fields',
set_today: 'Set Today', set_today: 'Set Today',
toggle_multiline_text: 'Toggle Multiline Text',
date: 'Date', date: 'Date',
email_has_been_sent: 'Email has been sent' email_has_been_sent: 'Email has been sent'
} }
@ -69,6 +70,7 @@ const es = {
please_fill_all_required_fields: 'Por favor, complete todos los campos obligatorios', please_fill_all_required_fields: 'Por favor, complete todos los campos obligatorios',
set_today: 'Establecer Hoy', set_today: 'Establecer Hoy',
date: 'Fecha', date: 'Fecha',
toggle_multiline_text: 'Alternar Texto Multilínea',
email_has_been_sent: 'El correo electrónico ha sido enviado' email_has_been_sent: 'El correo electrónico ha sido enviado'
} }
@ -106,6 +108,7 @@ const it = {
please_fill_all_required_fields: 'Si prega di compilare tutti i campi obbligatori', please_fill_all_required_fields: 'Si prega di compilare tutti i campi obbligatori',
set_today: 'Imposta Oggi', set_today: 'Imposta Oggi',
date: 'Data', date: 'Data',
toggle_multiline_text: 'Attiva Testo Multilinea',
email_has_been_sent: "L'email è stata inviata" email_has_been_sent: "L'email è stata inviata"
} }
@ -143,6 +146,7 @@ const de = {
please_fill_all_required_fields: 'Bitte füllen Sie alle erforderlichen Felder aus', please_fill_all_required_fields: 'Bitte füllen Sie alle erforderlichen Felder aus',
set_today: 'Heute einstellen', set_today: 'Heute einstellen',
date: 'Datum', date: 'Datum',
toggle_multiline_text: 'Mehrzeiligen Text umschalten',
email_has_been_sent: 'Die E-Mail wurde gesendet' email_has_been_sent: 'Die E-Mail wurde gesendet'
} }
@ -180,6 +184,7 @@ const fr = {
please_fill_all_required_fields: 'Veuillez remplir tous les champs obligatoires', please_fill_all_required_fields: 'Veuillez remplir tous les champs obligatoires',
set_today: "Définir Aujourd'hui", set_today: "Définir Aujourd'hui",
date: 'Date', date: 'Date',
toggle_multiline_text: 'Basculer le Texte Multiligne',
email_has_been_sent: "L'email a été envoyé" email_has_been_sent: "L'email a été envoyé"
} }
@ -217,6 +222,7 @@ const pl = {
please_fill_all_required_fields: 'Proszę wypełnić wszystkie wymagane pola', please_fill_all_required_fields: 'Proszę wypełnić wszystkie wymagane pola',
set_today: 'Ustaw Dziś', set_today: 'Ustaw Dziś',
date: 'Data', date: 'Data',
toggle_multiline_text: 'Przełącz Tekst Wielolinijkowy',
email_has_been_sent: 'E-mail został wysłany' email_has_been_sent: 'E-mail został wysłany'
} }
@ -254,6 +260,7 @@ const uk = {
please_fill_all_required_fields: "Будь ласка, заповніть всі обов'язкові поля", please_fill_all_required_fields: "Будь ласка, заповніть всі обов'язкові поля",
set_today: 'Задати Сьогодні', set_today: 'Задати Сьогодні',
date: 'Дата', date: 'Дата',
toggle_multiline_text: 'Перемкнути Багаторядковий Текст',
email_has_been_sent: 'Електронний лист був відправлений' email_has_been_sent: 'Електронний лист був відправлений'
} }
@ -291,6 +298,7 @@ const cs = {
please_fill_all_required_fields: 'Prosím vyplňte všechny povinné položky', please_fill_all_required_fields: 'Prosím vyplňte všechny povinné položky',
set_today: 'Nastavit Dnes', set_today: 'Nastavit Dnes',
date: 'Datum', date: 'Datum',
toggle_multiline_text: 'Přepnout Víceřádkový Text',
email_has_been_sent: 'E-mail byl odeslán' email_has_been_sent: 'E-mail byl odeslán'
} }
@ -328,6 +336,7 @@ const pt = {
please_fill_all_required_fields: 'Por favor, preencha todos os campos obrigatórios', please_fill_all_required_fields: 'Por favor, preencha todos os campos obrigatórios',
set_today: 'Definir Hoje', set_today: 'Definir Hoje',
date: 'Data', date: 'Data',
toggle_multiline_text: 'Alternar Texto Multilinha',
email_has_been_sent: 'Email enviado' email_has_been_sent: 'Email enviado'
} }

@ -0,0 +1,111 @@
<template>
<label
v-if="field.name"
:for="field.uuid"
class="label text-2xl mb-2"
>{{ field.name }}
<template v-if="!field.required">({{ t('optional') }})</template>
</label>
<div
v-else
class="py-1"
/>
<div class="items-center flex">
<input
v-if="!isTextArea"
:id="field.uuid"
v-model="text"
class="base-input !text-2xl w-full !pr-11 -mr-10"
:required="field.required"
:pattern="field.validation?.pattern"
:oninvalid="field.validation?.message ? `this.setCustomValidity(${JSON.stringify(field.validation.message)})` : ''"
:oninput="field.validation?.message ? `this.setCustomValidity('')` : ''"
:placeholder="`${t('type_here')}...${field.required ? '' : ` (${t('optional')})`}`"
type="text"
:name="`values[${field.uuid}]`"
@focus="$emit('focus')"
>
<textarea
v-if="isTextArea"
:id="field.uuid"
ref="textarea"
v-model="text"
class="base-textarea !text-2xl w-full"
:placeholder="`${t('type_here')}...${field.required ? '' : ` (${t('optional')})`}`"
:required="field.required"
:name="`values[${field.uuid}]`"
@input="resizeTextarea"
@focus="$emit('focus')"
/>
<div
v-if="!isTextArea"
class="tooltip"
:data-tip="t('toggle_multiline_text')"
>
<a
href="#"
class="btn btn-ghost btn-circle btn-sm"
@click.prevent="toggleTextArea"
>
<IconAlignBoxLeftTop />
</a>
</div>
</div>
</template>
<script>
import { IconAlignBoxLeftTop } from '@tabler/icons-vue'
export default {
name: 'TextStep',
components: {
IconAlignBoxLeftTop
},
inject: ['t'],
props: {
field: {
type: Object,
required: true
},
modelValue: {
type: String,
required: false,
default: ''
}
},
emits: ['update:model-value', 'focus'],
data () {
return {
isTextArea: false
}
},
computed: {
text: {
set (value) {
this.$emit('update:model-value', value)
},
get () {
return this.modelValue
}
}
},
methods: {
resizeTextarea () {
const textarea = this.$refs.textarea
textarea.style.height = 'auto'
textarea.style.height = textarea.scrollHeight + 'px'
},
toggleTextArea () {
this.isTextArea = true
this.$nextTick(() => {
this.$refs.textarea.focus()
this.$refs.textarea.setSelectionRange(this.$refs.textarea.value.length, this.$refs.textarea.value.length)
this.resizeTextarea()
})
}
}
}
</script>

@ -1,11 +1,11 @@
<form action="<%= request.path %>" method="get" class="items-center hidden md:flex"> <form action="<%= request.path %>" method="get" class="items-center hidden md:flex">
<div class="relative"> <% if params[:q].present? %>
<% if params[:q].present? %> <div class="relative">
<a href="<%= request.path %>" title="Clear" class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-auto text-neutral text-2xl font-extralight"> <a href="<%= request.path %>" title="Clear" class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-auto text-neutral text-2xl font-extralight">
&times; &times;
</a> </a>
<% end %> </div>
</div> <% end %>
<input id="search" name="q" value="<%= params[:q] %>" class="input input-ghost text-lg pr-10 -mr-12 <%= 'pl-8 input-outlined' if params[:q].present? %>"> <input id="search" name="q" value="<%= params[:q] %>" class="input input-ghost text-lg pr-10 -mr-12 <%= 'pl-8 input-outlined' if params[:q].present? %>">
<button type="submit" title="Search" class="btn btn-ghost btn-circle" onclick="window.search.value || document.activeElement === window.search ? null : [event.preventDefault(), window.search.focus()]"> <button type="submit" title="Search" class="btn btn-ghost btn-circle" onclick="window.search.value || document.activeElement === window.search ? null : [event.preventDefault(), window.search.focus()]">
<span class="enabled"> <span class="enabled">

@ -28,8 +28,6 @@
<%= l(Date.parse(value), format: :long, locale: local_assigns[:locale]) %> <%= l(Date.parse(value), format: :long, locale: local_assigns[:locale]) %>
</div> </div>
<% else %> <% else %>
<div class="flex items-center px-0.5"> <div class="flex items-center px-0.5 whitespace-pre-wrap"><%= Array.wrap(value).join(', ') %></div>
<%= Array.wrap(value).join(', ') %>
</div>
<% end %> <% end %>
</div> </div>

@ -23,7 +23,6 @@ module Submissions
# rubocop:disable Metrics # rubocop:disable Metrics
def call(submitter) def call(submitter)
layouter = HexaPDF::Layout::TextLayouter.new(valign: :center)
cell_layouter = HexaPDF::Layout::TextLayouter.new(valign: :center, align: :center) cell_layouter = HexaPDF::Layout::TextLayouter.new(valign: :center, align: :center)
template = submitter.submission.template template = submitter.submission.template
@ -38,7 +37,6 @@ module Submissions
field.fetch('areas', []).each do |area| field.fetch('areas', []).each do |area|
pdf = pdfs_index[area['attachment_uuid']] pdf = pdfs_index[area['attachment_uuid']]
pdf.fonts.add(FONT_NAME)
page = pdf.pages[area['page']] page = pdf.pages[area['page']]
page.rotate(0, flatten: true) if page[:Rotate] != 0 page.rotate(0, flatten: true) if page[:Rotate] != 0
@ -50,6 +48,8 @@ module Submissions
height = page.box.height height = page.box.height
font_size = ((page.box.width / A4_SIZE[0].to_f) * FONT_SIZE).to_i font_size = ((page.box.width / A4_SIZE[0].to_f) * FONT_SIZE).to_i
layouter = HexaPDF::Layout::TextLayouter.new(valign: :center, font: pdf.fonts.add(FONT_NAME), font_size:)
value = submitter.values[field['uuid']] value = submitter.values[field['uuid']]
next if Array.wrap(value).compact_blank.blank? next if Array.wrap(value).compact_blank.blank?

Loading…
Cancel
Save