fix refactor complete button

pull/663/merge
Pete Matsyburka 1 month ago
parent 04129ded90
commit e378025a2d

@ -53,10 +53,8 @@ safeRegisterElement('submission-form', class extends HTMLElement {
completedRedirectUrl: this.dataset.completedRedirectUrl, completedRedirectUrl: this.dataset.completedRedirectUrl,
attachments: reactive(JSON.parse(this.dataset.attachments)), attachments: reactive(JSON.parse(this.dataset.attachments)),
fields: JSON.parse(this.dataset.fields), fields: JSON.parse(this.dataset.fields),
completeButtonRef: document.getElementById('complete_button_container'), completeButtonContainer: document.getElementById('complete_button_container'),
completeButtonMobileRef: document.getElementById('complete_button_container_mobile'), completeButtonScrollContainer: document.getElementById('complete_button_container_scroll')
declineButtonRef: document.getElementById('decline_button')?.closest('modal-button'),
declineButtonMobileRef: document.getElementById('decline_button_mobile')?.closest('modal-button')
}) })
this.app.mount(this.appElem) this.app.mount(this.appElem)

@ -114,12 +114,12 @@
</button> </button>
</Teleport> </Teleport>
<Teleport <Teleport
v-for="ref in (canShowCompleteButton ? [completeButtonRef, completeButtonMobileRef].filter(Boolean) : [])" v-for="ref in (showCompleteButton ? [completeButtonContainer, completeButtonScrollContainer].filter(Boolean) : [])"
:key="ref" :key="ref"
:to="ref" :to="ref"
> >
<button <button
class="btn btn-sm btn-neutral text-white px-4" class="complete-button btn btn-sm btn-neutral text-white px-4"
form="steps_form" form="steps_form"
type="submit" type="submit"
name="completed" name="completed"
@ -816,22 +816,12 @@ export default {
required: false, required: false,
default: null default: null
}, },
completeButtonRef: { completeButtonContainer: {
type: Object, type: Object,
required: false, required: false,
default: null default: null
}, },
completeButtonMobileRef: { completeButtonScrollContainer: {
type: Object,
required: false,
default: null
},
declineButtonRef: {
type: Object,
required: false,
default: null
},
declineButtonMobileRef: {
type: Object, type: Object,
required: false, required: false,
default: null default: null
@ -1053,6 +1043,7 @@ export default {
isSubmitting: false, isSubmitting: false,
isSubmittingComplete: false, isSubmittingComplete: false,
submittedValues: {}, submittedValues: {},
isFormStarted: false,
recalculateButtonDisabledKey: '', recalculateButtonDisabledKey: '',
isAccessibilityMode: false isAccessibilityMode: false
} }
@ -1101,9 +1092,9 @@ export default {
}) })
}) })
}, },
canShowCompleteButton () { showCompleteButton () {
return this.completeButtonRef && !this.emptyValueRequiredStep && !this.isCompleted && !this.isInvite && return this.completeButtonContainer && !this.isCompleted && !this.isInvite && this.isFormStarted &&
this.stepFields.some((fields) => fields.some((f) => !isEmpty(this.values[f.uuid]))) !this.stepFields.find((fields) => fields.some((f) => f.required && isEmpty(this.submittedValues[f.uuid])))
}, },
submitButtonText () { submitButtonText () {
if (this.alwaysMinimize) { if (this.alwaysMinimize) {
@ -1287,15 +1278,6 @@ export default {
this.currentStep -= 1 this.currentStep -= 1
} }
}, },
canShowCompleteButton: {
immediate: true,
handler (show) {
this.$nextTick(() => {
if (this.declineButtonRef) this.declineButtonRef.classList.toggle('hidden', show)
if (this.declineButtonMobileRef) this.declineButtonMobileRef.classList.toggle('hidden', show)
})
}
},
attachmentConditionsIndex: { attachmentConditionsIndex: {
deep: true, deep: true,
immediate: true, immediate: true,
@ -1715,6 +1697,8 @@ export default {
return Promise.reject(new Error(data.error)) return Promise.reject(new Error(data.error))
} }
this.isFormStarted = true
const nextStep = (isLastStep && emptyRequiredField) || (forceComplete ? null : this.findNextStep(submitStepIndex)) const nextStep = (isLastStep && emptyRequiredField) || (forceComplete ? null : this.findNextStep(submitStepIndex))
if (nextStep) { if (nextStep) {
@ -1751,6 +1735,7 @@ export default {
}, },
async performComplete (resp) { async performComplete (resp) {
this.isCompleted = true this.isCompleted = true
this.isFormVisible = true
if (resp?.text) { if (resp?.text) {
const respData = await resp.text() const respData = await resp.text()

@ -21,21 +21,32 @@
<h1 class="text-xl md:text-2xl font-medium focus:text-clip" style="width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;"> <h1 class="text-xl md:text-2xl font-medium focus:text-clip" style="width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">
<%= @submitter.submission.name || @submitter.submission.template.name %> <%= @submitter.submission.name || @submitter.submission.template.name %>
</h1> </h1>
<div class="flex items-center space-x-2" style="margin-left: 20px; flex-shrink: 0"> <div class="flex items-center gap-2 group" style="margin-left: 20px; flex-shrink: 0">
<span id="complete_button_container"></span> <% decline_modal_id = nil %>
<% if @form_configs[:with_decline] %>
<modal-button data-target="<%= decline_modal_id = SecureRandom.uuid %>" class="hidden group-has-[.complete-button]:flex">
<button type="button" class="btn btn-sm md:!px-5 px-2" aria-label="<%= t(:decline) %>">
<span class="hidden md:inline"><%= t(:decline) %></span>
<span class="inline md:hidden">
<%= svg_icon('x', class: 'w-5 h-5') %>
</span>
</button>
</modal-button>
<% end %>
<span id="complete_button_container" class="peer contents"></span>
<% if @form_configs[:with_delegate] %> <% if @form_configs[:with_delegate] %>
<modal-button data-target="<%= delegate_modal_id = SecureRandom.uuid %>"> <modal-button data-target="<%= delegate_modal_id = SecureRandom.uuid %>" class="hidden peer-empty:flex">
<button id="delegate_button" type="button" class="btn btn-sm !px-5"><%= t(:delegate) %></button> <button id="delegate_button" type="button" class="btn btn-sm !px-5"><%= t(:delegate) %></button>
</modal-button> </modal-button>
<% if @form_configs[:with_decline] %> <% if @form_configs[:with_decline] %>
<modal-button data-target="<%= decline_modal_id = SecureRandom.uuid %>"> <modal-button data-target="<%= decline_modal_id %>" class="hidden peer-empty:flex">
<button id="decline_button" type="button" class="btn btn-sm px-2" aria-label="<%= t(:decline) %>"> <button id="decline_button" type="button" class="btn btn-sm px-2" aria-label="<%= t(:decline) %>">
<%= svg_icon('x', class: 'w-5 h-5') %> <%= svg_icon('x', class: 'w-5 h-5') %>
</button> </button>
</modal-button> </modal-button>
<% end %> <% end %>
<% if @form_configs[:with_partial_download] %> <% if @form_configs[:with_partial_download] %>
<download-button role="button" tabindex="0" data-src="<%= submit_form_download_index_path(@submitter.slug) %>" class="btn btn-neutral text-white btn-sm px-2" title="<%= t('download') %>" aria-label="<%= t('download') %>"> <download-button role="button" tabindex="0" data-src="<%= submit_form_download_index_path(@submitter.slug) %>" class="btn btn-neutral text-white btn-sm px-2 hidden peer-empty:flex" title="<%= t('download') %>" aria-label="<%= t('download') %>">
<span data-target="download-button.defaultButton"> <span data-target="download-button.defaultButton">
<%= svg_icon('download', class: 'w-5 h-5') %> <%= svg_icon('download', class: 'w-5 h-5') %>
</span> </span>
@ -46,12 +57,12 @@
<% end %> <% end %>
<% else %> <% else %>
<% if @form_configs[:with_decline] %> <% if @form_configs[:with_decline] %>
<modal-button data-target="<%= decline_modal_id = SecureRandom.uuid %>"> <modal-button data-target="<%= decline_modal_id %>" class="hidden peer-empty:flex">
<button id="decline_button" type="button" class="btn btn-sm !px-5"><%= t(:decline) %></button> <button id="decline_button" type="button" class="btn btn-sm !px-5"><%= t(:decline) %></button>
</modal-button> </modal-button>
<% end %> <% end %>
<% if @form_configs[:with_partial_download] %> <% if @form_configs[:with_partial_download] %>
<download-button role="button" tabindex="0" data-src="<%= submit_form_download_index_path(@submitter.slug) %>" class="btn btn-neutral text-white btn-sm !px-4" aria-label="<%= t('download') %>"> <download-button role="button" tabindex="0" data-src="<%= submit_form_download_index_path(@submitter.slug) %>" class="btn btn-neutral text-white btn-sm !px-4 hidden peer-empty:flex" aria-label="<%= t('download') %>">
<span class="flex items-center justify-center" data-target="download-button.defaultButton"> <span class="flex items-center justify-center" data-target="download-button.defaultButton">
<%= svg_icon('download', class: 'w-6 h-6 inline md:hidden') %> <%= svg_icon('download', class: 'w-6 h-6 inline md:hidden') %>
<span class="hidden md:inline"><%= t('download') %></span> <span class="hidden md:inline"><%= t('download') %></span>
@ -65,10 +76,17 @@
<% end %> <% end %>
</div> </div>
</header> </header>
<scroll-buttons inert class="fixed right-5 top-2 hidden md:flex gap-1 z-50 ease-in-out opacity-0 -translate-y-10"> <scroll-buttons inert class="fixed right-5 top-2 hidden md:flex gap-1 z-50 ease-in-out opacity-0 -translate-y-10 group">
<span id="complete_button_container_mobile"></span> <% if @form_configs[:with_decline] %>
<modal-button data-target="<%= decline_modal_id %>" class="hidden group-has-[.complete-button]:flex">
<button type="button" class="btn btn-sm px-2" aria-label="<%= t(:decline) %>">
<%= svg_icon('x', class: 'w-5 h-5') %>
</button>
</modal-button>
<% end %>
<span id="complete_button_container_scroll" class="peer contents"></span>
<% if @form_configs[:with_delegate] %> <% if @form_configs[:with_delegate] %>
<modal-button data-target="<%= delegate_modal_id %>"> <modal-button data-target="<%= delegate_modal_id %>" class="hidden peer-empty:flex">
<button id="delegate_button_mobile" type="button" class="btn btn-sm px-0" aria-label="<%= t(:delegate) %>"> <button id="delegate_button_mobile" type="button" class="btn btn-sm px-0" aria-label="<%= t(:delegate) %>">
<span class="min-[1366px]:inline hidden px-3"> <span class="min-[1366px]:inline hidden px-3">
<%= t(:delegate) %> <%= t(:delegate) %>
@ -79,23 +97,15 @@
</button> </button>
</modal-button> </modal-button>
<% if @form_configs[:with_decline] %> <% if @form_configs[:with_decline] %>
<modal-button data-target="<%= decline_modal_id %>"> <modal-button data-target="<%= decline_modal_id %>" class="hidden peer-empty:flex">
<button id="decline_button_mobile" type="button" class="btn btn-sm px-2" aria-label="<%= t(:decline) %>"> <button id="decline_button_mobile" type="button" class="btn btn-sm px-2" aria-label="<%= t(:decline) %>">
<%= svg_icon('x', class: 'w-5 h-5') %> <%= svg_icon('x', class: 'w-5 h-5') %>
</button> </button>
</modal-button> </modal-button>
<% end %> <% end %>
<download-button role="button" tabindex="0" data-src="<%= submit_form_download_index_path(@submitter.slug) %>" class="btn btn-neutral text-white btn-sm px-2" aria-label="<%= t('download') %>">
<span data-target="download-button.defaultButton">
<%= svg_icon('download', class: 'w-5 h-5') %>
</span>
<span class="hidden" data-target="download-button.loadingButton">
<%= svg_icon('loader', class: 'w-5 h-5 animate-spin') %>
</span>
</download-button>
<% else %> <% else %>
<% if @form_configs[:with_decline] %> <% if @form_configs[:with_decline] %>
<modal-button data-target="<%= decline_modal_id %>"> <modal-button data-target="<%= decline_modal_id %>" class="hidden peer-empty:flex">
<button id="decline_button_mobile" type="button" class="btn btn-sm px-0" aria-label="<%= t(:decline) %>"> <button id="decline_button_mobile" type="button" class="btn btn-sm px-0" aria-label="<%= t(:decline) %>">
<span class="min-[1366px]:inline hidden px-3"> <span class="min-[1366px]:inline hidden px-3">
<%= t(:decline) %> <%= t(:decline) %>
@ -106,7 +116,8 @@
</button> </button>
</modal-button> </modal-button>
<% end %> <% end %>
<download-button role="button" tabindex="0" data-src="<%= submit_form_download_index_path(@submitter.slug) %>" class="btn btn-neutral text-white btn-sm px-2" aria-label="<%= t('download') %>"> <% end %>
<download-button role="button" tabindex="0" data-src="<%= submit_form_download_index_path(@submitter.slug) %>" class="btn btn-neutral text-white btn-sm px-2 hidden peer-empty:flex" aria-label="<%= t('download') %>">
<span data-target="download-button.defaultButton"> <span data-target="download-button.defaultButton">
<%= svg_icon('download', class: 'w-5 h-5') %> <%= svg_icon('download', class: 'w-5 h-5') %>
</span> </span>
@ -114,7 +125,6 @@
<%= svg_icon('loader', class: 'w-5 h-5 animate-spin') %> <%= svg_icon('loader', class: 'w-5 h-5 animate-spin') %>
</span> </span>
</download-button> </download-button>
<% end %>
</scroll-buttons> </scroll-buttons>
<% end %> <% end %>
<% schema.each do |item| %> <% schema.each do |item| %>

@ -1286,17 +1286,19 @@ RSpec.describe 'Signing Form' do
submission.update(template_fields: template.fields) submission.update(template_fields: template.fields)
end end
it 'shows header complete button and hides decline after filling required fields' do it 'shows header complete button and hides download after filling required fields' do
visit submit_form_path(slug: submitter.slug) visit submit_form_path(slug: submitter.slug)
expect(page).to have_button('Decline') expect(page).to have_button('Decline')
expect(page).to have_css('download-button[aria-label="Download"]', visible: true)
expect(page).not_to have_css('#complete_button_container button') expect(page).not_to have_css('#complete_button_container button')
fill_in 'First Name', with: 'John Doe' fill_in 'First Name', with: 'John Doe'
click_button 'next' click_button 'next'
expect(page).to have_css('#complete_button_container button') expect(page).to have_css('#complete_button_container button')
expect(page).not_to have_button('Decline') expect(page).to have_button('Decline')
expect(page).to have_css('download-button[aria-label="Download"]', visible: :hidden)
end end
it 'completes the form via header complete button skipping optional fields' do it 'completes the form via header complete button skipping optional fields' do

Loading…
Cancel
Save