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

@ -9,6 +9,7 @@ import FileDropzone from './elements/file_dropzone'
import MenuActive from './elements/menu_active' import MenuActive from './elements/menu_active'
import ClipboardCopy from './elements/clipboard_copy' import ClipboardCopy from './elements/clipboard_copy'
import TemplateBuilder from './template_builder/builder' import TemplateBuilder from './template_builder/builder'
import DynamicList from './elements/dynamic_list'
document.addEventListener('turbo:before-cache', () => { document.addEventListener('turbo:before-cache', () => {
window.flash?.remove() window.flash?.remove()
@ -26,6 +27,7 @@ window.customElements.define('turbo-modal', TurboModal)
window.customElements.define('file-dropzone', FileDropzone) window.customElements.define('file-dropzone', FileDropzone)
window.customElements.define('menu-active', MenuActive) window.customElements.define('menu-active', MenuActive)
window.customElements.define('clipboard-copy', ClipboardCopy) window.customElements.define('clipboard-copy', ClipboardCopy)
window.customElements.define('dynamic-list', DynamicList)
window.customElements.define('template-builder', class extends HTMLElement { window.customElements.define('template-builder', class extends HTMLElement {
connectedCallback () { 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="enabled">
<span class="flex justify-center space-x-2"> <span class="flex items-center justify-center space-x-2">
<%= icon if icon %> <%= icon if icon %>
<span><%= title %></span> <span><%= title %></span>
</span> </span>
</span> </span>
<span class="disabled"> <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') %> <%= svg_icon('loader', class: 'w-6 h-6 animate-spin') %>
<span><%= disabled_with %>...</span> <span><%= disabled_with %>...</span>
</span> </span>

@ -7,7 +7,7 @@
<span> <span>
<%= local_assigns[:title] %> <%= local_assigns[:title] %>
</span> </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> </div>
<% end %> <% end %>
<div> <div>

@ -36,6 +36,9 @@
<th> <th>
Status Status
</th> </th>
<th>
Share Link
</th>
<th class="text-right" width="1px"> <th class="text-right" width="1px">
</th> </th>
</tr> </tr>
@ -46,6 +49,7 @@
<td> <td>
<% submission.submitters.each do |submitter| %> <% submission.submitters.each do |submitter| %>
<%= submitter.email %> <%= submitter.email %>
</br>
<% end %> <% end %>
</td> </td>
<td> <td>
@ -54,10 +58,22 @@
<span class="badge badge-info badge-outline"> <span class="badge badge-info badge-outline">
<%= submitter.status %> <%= submitter.status %>
</span> </span>
<%= link_to 'Copy', submit_form_url(slug: submitter.slug), title: 'Copy', class: 'btn btn-outline btn-xs' %>
</div> </div>
<% end %> <% end %>
</td> </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"> <td class="flex items-center space-x-2 justify-end">
<%= link_to 'View', submission_path(submission), title: 'View', class: 'btn btn-outline btn-xs' %> <%= 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?' } %> <%= 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' %> <%= f.text_area :emails, required: true, class: 'base-textarea' %>
</div> </div>
<% else %> <% else %>
<table class=""> <dynamic-list class="space-y-4">
<thead> <div class="space-y-4">
<tr> <div class="card card-compact bg-base-200" data-targets="dynamic-list.items">
<% @template.submitters.each do |item| %> <div class="card-body">
<th class="w-1/2 text-left"> <div class="absolute right-4 top-5">
<%= item['name'] %> <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">
</th> <%= svg_icon('trash', class: 'w-4 h-4') %>
<% end %> </a>
<th> </div>
</th> <div class="grid md:grid-cols-2 gap-4">
</tr> <% @template.submitters.each.with_index(1) do |item, index| %>
</thead> <div class="form-control">
<tbody> <label class="label">
<tr> <span class="label-text"> <%= item['name'] %></span>
<% @template.submitters.each do |item| %> </label>
<td> <input type="hidden" name="submission[1][submitters][<%= index %>][uuid]" value="<%= item['uuid'] %>" >
<input type="hidden" name="submission[][submitters][][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>
<input type="email" name="submission[][submitters][][email]" value="<%= item['email'] %>" required> </div>
</td>
<% end %> <% end %>
<td> </div>
&times; </div>
</td> </div>
</tr> </div>
</tbody> <a href="#" class="btn btn-primary btn-sm w-full flex items-center justify-center" data-action="click:dynamic-list#addItem">
</table> <%= svg_icon('user_plus', class: 'w-4 h-4') %>
<button> <span>Add Recipient</span>
+ Add new </a>
</button> </dynamic-list>
<% end %> <% end %>
<div class="form-control"> <div class="form-control">
<%= f.label :send_email, class: 'flex items-center cursor-pointer' do %> <%= 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' %> <%= link_to @submission.template.name, template_submissions_path(@submission.template), class: 'link link-hover' %>
</dd> </dd>
</div> </div>
<%- if @submission.completed_at.present? %> <% @submission.submitters.each do |submitter| %>
<div class="py-6 sm:grid sm:grid-cols-3 sm:gap-4"> <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"> <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> </dd>
</div> </div>
<% end %> <% end %>
<% @submission.template.fields.each do |field| %> <% @submission.template.fields.each do |field| %>
<div class="py-6 sm:grid sm:grid-cols-3 sm:gap-4"> <div class="py-6 sm:grid sm:grid-cols-3 sm:gap-4">
<dt class="text-sm font-medium leading-6 text-gray-900"> <dt class="text-sm font-medium leading-6 text-gray-900">
<%= field['name'] %> <%= field['name'].presence || "[FIELD NAME]" %>
</dt> </dt>
<dd class="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0"> <dd class="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0">
<% if ['image', 'signature'].include?(field['type']) %> <% if ['image', 'signature'].include?(field['type']) %>

Loading…
Cancel
Save