add multiple submitters input form

pull/105/head
Alex Turchyn 2 years ago
parent 96508cd1ee
commit 662d052904

@ -57,10 +57,10 @@ class SubmissionsController < ApplicationController
end
def create_submissions_from_submitters
submissions_params.map do |attrs|
submissions_params[:submission].to_h.map do |_, attrs|
submission = @template.submissions.new
attrs[:submitters].each do |submitter_attrs|
attrs[:submitters].each do |_, submitter_attrs|
submission.submitters.new(**submitter_attrs, sent_at: params[:send_email] == '1' ? Time.current : nil)
end
@ -69,7 +69,7 @@ class SubmissionsController < ApplicationController
end
def submissions_params
params.require(:submission).map { |param| param.permit(submitters: [%i[uuid email]]) }
params.permit(submission: { submitters: %i[uuid email] })
end
def load_template

@ -9,6 +9,7 @@ import FileDropzone from './elements/file_dropzone'
import MenuActive from './elements/menu_active'
import ClipboardCopy from './elements/clipboard_copy'
import TemplateBuilder from './template_builder/builder'
import DynamicList from './elements/dynamic_list'
document.addEventListener('turbo:before-cache', () => {
window.flash?.remove()
@ -26,6 +27,7 @@ window.customElements.define('turbo-modal', TurboModal)
window.customElements.define('file-dropzone', FileDropzone)
window.customElements.define('menu-active', MenuActive)
window.customElements.define('clipboard-copy', ClipboardCopy)
window.customElements.define('dynamic-list', DynamicList)
window.customElements.define('template-builder', class extends HTMLElement {
connectedCallback () {

@ -0,0 +1,33 @@
import { actionable } from '@github/catalyst/lib/actionable'
import { targets, targetable } from '@github/catalyst/lib/targetable'
export default actionable(targetable(class extends HTMLElement {
static [targets.static] = ['items']
addItem = (e) => {
e.preventDefault()
const originalItem = this.items[0]
const duplicateItem = originalItem.cloneNode(true)
const uniqueId = Math.floor(Math.random() * 10 ** 16)
duplicateItem.querySelectorAll("select, textarea, input:not([type='hidden'])").forEach((input) => {
input.value = ''
input.checked = false
input.removeAttribute('selected')
})
duplicateItem.querySelectorAll('select, textarea, input').forEach((input) => {
input.name = input.name.replace('[1]', `[${uniqueId}]`)
})
duplicateItem.querySelectorAll('a.hidden').forEach((button) => button.classList.toggle('hidden'))
originalItem.parentNode.append(duplicateItem)
}
removeItem = (e) => {
e.preventDefault()
this.items.find((item) => item.contains(e.target))?.remove()
}
}))

@ -0,0 +1,8 @@
<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">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
<path d="M4 7l16 0" />
<path d="M10 11l0 6" />
<path d="M14 11l0 6" />
<path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12" />
<path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3" />
</svg>

After

Width:  |  Height:  |  Size: 477 B

@ -0,0 +1,8 @@
<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">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
<path d="M5 7a4 4 0 1 0 8 0a4 4 0 0 0 -8 0" />
<path d="M3 21v-2a4 4 0 0 1 4 -4h4c.96 0 1.84 .338 2.53 .901" />
<path d="M16 3.13a4 4 0 0 1 0 7.75" />
<path d="M16 19h6" />
<path d="M19 16v6" />
</svg>

After

Width:  |  Height:  |  Size: 487 B

@ -1,11 +1,11 @@
<span class="enabled">
<span class="flex justify-center space-x-2">
<span class="flex items-center justify-center space-x-2">
<%= icon if icon %>
<span><%= title %></span>
</span>
</span>
<span class="disabled">
<span class="flex justify-center space-x-2">
<span class="flex items-center justify-center space-x-2">
<%= svg_icon('loader', class: 'w-6 h-6 animate-spin') %>
<span><%= disabled_with %>...</span>
</span>

@ -7,7 +7,7 @@
<span>
<%= local_assigns[:title] %>
</span>
<a href="#" class="text-xl" data-action="click:turbo-modal#close">&times;</a>
<a href="#" class="w-8 h-8 flex items-center justify-center text-xl rounded-lg text-center hover:bg-base-300" data-action="click:turbo-modal#close">&times;</a>
</div>
<% end %>
<div>

@ -36,6 +36,9 @@
<th>
Status
</th>
<th>
Share Link
</th>
<th class="text-right" width="1px">
</th>
</tr>
@ -46,6 +49,7 @@
<td>
<% submission.submitters.each do |submitter| %>
<%= submitter.email %>
</br>
<% end %>
</td>
<td>
@ -54,10 +58,22 @@
<span class="badge badge-info badge-outline">
<%= submitter.status %>
</span>
<%= link_to 'Copy', submit_form_url(slug: submitter.slug), title: 'Copy', class: 'btn btn-outline btn-xs' %>
</div>
<% end %>
</td>
<td>
<% submission.submitters.each do |submitter| %>
<% share_link_input_id = "share-link-input_#{submitter.id}" %>
<div class="join ">
<input id="<%= share_link_input_id %>" autocomplete="off" type="text" class="input input-xs input-bordered join-item" value="<%= submit_form_url(slug: submitter.slug) %>" disabled>
<clipboard-copy class="btn btn-xs btn-neutral btn-square join-item text-white font-bold swap swap-active" for="<%= share_link_input_id %>">
<%= svg_icon('clipboard', class: 'w-3 h-3 swap-on text-white') %>
<%= svg_icon('clipboard_copy', class: 'w-3 h-3 swap-off text-white') %>
</clipboard-copy>
</div>
<br/>
<% end %>
</td>
<td class="flex items-center space-x-2 justify-end">
<%= link_to 'View', submission_path(submission), title: 'View', class: 'btn btn-outline btn-xs' %>
<%= button_to 'Remove', submission_path(submission), class: 'btn btn-outline btn-error btn-xs', title: 'Delete', method: :delete, data: { turbo_confirm: 'Are you sure?' } %>

@ -6,35 +6,34 @@
<%= f.text_area :emails, required: true, class: 'base-textarea' %>
</div>
<% else %>
<table class="">
<thead>
<tr>
<% @template.submitters.each do |item| %>
<th class="w-1/2 text-left">
<%= item['name'] %>
</th>
<% end %>
<th>
</th>
</tr>
</thead>
<tbody>
<tr>
<% @template.submitters.each do |item| %>
<td>
<input type="hidden" name="submission[][submitters][][uuid]" value="<%= item['uuid'] %>" >
<input type="email" name="submission[][submitters][][email]" value="<%= item['email'] %>" required>
</td>
<dynamic-list class="space-y-4">
<div class="space-y-4">
<div class="card card-compact bg-base-200" data-targets="dynamic-list.items">
<div class="card-body">
<div class="absolute right-4 top-5">
<a href="#" data-action="click:dynamic-list#removeItem" class="block w-6 h-6 rounded-lg text-neutral-700 text-center bg-base-300 p-1 hidden hover:bg-neutral hover:text-white">
<%= svg_icon('trash', class: 'w-4 h-4') %>
</a>
</div>
<div class="grid md:grid-cols-2 gap-4">
<% @template.submitters.each.with_index(1) do |item, index| %>
<div class="form-control">
<label class="label">
<span class="label-text"> <%= item['name'] %></span>
</label>
<input type="hidden" name="submission[1][submitters][<%= index %>][uuid]" value="<%= item['uuid'] %>" >
<input type="email" name="submission[1][submitters][<%= index %>][email]" value="<%= item['email'] %>" class="input input-sm input-bordered" placeholder="Email" required>
</div>
<% end %>
<td>
&times;
</td>
</tr>
</tbody>
</table>
<button>
+ Add new
</button>
</div>
</div>
</div>
</div>
<a href="#" class="btn btn-primary btn-sm w-full flex items-center justify-center" data-action="click:dynamic-list#addItem">
<%= svg_icon('user_plus', class: 'w-4 h-4') %>
<span>Add Recipient</span>
</a>
</dynamic-list>
<% end %>
<div class="form-control">
<%= f.label :send_email, class: 'flex items-center cursor-pointer' do %>

@ -12,18 +12,18 @@
<%= link_to @submission.template.name, template_submissions_path(@submission.template), class: 'link link-hover' %>
</dd>
</div>
<%- if @submission.completed_at.present? %>
<% @submission.submitters.each do |submitter| %>
<div class="py-6 sm:grid sm:grid-cols-3 sm:gap-4">
<dt class="text-sm font-medium leading-6 text-gray-900">Completed at</dt>
<dt class="text-sm font-medium leading-6 text-gray-900"><%= submitter.email %></dt>
<dd class="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0">
<%= l(@submission.completed_at, format: :long) %>
<%= submitter.status %>
</dd>
</div>
<% end %>
<% @submission.template.fields.each do |field| %>
<div class="py-6 sm:grid sm:grid-cols-3 sm:gap-4">
<dt class="text-sm font-medium leading-6 text-gray-900">
<%= field['name'] %>
<%= field['name'].presence || "[FIELD NAME]" %>
</dt>
<dd class="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0">
<% if ['image', 'signature'].include?(field['type']) %>

Loading…
Cancel
Save