mirror of https://github.com/docusealco/docuseal
parent
587be1bb67
commit
1da67011c4
|
After Width: | Height: | Size: 327 B |
|
After Width: | Height: | Size: 422 B |
|
Before Width: | Height: | Size: 504 B After Width: | Height: | Size: 404 B |
|
After Width: | Height: | Size: 467 B |
@ -0,0 +1,16 @@
|
||||
<html data-theme="docuseal">
|
||||
<head>
|
||||
<title>
|
||||
Docuseal
|
||||
</title>
|
||||
<%= csrf_meta_tags %>
|
||||
<%= csp_meta_tag %>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<%= javascript_pack_tag 'application', defer: true %>
|
||||
<%= stylesheet_pack_tag 'application', media: 'all' %>
|
||||
</head>
|
||||
<body>
|
||||
<% if flash.present? %><% render 'shared/flash' %><% end %>
|
||||
<%= yield %>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,11 @@
|
||||
<div id="flash" class="absolute top-0 w-full h-0">
|
||||
<div class="max-w-xl mx-auto mt-1.5">
|
||||
<div class="alert py-3">
|
||||
<%= svg_icon('info_circle', class: 'stroke-info flex-shrink-0 w-6 h-6') %>
|
||||
<div>
|
||||
<span><%= flash[:notice] || flash[:alert] %></span>
|
||||
</div>
|
||||
<a href="#" class="w-6 h-6 rounded-lg text-center hover:bg-base-300" onclick="[event.preventDefault(), window.flash.remove()]">×</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -0,0 +1,26 @@
|
||||
<div class="flex absolute text-[1.5vw] lg:text-base" style="width: <%= area['w'] * 100 %>%; height: <%= area['h'] * 100 %>%; left: <%= area['x'] * 100 %>%; top: <%= area['y'] * 100 %>%">
|
||||
<% if field['type'].in?(['signature', 'image']) %>
|
||||
<img class="object-contain mx-auto" src="<%= attachments_index[value].url %>" loading="lazy">
|
||||
<% elsif field['type'] == 'file' %>
|
||||
<div class="px-0.5 flex flex-col justify-center">
|
||||
<% Array.wrap(value).each do |val| %>
|
||||
<a target="_blank" href="<%= attachments_index[val].url %>">
|
||||
<%= svg_icon('paperclip', class: "inline w-[1.5vw] h-[1.5vw] lg:w-4 lg:h-4") %>
|
||||
<%= attachments_index[val].filename %>
|
||||
</a>
|
||||
<% end %>
|
||||
</div>
|
||||
<% elsif field['type'] == 'checkbox' %>
|
||||
<div class="w-full p-[0.2vw] flex items-center justify-center">
|
||||
<%= svg_icon('check', class: "aspect-square #{area['w'] > area['h'] ? '!w-auto !h-full' : '!w-full !h-auto'}") %>
|
||||
</div>
|
||||
<% elsif field['type'] == 'date' %>
|
||||
<div class="flex items-center px-0.5">
|
||||
<%= l(Date.parse(value)) %>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="flex items-center px-0.5">
|
||||
<%= Array.wrap(value).join(', ') %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
@ -1,73 +1,131 @@
|
||||
<div class="card card-compact bg-base-200 md:card-normal">
|
||||
<div class="card-body">
|
||||
<div>
|
||||
<h3 class="text-4xl font-bold leading-7 text-gray-900">Submission Information</h3>
|
||||
<p class="mt-2 max-w-2xl text-sm leading-6 text-gray-500">Personal details</p>
|
||||
</div>
|
||||
<div class="mt-2 border-t border-gray-300">
|
||||
<dl class="divide-y divide-gray-300">
|
||||
<div class="py-6 sm:grid sm:grid-cols-3 sm:gap-4">
|
||||
<dt class="text-sm font-medium leading-6 text-gray-900">Template</dt>
|
||||
<dd class="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0">
|
||||
<%= link_to @submission.template.name, template_submissions_path(@submission.template), class: 'link link-hover' %>
|
||||
</dd>
|
||||
</div>
|
||||
<% @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"><%= submitter.email %></dt>
|
||||
<dd class="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0">
|
||||
<%= submitter.status %>
|
||||
</dd>
|
||||
<div style="max-width: 1600px" class="mx-auto pl-4">
|
||||
<div class="flex justify-between py-1.5 items-center pr-4">
|
||||
<div class="flex space-x-3">
|
||||
<a href="/"><%= render 'shared/logo' %></a>
|
||||
<span class="text-3xl font-semibold focus:text-clip"><%= @submission.template.name %></span>
|
||||
</div>
|
||||
<div class="space-x-3 flex items-center">
|
||||
<% if last_submitter = @submission.submitters.select(&:completed_at?).max_by(&:completed_at) %>
|
||||
<download-button data-src="<%= submitter_download_index_path(last_submitter.slug) %>" class="base-button">
|
||||
<span class="flex items-center justify-center space-x-2" data-target="download-button.defaultButton">
|
||||
<%= svg_icon('download', class: 'w-6 h-6') %>
|
||||
<span>Download</span>
|
||||
</span>
|
||||
<span class="flex items-center justify-center space-x-2 hidden" data-target="download-button.loadingButton">
|
||||
<%= svg_icon('loader', class: 'w-6 h-6 animate-spin') %>
|
||||
<span>Downloading</span>
|
||||
</span>
|
||||
</download-button>
|
||||
<% 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'].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']) %>
|
||||
<ul role="list" class="divide-y divide-gray-100 rounded-md border border-gray-200">
|
||||
<% @submission.submitters.each do |submitter| %>
|
||||
<% Array.wrap(submitter.values[field['uuid']]).each do |uuid| %>
|
||||
<li class="py-4 pl-4 pr-5 text-sm leading-6">
|
||||
<div class="flex w-0 flex-1 items-center">
|
||||
<%= image_tag ActiveStorage::Attachment.find_by(uuid:).url %>
|
||||
</div>
|
||||
</li>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex" style="max-height: calc(100vh - 60px)">
|
||||
<div class="overflow-y-auto overflow-x-hidden w-52 flex-none pr-3 mt-0.5 pt-0.5">
|
||||
<% @submission.template.documents.each do |document| %>
|
||||
<a href="#<%= "page-#{document.uuid}-0" %>" onclick="[event.preventDefault(), window[event.target.closest('a').href.split('#')[1]].scrollIntoView({ behavior: 'smooth', block: 'start' })]" class="block cursor-pointer">
|
||||
<img src="<%= document.preview_images.first.url %>" width="<%= document.preview_images.first.metadata['width'] %>" height="<%= document.preview_images.first.metadata['height'] %>" class="rounded border" loading="lazy" >
|
||||
<div class="pb-2 pt-1.5 text-center">
|
||||
<%= @submission.template.schema.find { |e| e['attachment_uuid'] == document.uuid }&.dig('name').presence || attachment.filename.base %>
|
||||
</div>
|
||||
</a>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="w-full overflow-y-auto overflow-x-hidden mt-0.5 pt-0.5">
|
||||
<div class="pr-3.5 pl-0.5">
|
||||
<% fields_index = Templates.build_field_areas_index(@submission.template) %>
|
||||
<% values = @submission.submitters.reduce({}) { |acc, sub| acc.merge(sub.values) } %>
|
||||
<% attachments_index = ActiveStorage::Attachment.where(record: @submission.submitters, name: :attachments).preload(:blob).index_by(&:uuid) %>
|
||||
<% @submission.template.schema.each do |item| %>
|
||||
<% document = @submission.template.documents.find { |e| e.uuid == item['attachment_uuid'] } %>
|
||||
<% document.preview_images.sort_by { |a| a.filename.base.to_i }.each_with_index do |page, index| %>
|
||||
<div id="<%= "page-#{document.uuid}-#{index}" %>" class="relative">
|
||||
<img src="<%= page.url %>" width="<%= page.metadata['width'] %>" class="shadow-md mb-4" height="<%= page.metadata['height'] %>" loading="lazy">
|
||||
<div class="top-0 bottom-0 left-0 right-0 absolute">
|
||||
<% fields_index.dig(document.uuid, index)&.each do |(area, field)| %>
|
||||
<% value = values[field['uuid']] %>
|
||||
<% next if value.blank? %>
|
||||
<%= render 'submissions/value', area:, field:, attachments_index:, value: %>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% elsif ['attachment'].include?(field['type']) %>
|
||||
<ul role="list" class="divide-y divide-gray-100 rounded-md border border-gray-200">
|
||||
<% @submission.submitters.each do |submitter| %>
|
||||
<% Array.wrap(submitter.values[field['uuid']]).each do |uuid| %>
|
||||
<% attachment = ActiveStorage::Attachment.find_by(uuid:) %>
|
||||
<li class="flex items-center justify-between py-4 pl-4 pr-5 text-sm leading-6">
|
||||
<div class="flex w-0 flex-1 items-center">
|
||||
<%= svg_icon('paperclip', class: 'h-5 w-5 flex-shrink-0 text-gray-300') %>
|
||||
<div class="ml-4 flex min-w-0 flex-1 gap-2">
|
||||
<span class="truncate font-medium">
|
||||
<%= attachment.filename %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative w-80 flex-none pt-0.5 pr-4 pl-0.5 overflow-auto space">
|
||||
<% colors = ['bg-red-500', 'bg-sky-500', 'bg-emerald-500', 'bg-yellow-300', 'bg-purple-600'] %>
|
||||
<% submitter_fields_index = @submission.template.fields.group_by { |f| f['submitter_uuid'] } %>
|
||||
<% @submission.template.submitters.each_with_index do |item, index| %>
|
||||
<% submitter = @submission.submitters.find { |e| e.uuid == item['uuid'] } %>
|
||||
<div class="sticky -top-1 bg-base-100 pt-1 -mt-1 z-10">
|
||||
<div class="border border-base-300 rounded-md px-2 py-1 mb-1">
|
||||
<div class="flex items-center space-x-1 ">
|
||||
<span class="mx-1 w-3 h-3 rounded-full <%= colors[index] %>"></span>
|
||||
<span class="text-lg">
|
||||
<%= @submission.template.submitters.find { |e| e['uuid'] == submitter.uuid }&.dig('name') || "#{(index + 1).ordinalize} Submitter" %>
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center space-x-1 mt-1">
|
||||
<%= svg_icon('mail', class: 'w-5 h-5') %>
|
||||
<span>
|
||||
<%= submitter.email %>
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center space-x-1 mt-1">
|
||||
<%= svg_icon('writing', class: 'w-5 h-5') %>
|
||||
<span>
|
||||
<%= submitter.completed_at? ? l(submitter.completed_at, format: :long) : 'Not completed yet' %>
|
||||
</span>
|
||||
</div>
|
||||
<div class="ml-4 flex-shrink-0">
|
||||
<%= link_to 'Download', attachment.url, class: "font-medium text-indigo-600 hover:text-indigo-500" %>
|
||||
<% unless submitter.completed_at? %>
|
||||
<div class="mt-2 mb-1">
|
||||
<a class="btn btn-xs btn-primary w-full" target="_blank" href="<%= submit_form_url(slug: submitter.slug) %>">
|
||||
Submit Form
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-1.5 mb-4">
|
||||
<% submitter_field_counters = Hash.new { 0 } %>
|
||||
<% submitter_fields_index[submitter.uuid].each_with_index do |field, index| %>
|
||||
<% submitter_field_counters[field['type']] += 1 %>
|
||||
<% value = values[field['uuid']] %>
|
||||
<% next if value.blank? %>
|
||||
<div class="pt-2.5 border-b border-base-300">
|
||||
<div class="text-xs font-medium uppercase mb-0.5">
|
||||
<%= field['name'].presence || "#{field['type'].titleize} Field #{submitter_field_counters[field['type']]}" %>
|
||||
</div>
|
||||
<div>
|
||||
<% if field['type'] == 'signature' %>
|
||||
<div class="w-full bg-base-300">
|
||||
<img class="object-contain mx-auto" height="<%= attachments_index[value].metadata['height'] %>" width="<%= attachments_index[value].metadata['width'] %>" src="<%= attachments_index[value].url %>" loading="lazy">
|
||||
</div>
|
||||
<% elsif field['type'] == 'image' %>
|
||||
<img class="object-contain mx-auto max-h-28" height="<%= attachments_index[value].metadata['height'] %>" width="<%= attachments_index[value].metadata['width'] %>" src="<%= attachments_index[value].url %>" loading="lazy">
|
||||
<% elsif field['type'] == 'file' %>
|
||||
<div class="flex flex-col justify-center">
|
||||
<% Array.wrap(value).each do |val| %>
|
||||
<a target="_blank" class="flex items-center space-x-1" href="<%= attachments_index[val].url %>">
|
||||
<%= svg_icon('paperclip', class: "w-4 h-4") %>
|
||||
<span>
|
||||
<%= attachments_index[val].filename %>
|
||||
</span>
|
||||
</a>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% elsif field['type'] == 'checkbox' %>
|
||||
<%= svg_icon('check', class: "w-6 h-6") %>
|
||||
<% elsif field['type'] == 'date' %>
|
||||
<%= l(Date.parse(value)) %>
|
||||
<% else %>
|
||||
<% @submission.submitters.each do |submitter| %>
|
||||
<%= submitter.values[field['uuid']] %>
|
||||
<%= Array.wrap(value).join(', ') %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</dt>
|
||||
</div>
|
||||
<% end %>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,4 +1,20 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Templates
|
||||
module_function
|
||||
|
||||
def build_field_areas_index(template)
|
||||
hash = {}
|
||||
|
||||
template.fields.each do |field|
|
||||
(field['areas'] || []).each do |area|
|
||||
hash[area['attachment_uuid']] ||= {}
|
||||
acc = (hash[area['attachment_uuid']][area['page']] ||= [])
|
||||
|
||||
acc << [area, field]
|
||||
end
|
||||
end
|
||||
|
||||
hash
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
Reference in new issue