Skip to content

Commit 5fe75c8

Browse files
authored
Merge from docusealco/wip
2 parents 6a3a185 + 4549a04 commit 5fe75c8

27 files changed

Lines changed: 217 additions & 73 deletions

app/javascript/application.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ safeRegisterElement('template-builder', class extends HTMLElement {
164164
this.app = createApp(TemplateBuilder, {
165165
template,
166166
customFields: reactive(JSON.parse(this.dataset.customFields || '[]')),
167+
dateFormats: JSON.parse(this.dataset.dateFormats || '[]'),
167168
dynamicDocuments: reactive(JSON.parse(this.dataset.dynamicDocuments || '[]')),
168169
backgroundColor: '#faf7f5',
169170
locale: this.dataset.locale,

app/javascript/submission_form/form.vue

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,6 +1575,7 @@ export default {
15751575
}
15761576
},
15771577
goToStep (stepIndex, scrollToArea = false, clickUpload = false) {
1578+
this.isInvite = false
15781579
this.currentStep = stepIndex
15791580
this.showFillAllRequiredFields = false
15801581
@@ -1599,6 +1600,10 @@ export default {
15991600
})
16001601
},
16011602
saveStep (formData) {
1603+
if (!formData && !this.$refs.form) {
1604+
return
1605+
}
1606+
16021607
const currentFieldUuids = this.currentStepFields.map((f) => f.uuid)
16031608
const currentFieldType = this.currentField.type
16041609

app/javascript/template_builder/area.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ export default {
319319
default: false
320320
}
321321
},
322-
emits: ['start-resize', 'stop-resize', 'start-drag', 'stop-drag', 'remove', 'scroll-to', 'add-custom-field', 'click-title'],
322+
emits: ['start-resize', 'stop-resize', 'start-drag', 'stop-drag', 'remove', 'scroll-to', 'add-custom-field', 'click-title', 'multi-select'],
323323
data () {
324324
return {
325325
isContenteditable: false,
@@ -798,6 +798,8 @@ export default {
798798
this.selectedAreasRef.value.splice(this.selectedAreasRef.value.indexOf(this.area), 1)
799799
}
800800
801+
this.$emit('multi-select', e)
802+
801803
return
802804
}
803805

app/javascript/template_builder/page.vue

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
@scroll-to="$emit('scroll-to', $event)"
5858
@add-custom-field="$emit('add-custom-field', $event)"
5959
@contextmenu="openAreaContextMenu($event, item.area, item.field)"
60+
@multi-select="openMultiSelectContextMenu"
6061
@click-title="closeContextMenu"
6162
/>
6263
<FieldArea
@@ -408,6 +409,12 @@ export default {
408409
return
409410
}
410411
412+
if (this.selectedAreasRef.value.length >= 2) {
413+
this.openSelectionContextMenu(event)
414+
415+
return
416+
}
417+
411418
event.preventDefault()
412419
event.stopPropagation()
413420
@@ -443,6 +450,13 @@ export default {
443450
areas: this.selectedAreasRef.value
444451
}
445452
},
453+
openMultiSelectContextMenu (event) {
454+
if (this.selectedAreasRef.value.length >= 2) {
455+
this.openSelectionContextMenu(event)
456+
} else {
457+
this.closeContextMenu()
458+
}
459+
},
446460
handleSelectionCopy () {
447461
this.$emit('copy-selected-areas')
448462

app/javascript/template_builder/selection_context_menu.vue

Lines changed: 84 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,62 @@
99
@mousedown.stop
1010
@pointerdown.stop
1111
>
12+
<label
13+
v-if="requiredFields.length"
14+
class="field-settings-required w-full px-2 py-1 rounded-md hover:bg-neutral-100 flex items-center space-x-2 text-sm cursor-pointer"
15+
@click.stop
16+
>
17+
<input
18+
:checked="isAllRequired"
19+
:indeterminate="isMixedRequired"
20+
type="checkbox"
21+
class="toggle toggle-xs"
22+
:disabled="!editable"
23+
@change="handleToggleRequired($event.target.checked)"
24+
@click.stop
25+
>
26+
<span>{{ t('required') }}</span>
27+
</label>
28+
<label
29+
v-if="readOnlyFields.length"
30+
class="field-settings-read-only w-full px-2 py-1 rounded-md hover:bg-neutral-100 flex items-center space-x-2 text-sm cursor-pointer"
31+
@click.stop
32+
>
33+
<input
34+
:checked="isAllReadOnly"
35+
:indeterminate="isMixedReadOnly"
36+
type="checkbox"
37+
class="toggle toggle-xs"
38+
:disabled="!editable"
39+
@change="handleToggleReadOnly($event.target.checked)"
40+
@click.stop
41+
>
42+
<span>{{ t('read_only') }}</span>
43+
</label>
44+
<hr
45+
v-if="requiredFields.length || readOnlyFields.length"
46+
class="my-1 border-neutral-200"
47+
>
48+
<button
49+
v-if="showFont"
50+
class="w-full px-2 py-1 rounded-md hover:bg-neutral-100 flex items-center space-x-2 text-sm"
51+
@click.stop="openFontModal"
52+
>
53+
<IconTypography class="w-4 h-4" />
54+
<span>{{ t('font') }}</span>
55+
</button>
56+
<button
57+
v-if="showCondition"
58+
class="w-full px-2 py-1 rounded-md hover:bg-neutral-100 flex items-center space-x-2 text-sm"
59+
@click.stop="openConditionModal"
60+
>
61+
<IconRouteAltLeft class="w-4 h-4" />
62+
<span>{{ t('condition') }}</span>
63+
</button>
64+
<hr
65+
v-if="showFont || showCondition"
66+
class="my-1 border-neutral-200"
67+
>
1268
<ContextSubmenu
1369
:icon="IconLayoutAlignMiddle"
1470
:label="t('align')"
@@ -61,26 +117,6 @@
61117
<span>{{ t('height') }}</span>
62118
</button>
63119
</ContextSubmenu>
64-
<hr
65-
v-if="showFont || showCondition"
66-
class="my-1 border-neutral-200"
67-
>
68-
<button
69-
v-if="showFont"
70-
class="w-full px-2 py-1 rounded-md hover:bg-neutral-100 flex items-center space-x-2 text-sm"
71-
@click.stop="openFontModal"
72-
>
73-
<IconTypography class="w-4 h-4" />
74-
<span>{{ t('font') }}</span>
75-
</button>
76-
<button
77-
v-if="showCondition"
78-
class="w-full px-2 py-1 rounded-md hover:bg-neutral-100 flex items-center space-x-2 text-sm"
79-
@click.stop="openConditionModal"
80-
>
81-
<IconRouteAltLeft class="w-4 h-4" />
82-
<span>{{ t('condition') }}</span>
83-
</button>
84120
<hr class="my-1 border-neutral-200">
85121
<button
86122
class="w-full px-2 py-1 rounded-md hover:bg-neutral-100 flex items-center justify-between text-sm"
@@ -192,6 +228,24 @@ export default {
192228
return this.template.fields.find((f) => f.areas?.includes(area))
193229
}).filter(Boolean)
194230
},
231+
requiredFields () {
232+
return this.selectedFields.filter((f) => !['phone', 'stamp', 'verification', 'strikethrough', 'heading'].includes(f.type))
233+
},
234+
readOnlyFields () {
235+
return this.selectedFields.filter((f) => ['text', 'number', 'radio', 'multiple', 'select'].includes(f.type))
236+
},
237+
isAllRequired () {
238+
return this.requiredFields.every((f) => f.required)
239+
},
240+
isMixedRequired () {
241+
return !this.isAllRequired && this.requiredFields.some((f) => f.required)
242+
},
243+
isAllReadOnly () {
244+
return this.readOnlyFields.every((f) => f.readonly)
245+
},
246+
isMixedReadOnly () {
247+
return !this.isAllReadOnly && this.readOnlyFields.some((f) => f.readonly)
248+
},
195249
isMac () {
196250
return (navigator.userAgentData?.platform || navigator.platform)?.toLowerCase()?.includes('mac')
197251
},
@@ -234,6 +288,16 @@ export default {
234288
}
235289
}
236290
},
291+
handleToggleRequired (value) {
292+
this.requiredFields.forEach((field) => { field.required = value })
293+
294+
this.save()
295+
},
296+
handleToggleReadOnly (value) {
297+
this.readOnlyFields.forEach((field) => { field.readonly = value })
298+
299+
this.save()
300+
},
237301
onKeyDown (event) {
238302
if (event.key === 'Escape') {
239303
event.preventDefault()

app/models/account_config.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class AccountConfig < ApplicationRecord
4848
WITH_SIGNATURE_ID = 'with_signature_id'
4949
WITH_FILE_LINKS_KEY = 'with_file_links'
5050
WITH_SIGNATURE_ID_REASON_KEY = 'with_signature_id_reason'
51+
WITH_SIGNATURE_ID_COMPLETED_AT_KEY = 'with_signature_id_completed_at'
5152
RECIPIENT_FORM_FIELDS_KEY = 'recipient_form_fields'
5253
WITH_AUDIT_VALUES_KEY = 'with_audit_values'
5354
WITH_AUDIT_SENDER_KEY = 'with_audit_sender'
@@ -59,6 +60,7 @@ class AccountConfig < ApplicationRecord
5960
COMBINE_PDF_RESULT_KEY = 'combine_pdf_result_key'
6061
DOCUMENT_FILENAME_FORMAT_KEY = 'document_filename_format'
6162
TEMPLATE_CUSTOM_FIELDS_KEY = 'template_custom_fields'
63+
TEMPLATE_DATE_FORMATS_KEY = 'template_date_formats'
6264
POLICY_LINKS_KEY = 'policy_links'
6365
ENABLE_MCP_KEY = 'enable_mcp'
6466

app/views/icons/_message.html.erb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<svg xmlns="http://www.w3.org/2000/svg" class="<%= local_assigns[:class] %>" width="44" height="44" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
2+
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
3+
<path d="M8 9h8" />
4+
<path d="M8 13h6" />
5+
<path d="M18 4a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-5l-5 3v-3h-2a3 3 0 0 1 -3 -3v-8a3 3 0 0 1 3 -3h12" />
6+
</svg>

app/views/shared/_navbar.html.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
<%= svg_icon('logout', class: 'w-5 h-5 flex-shrink-0 stroke-2 inline') %>
7676
<span class="whitespace-nowrap"><%= t('sign_out') %></span>
7777
</button>
78-
<%= button_to '', destroy_user_session_path, method: :delete, data: { turbo: false }, form: { id: 'destroy_user_session_form' }, form_class: 'hidden' %>
78+
<%= button_to '', destroy_user_session_path, method: :delete, form: { id: 'destroy_user_session_form', data: { turbo: false } }, form_class: 'hidden' %>
7979
</li>
8080
</ul>
8181
</div>

app/views/shared/_settings_nav.html.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@
132132
<%= capture do %>
133133
<div class="tooltip" data-tip="<%= t('ai_assistant') %>">
134134
<a href="<%= Docuseal::CHATGPT_URL %>" target="_blank" class="btn btn-circle btn-primary btn-md">
135-
<%= svg_icon('brand_openai', class: 'w-8 h-8') %>
135+
<%= svg_icon('message', class: 'w-8 h-8') %>
136136
</a>
137137
</div>
138138
<% end %>

app/views/submissions/_send_email_base.html.erb

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
<% is_edit_viewer = local_assigns[:submitter] && local_assigns[:viewer_submitter_uuids].include?(local_assigns[:submitter].uuid) %>
4848
<div id="<%= message_field_id %>" class="card card-compact bg-base-300/40 hidden">
4949
<div class="card-body">
50-
<%= tag.input id: toggle_uuid = SecureRandom.uuid, value: '1', name: 'request_email_per_submitter', class: 'peer', type: 'checkbox', hidden: true, checked: local_assigns[:message_per_submitter] != false && template_submitters.size < 5 && template&.preferences&.dig('submitters').to_a.size > 1 %>
50+
<%= tag.input id: toggle_uuid = SecureRandom.uuid, value: '1', name: 'request_email_per_submitter', class: 'peer', type: 'checkbox', hidden: true, checked: local_assigns[:message_per_submitter] != false && template_submitters.size < 11 && template&.preferences&.dig('submitters').to_a.size > 1 %>
5151
<% if local_assigns[:viewer_submitter_uuids].present? && local_assigns[:submitter].blank? %>
5252
<% (template_submitters.pluck('uuid') - local_assigns[:viewer_submitter_uuids].to_a).each do |signer_uuid| %>
5353
<%= hidden_field_tag 'email_message_submitter_uuids[]', signer_uuid %>
@@ -57,7 +57,7 @@
5757
<div class="form-control">
5858
<div class="flex justify-between">
5959
<%= f.label :subject, t('subject'), class: 'label' %>
60-
<% if template_submitters.size > 1 && template_submitters.size < 5 && local_assigns[:message_per_submitter] != false %>
60+
<% if template_submitters.size > 1 && template_submitters.size < 11 && local_assigns[:message_per_submitter] != false %>
6161
<label for="<%= toggle_uuid %>" class="label underline">
6262
<%= t('edit_per_party') %>
6363
</label>
@@ -78,16 +78,18 @@
7878
</div>
7979
<%= render 'submissions/message_fields' %>
8080
</div>
81-
<% if template_submitters.size > 1 && template_submitters.size < 5 && local_assigns[:message_per_submitter] != false %>
81+
<% if template_submitters.size > 1 && template_submitters.size < 11 && local_assigns[:message_per_submitter] != false %>
8282
<div class="hidden peer-checked:block form-control space-y-2">
8383
<% uuid = SecureRandom.uuid %>
8484
<% options = template_submitters.map { |e| [e['name'], "request_email_#{uuid}_#{e['uuid']}"] } %>
8585
<toggle-visible data-element-ids="<%= options.map(&:last).to_json %>" class="flex relative px-1">
86-
<ul class="tabs w-full flex flex-nowrap">
86+
<ul class="tabs w-full min-w-0 flex flex-nowrap">
8787
<% options.each_with_index do |(label, val), index| %>
88-
<div class="w-full">
88+
<div class="w-full min-w-0 has-[:checked]:min-w-fit">
8989
<%= f.radio_button :selected, val, checked: index.zero?, id: "#{val}_radio", data: { action: 'click:toggle-visible#trigger' }, class: 'hidden peer' %>
90-
<%= f.label :selected, label, value: val, for: "#{val}_radio", class: 'tab w-full tab-lifted peer-checked:tab-active !bg-transparent' %>
90+
<%= f.label :selected, value: val, for: "#{val}_radio", class: 'tab w-full tab-lifted peer-checked:tab-active !bg-transparent !px-2' do %>
91+
<span class="truncate" title="<%= label %>"><%= label %></span>
92+
<% end %>
9193
</div>
9294
<% end %>
9395
</ul>

0 commit comments

Comments
 (0)