mirror of
https://github.com/docusealco/docuseal.git
synced 2026-08-07 15:25:16 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5439c63ce7 | |||
| b78287242b | |||
| b869ae38b3 | |||
| 4a320e9ba6 | |||
| 0025928a35 | |||
| c227a1988a |
@@ -25,7 +25,7 @@ module Api
|
||||
|
||||
def paginate(relation)
|
||||
result = relation.order(id: :desc)
|
||||
.limit([params[:limit] || DEFAULT_LIMIT, MAX_LIMIT].min)
|
||||
.limit([params.fetch(:limit, DEFAULT_LIMIT).to_i, MAX_LIMIT].min)
|
||||
|
||||
result = result.where('id < ?', params[:after]) if params[:after].present?
|
||||
result = result.where('id > ?', params[:before]) if params[:before].present?
|
||||
|
||||
@@ -47,7 +47,7 @@ class StartFormController < ApplicationController
|
||||
private
|
||||
|
||||
def submitter_params
|
||||
params.require(:submitter).permit(:email, :phone).tap do |attrs|
|
||||
params.require(:submitter).permit(:email, :phone, :name).tap do |attrs|
|
||||
attrs[:email] = Submissions.normalize_email(attrs[:email])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -156,32 +156,17 @@
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<span
|
||||
v-if="drawField"
|
||||
class="fixed text-center w-full left-1/2 bottom-0 transform -translate-x-1/2"
|
||||
>
|
||||
<span
|
||||
class="rounded bg-base-200 px-4 py-2 rounded-full inline-flex space-x-2 mx-auto items-center mb-4 z-20 md:hidden"
|
||||
>
|
||||
<component
|
||||
:is="fieldIcons[drawField.type]"
|
||||
:width="20"
|
||||
:height="20"
|
||||
class="inline"
|
||||
:stroke-width="1.6"
|
||||
/>
|
||||
<span>
|
||||
Draw {{ fieldNames[drawField.type] }} Field
|
||||
</span>
|
||||
<a
|
||||
href="#"
|
||||
class="link block text-center"
|
||||
@click.prevent="drawField = null"
|
||||
>
|
||||
Cancel
|
||||
</a>
|
||||
</span>
|
||||
</span>
|
||||
<MobileDrawField
|
||||
v-if="drawField && isBreakpointLg"
|
||||
:draw-field="drawField"
|
||||
:fields="template.fields"
|
||||
:submitters="template.submitters"
|
||||
:selected-submitter="selectedSubmitter"
|
||||
class="md:hidden"
|
||||
:editable="editable"
|
||||
@cancel="drawField = null"
|
||||
@change-submitter="[selectedSubmitter = $event, drawField.submitter_uuid = $event.uuid]"
|
||||
/>
|
||||
<FieldType
|
||||
v-if="sortedDocuments.length && !drawField && editable"
|
||||
class="dropdown-top dropdown-end fixed bottom-4 right-4 z-10 md:hidden"
|
||||
@@ -251,6 +236,7 @@
|
||||
import Upload from './upload'
|
||||
import Dropzone from './dropzone'
|
||||
import Fields from './fields'
|
||||
import MobileDrawField from './mobile_draw_field'
|
||||
import Document from './document'
|
||||
import Logo from './logo'
|
||||
import Contenteditable from './contenteditable'
|
||||
@@ -267,6 +253,7 @@ export default {
|
||||
Upload,
|
||||
Document,
|
||||
Fields,
|
||||
MobileDrawField,
|
||||
IconPlus,
|
||||
FieldType,
|
||||
IconX,
|
||||
|
||||
@@ -1,5 +1,91 @@
|
||||
<template>
|
||||
<div class="dropdown">
|
||||
<div v-if="mobileView">
|
||||
<div class="flex space-x-2 items-end">
|
||||
<div class="group/contenteditable-container bg-base-100 rounded-md p-2 border border-base-300 w-full flex justify-between items-end">
|
||||
<div class="flex items-center space-x-2">
|
||||
<span
|
||||
class="w-3 h-3 flex-shrink-0 rounded-full"
|
||||
:class="colors[submitters.indexOf(selectedSubmitter)]"
|
||||
/>
|
||||
<Contenteditable
|
||||
v-model="selectedSubmitter.name"
|
||||
class="cursor-text"
|
||||
:icon-inline="true"
|
||||
:editable="editable"
|
||||
:select-on-edit-click="true"
|
||||
:icon-width="18"
|
||||
@update:model-value="$emit('name-change', selectedSubmitter)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown dropdown-top dropdown-end">
|
||||
<label
|
||||
tabindex="0"
|
||||
class="bg-base-100 cursor-pointer rounded-md p-2 border border-base-300 w-full flex justify-center"
|
||||
>
|
||||
<IconChevronUp
|
||||
width="24"
|
||||
height="24"
|
||||
/>
|
||||
</label>
|
||||
<ul
|
||||
v-if="editable"
|
||||
tabindex="0"
|
||||
class="rounded-md min-w-max mb-2"
|
||||
:class="menuClasses"
|
||||
@click="closeDropdown"
|
||||
>
|
||||
<li
|
||||
v-for="(submitter, index) in submitters"
|
||||
:key="submitter.uuid"
|
||||
>
|
||||
<a
|
||||
href="#"
|
||||
class="flex px-2 group justify-between items-center"
|
||||
:class="{ 'active': submitter === selectedSubmitter }"
|
||||
@click.prevent="selectSubmitter(submitter)"
|
||||
>
|
||||
<span class="py-1 flex items-center">
|
||||
<span
|
||||
class="rounded-full w-3 h-3 ml-1 mr-3"
|
||||
:class="colors[index]"
|
||||
/>
|
||||
<span>
|
||||
{{ submitter.name }}
|
||||
</span>
|
||||
</span>
|
||||
<button
|
||||
v-if="submitters.length > 1 && editable"
|
||||
class="px-2"
|
||||
@click.stop="remove(submitter)"
|
||||
>
|
||||
<IconTrashX :width="18" />
|
||||
</button>
|
||||
</a>
|
||||
</li>
|
||||
<li v-if="submitters.length < 10 && editable">
|
||||
<a
|
||||
href="#"
|
||||
class="flex px-2"
|
||||
@click.prevent="addSubmitter"
|
||||
>
|
||||
<IconUserPlus
|
||||
:width="20"
|
||||
:stroke-width="1.6"
|
||||
/>
|
||||
<span class="py-1">
|
||||
Add Submitter
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="dropdown"
|
||||
>
|
||||
<label
|
||||
v-if="compact"
|
||||
tabindex="0"
|
||||
@@ -92,7 +178,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { IconUserPlus, IconTrashX, IconPlus } from '@tabler/icons-vue'
|
||||
import { IconUserPlus, IconTrashX, IconPlus, IconChevronUp } from '@tabler/icons-vue'
|
||||
import Contenteditable from './contenteditable'
|
||||
import { v4 } from 'uuid'
|
||||
|
||||
@@ -102,7 +188,8 @@ export default {
|
||||
IconUserPlus,
|
||||
Contenteditable,
|
||||
IconPlus,
|
||||
IconTrashX
|
||||
IconTrashX,
|
||||
IconChevronUp
|
||||
},
|
||||
props: {
|
||||
submitters: {
|
||||
@@ -119,6 +206,11 @@ export default {
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
mobileView: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
modelValue: {
|
||||
type: String,
|
||||
required: true
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<div class="fixed text-center w-full bottom-0 pr-6 mb-4">
|
||||
<span class="w-full bg-base-200 px-4 py-2 rounded-md inline-flex space-x-2 mx-auto items-center justify-between mb-2 z-20 md:hidden">
|
||||
<div class="flex items-center space-x-2">
|
||||
<component
|
||||
:is="fieldIcons[drawField.type]"
|
||||
:width="20"
|
||||
:height="20"
|
||||
class="inline"
|
||||
:stroke-width="1.6"
|
||||
/>
|
||||
<span> Draw {{ fieldNames[drawField.type] }} Field </span>
|
||||
</div>
|
||||
<a
|
||||
href="#"
|
||||
class="link block text-center"
|
||||
@click.prevent="$emit('cancel')"
|
||||
>
|
||||
Cancel
|
||||
</a>
|
||||
</span>
|
||||
<FieldSubmitter
|
||||
:model-value="selectedSubmitter.uuid"
|
||||
:submitters="submitters"
|
||||
:editable="editable"
|
||||
:mobile-view="true"
|
||||
@new-submitter="save"
|
||||
@remove="removeSubmitter"
|
||||
@name-change="save"
|
||||
@update:model-value="$emit('change-submitter', submitters.find((s) => s.uuid === $event))"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Field from './field'
|
||||
import FieldType from './field_type'
|
||||
import FieldSubmitter from './field_submitter'
|
||||
|
||||
export default {
|
||||
name: 'MobileDrawField',
|
||||
components: {
|
||||
Field,
|
||||
FieldSubmitter
|
||||
},
|
||||
inject: ['save'],
|
||||
props: {
|
||||
drawField: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
editable: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true
|
||||
},
|
||||
submitters: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
fields: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
selectedSubmitter: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
emits: ['change-submitter', 'cancel'],
|
||||
computed: {
|
||||
fieldNames: FieldType.computed.fieldNames,
|
||||
fieldIcons: FieldType.computed.fieldIcons
|
||||
},
|
||||
methods: {
|
||||
removeSubmitter (submitter) {
|
||||
[...this.fields].forEach((field) => {
|
||||
if (field.submitter_uuid === submitter.uuid) {
|
||||
this.removeField(field)
|
||||
}
|
||||
})
|
||||
|
||||
this.submitters.splice(this.submitters.indexOf(submitter), 1)
|
||||
|
||||
if (this.selectedSubmitter === submitter) {
|
||||
this.$emit('change-submitter', this.submitters[0])
|
||||
}
|
||||
|
||||
this.save()
|
||||
},
|
||||
removeField (field) {
|
||||
this.fields.splice(this.fields.indexOf(field), 1)
|
||||
|
||||
this.save()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -39,7 +39,7 @@
|
||||
<% if @submitter.submission.template.submitters.size == 1 %>
|
||||
<div class="divider">OR</div>
|
||||
<div>
|
||||
<%= button_to button_title(title: 'Resubmit', disabled_with: 'Resubmit', icon: svg_icon('reload', class: 'w-6 h-6')), start_form_path(@submitter.submission.template.slug), params: { submitter: { email: @submitter.email, phone: @submitter.phone }, resubmit: true }, method: :put, form: { onsubmit: 'event.submitter.disabled = true' }, class: 'white-button w-full' %>
|
||||
<%= button_to button_title(title: 'Resubmit', disabled_with: 'Resubmit', icon: svg_icon('reload', class: 'w-6 h-6')), start_form_path(@submitter.submission.template.slug), params: { submitter: { email: @submitter.email, phone: @submitter.phone, name: @submitter.name }, resubmit: true }, method: :put, form: { onsubmit: 'event.submitter.disabled = true' }, class: 'white-button w-full' %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<%= render 'submissions/annotation', annot: %>
|
||||
<% end %>
|
||||
<% fields_index.dig(document.uuid, index)&.each do |(area, field)| %>
|
||||
<% value = values[field['uuid']].presence || field['readonly'] ? Submitters::SubmitValues.template_default_value_for_submitter(field['default_value'], @submitter.submission.submitters.find { |e| e.uuid == field['submitter_uuid'] }, with_time: false) : nil %>
|
||||
<% value = values[field['uuid']].presence || (field['readonly'] ? Submitters::SubmitValues.template_default_value_for_submitter(field['default_value'], @submitter.submission.submitters.find { |e| e.uuid == field['submitter_uuid'] }, with_time: false) : nil) %>
|
||||
<% next if value.blank? %>
|
||||
<% next if !field['readonly'] && field['submitter_uuid'] == @submitter.uuid %>
|
||||
<%= render 'submissions/value', area:, field:, attachments_index:, value:, locale: @submitter.submission.template.account.locale %>
|
||||
|
||||
@@ -105,12 +105,16 @@ module Submitters
|
||||
when 'time'
|
||||
if with_time
|
||||
I18n.l(Time.current.in_time_zone(template.account.timezone), format: :long, locale: template.account.locale)
|
||||
else
|
||||
e
|
||||
end
|
||||
when 'date'
|
||||
I18n.l(Time.current.in_time_zone(template.account.timezone).to_date) if with_time
|
||||
when 'name', 'full_name'
|
||||
"#{attrs['first_name']} #{attrs['last_name']}".strip.presence || e
|
||||
when 'role', 'email', 'phone'
|
||||
if with_time
|
||||
I18n.l(Time.current.in_time_zone(template.account.timezone).to_date)
|
||||
else
|
||||
e
|
||||
end
|
||||
when 'role', 'email', 'phone', 'name'
|
||||
attrs[key] || e
|
||||
else
|
||||
e
|
||||
|
||||
Reference in New Issue
Block a user