mirror of https://github.com/docusealco/docuseal
parent
98fc9d964a
commit
4a303cb423
@ -1,22 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module Api
|
|
||||||
class FlowsController < ApiBaseController
|
|
||||||
def update
|
|
||||||
@flow = current_account.flows.find(params[:id])
|
|
||||||
|
|
||||||
@flow.update!(flow_params)
|
|
||||||
|
|
||||||
render :ok
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def flow_params
|
|
||||||
params.require(:flow).permit(:name,
|
|
||||||
schema: [%i[attachment_uuid name]],
|
|
||||||
fields: [[:uuid, :name, :type, :required,
|
|
||||||
{ options: [], areas: [%i[x y w h attachment_uuid page]] }]])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Api
|
||||||
|
class TemplatesController < ApiBaseController
|
||||||
|
def update
|
||||||
|
@template = current_account.templates.find(params[:id])
|
||||||
|
|
||||||
|
@template.update!(template_params)
|
||||||
|
|
||||||
|
render :ok
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def template_params
|
||||||
|
params.require(:template).permit(:name,
|
||||||
|
schema: [%i[attachment_uuid name]],
|
||||||
|
fields: [[:uuid, :name, :type, :required,
|
||||||
|
{ options: [], areas: [%i[x y w h attachment_uuid page]] }]])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -1,17 +1,17 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Api
|
module Api
|
||||||
class FlowsDocumentsController < ApiBaseController
|
class TemplatesDocumentsController < ApiBaseController
|
||||||
def create
|
def create
|
||||||
@flow = current_account.flows.find(params[:flow_id])
|
@template = current_account.templates.find(params[:template_id])
|
||||||
|
|
||||||
documents =
|
documents =
|
||||||
params[:blobs].map do |blob|
|
params[:blobs].map do |blob|
|
||||||
blob = ActiveStorage::Blob.find_signed(blob[:signed_id])
|
blob = ActiveStorage::Blob.find_signed(blob[:signed_id])
|
||||||
|
|
||||||
document = @flow.documents.create!(blob:)
|
document = @template.documents.create!(blob:)
|
||||||
|
|
||||||
Flows::ProcessDocument.call(document)
|
Templates::ProcessDocument.call(document)
|
||||||
end
|
end
|
||||||
|
|
||||||
schema = documents.map do |doc|
|
schema = documents.map do |doc|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class FlowsController < ApplicationController
|
|
||||||
layout false
|
|
||||||
|
|
||||||
def show
|
|
||||||
@flow = current_account.flows.preload(documents_attachments: { preview_images_attachments: :blob })
|
|
||||||
.find(params[:id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def new
|
|
||||||
@flow = current_account.flows.new
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@flow = current_account.flows.new(flow_params)
|
|
||||||
@flow.author = current_user
|
|
||||||
|
|
||||||
if @flow.save
|
|
||||||
redirect_to flow_path(@flow)
|
|
||||||
else
|
|
||||||
render turbo_stream: turbo_stream.replace(:modal, template: 'flows/new'), status: :unprocessable_entity
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
@flow = current_account.flows.find(params[:id])
|
|
||||||
@flow.update!(deleted_at: Time.current)
|
|
||||||
|
|
||||||
redirect_to settings_users_path, notice: 'Flow has been archived.'
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def flow_params
|
|
||||||
params.require(:flow).permit(:name, :schema)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class TemplatesController < ApplicationController
|
||||||
|
layout false
|
||||||
|
|
||||||
|
def show
|
||||||
|
@template = current_account.templates.preload(documents_attachments: { preview_images_attachments: :blob })
|
||||||
|
.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@template = current_account.templates.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@template = current_account.templates.new(template_params)
|
||||||
|
@template.author = current_user
|
||||||
|
|
||||||
|
if @template.save
|
||||||
|
redirect_to template_path(@template)
|
||||||
|
else
|
||||||
|
render turbo_stream: turbo_stream.replace(:modal, template: 'templates/new'), status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@template = current_account.templates.find(params[:id])
|
||||||
|
@template.update!(deleted_at: Time.current)
|
||||||
|
|
||||||
|
redirect_to settings_users_path, notice: 'template has been archived.'
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def template_params
|
||||||
|
params.require(:template).permit(:name, :schema)
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -1,12 +1,12 @@
|
|||||||
import { createApp, reactive } from 'vue'
|
import { createApp, reactive } from 'vue'
|
||||||
|
|
||||||
import Flow from './flow_form/form'
|
import Form from './submission_form/form'
|
||||||
|
|
||||||
window.customElements.define('flow-form', class extends HTMLElement {
|
window.customElements.define('submission-form', class extends HTMLElement {
|
||||||
connectedCallback () {
|
connectedCallback () {
|
||||||
this.appElem = document.createElement('div')
|
this.appElem = document.createElement('div')
|
||||||
|
|
||||||
this.app = createApp(Flow, {
|
this.app = createApp(Form, {
|
||||||
submissionSlug: this.dataset.submissionSlug,
|
submissionSlug: this.dataset.submissionSlug,
|
||||||
authenticityToken: this.dataset.authenticityToken,
|
authenticityToken: this.dataset.authenticityToken,
|
||||||
values: reactive(JSON.parse(this.dataset.values)),
|
values: reactive(JSON.parse(this.dataset.values)),
|
||||||
@ -1,4 +1,4 @@
|
|||||||
@config "../../tailwind.flow.config.js";
|
@config "../../tailwind.form.config.js";
|
||||||
|
|
||||||
@import "tailwindcss/base";
|
@import "tailwindcss/base";
|
||||||
@import "tailwindcss/components";
|
@import "tailwindcss/components";
|
||||||
@ -1,10 +1,10 @@
|
|||||||
<div class="max-w-6xl mx-auto px-2 py-3">
|
<div class="max-w-6xl mx-auto px-2 py-3">
|
||||||
<%= link_to 'Create Flow', new_flow_path, data: { turbo_frame: :modal } %>
|
<%= link_to 'Create Template', new_template_path, data: { turbo_frame: :modal } %>
|
||||||
<% @flows.each do |flow| %>
|
<% @templates.each do |template| %>
|
||||||
<div>
|
<div>
|
||||||
<%= flow.name %> |
|
<%= template.name %> |
|
||||||
<a href="<%= flow_path(flow) %>">edit</a> |
|
<a href="<%= template_path(template) %>">edit</a> |
|
||||||
<a href="<%= flow_submissions_path(flow) %>">submissions</a> |
|
<a href="<%= template_submissions_path(template) %>">submissions</a> |
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,10 +0,0 @@
|
|||||||
<%= render 'shared/turbo_modal', title: 'New Flow' do %>
|
|
||||||
<%= form_for @flow, data: { turbo_frame: :_top } do |f| %>
|
|
||||||
<div class="form-control my-6">
|
|
||||||
<%= f.text_field :name, required: true, placeholder: 'Flow Name', class: 'base-input' %>
|
|
||||||
</div>
|
|
||||||
<div class="form-control mt-4">
|
|
||||||
<%= f.button button_title('Create'), class: 'base-button' %>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
<% end %>
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
You have been invited to submit flow <%= @flow.name %>
|
|
||||||
<%= form_for @submission, url: start_flow_path(@flow.slug), data: { turbo_frame: :_top }, method: :put do |f| %>
|
|
||||||
Provide youe email to start
|
|
||||||
<div>
|
|
||||||
<%= f.label :email %>
|
|
||||||
<%= f.email_field :email, required: true %>
|
|
||||||
</div>
|
|
||||||
<%= f.button button_title %>
|
|
||||||
<% end %>
|
|
||||||
@ -1,5 +1,5 @@
|
|||||||
<p>
|
<p>
|
||||||
Form has been submitted alredy by ypu - thanks!
|
Form has been submitted alredy by ypu - thanks!
|
||||||
</p>
|
</p>
|
||||||
<%= button_to button_title('Send copy to Email'), send_submission_email_index_path, params: { flow_slug: @flow.slug, email: params[:email] }, form: { onsubmit: 'event.submitter.disabled = true' } %>
|
<%= button_to button_title('Send copy to Email'), send_submission_email_index_path, params: { template_slug: @template.slug, email: params[:email] }, form: { onsubmit: 'event.submitter.disabled = true' } %>
|
||||||
<%# do not allow donwload for securetiy reaosn<a href="">Download documets</a> %>
|
<%# do not allow donwload for securetiy reaosn<a href="">Download documets</a> %>
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
You have been invited to submit template <%= @template.name %>
|
||||||
|
<%= form_for @submission, url: start_form_path(@template.slug), data: { turbo_frame: :_top }, method: :put do |f| %>
|
||||||
|
Provide youe email to start
|
||||||
|
<div>
|
||||||
|
<%= f.label :email %>
|
||||||
|
<%= f.email_field :email, required: true %>
|
||||||
|
</div>
|
||||||
|
<%= f.button button_title %>
|
||||||
|
<% end %>
|
||||||
@ -1,4 +1,4 @@
|
|||||||
<p>Hi there</p>
|
<p>Hi there</p>
|
||||||
<p>You have been invited to submit a form:</p>
|
<p>You have been invited to submit a form:</p>
|
||||||
<p><%= link_to 'Submit', submit_flow_index_url(slug: @submission.slug) %></p>
|
<p><%= link_to 'Submit', submit_form_index_url(slug: @submission.slug) %></p>
|
||||||
<p>If you didn't request this, please ignore this email.</p>
|
<p>If you didn't request this, please ignore this email.</p>
|
||||||
|
|||||||
@ -1,18 +0,0 @@
|
|||||||
<% attachment_field_uuids = @submission.flow.fields.select { |f| f['type'].in?(%w[image signature attachment]) }.pluck('uuid') %>
|
|
||||||
<% attachments = ActiveStorage::Attachment.where(uuid: @submission.values.values_at(*attachment_field_uuids).flatten).preload(:blob) %>
|
|
||||||
<flow-view class="mx-auto block" style="max-width: 1000px">
|
|
||||||
<% @submission.flow.schema.each do |item| %>
|
|
||||||
<% document = @submission.flow.documents.find { |a| a.uuid == item['attachment_uuid'] } %>
|
|
||||||
<% document.preview_images.sort_by { |a| a.filename.base.to_i }.each_with_index do |page, index| %>
|
|
||||||
<div class="relative">
|
|
||||||
<img src="<%= page.url %>" width="<%= page.metadata['width'] %>" height="<%= page.metadata['height'] %>" loading="lazy">
|
|
||||||
<div id="page-<%= [document.uuid, index].join('-') %>" class="top-0 bottom-0 left-0 right-0 absolute"></div>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
<% end %>
|
|
||||||
<div class="sticky bottom-8 w-full">
|
|
||||||
<div class="bg-white mx-8 md:mx-32 border p-4 rounded">
|
|
||||||
<flow-form data-submission-slug="<%= @submission.slug %>" data-attachments="<%= attachments.to_json(only: %i[uuid], methods: %i[url filename content_type]) %>" data-fields="<%= @submission.flow.fields.to_json %>" data-values="<%= @submission.values.to_json %>" data-authenticity-token="<%= form_authenticity_token %>"></flow-form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</flow-view>
|
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
<% attachment_field_uuids = @submission.template.fields.select { |f| f['type'].in?(%w[image signature attachment]) }.pluck('uuid') %>
|
||||||
|
<% attachments = ActiveStorage::Attachment.where(uuid: @submission.values.values_at(*attachment_field_uuids).flatten).preload(:blob) %>
|
||||||
|
<div class="mx-auto block" style="max-width: 1000px">
|
||||||
|
<% @submission.template.schema.each do |item| %>
|
||||||
|
<% document = @submission.template.documents.find { |a| a.uuid == item['attachment_uuid'] } %>
|
||||||
|
<% document.preview_images.sort_by { |a| a.filename.base.to_i }.each_with_index do |page, index| %>
|
||||||
|
<div class="relative">
|
||||||
|
<img src="<%= page.url %>" width="<%= page.metadata['width'] %>" height="<%= page.metadata['height'] %>" loading="lazy">
|
||||||
|
<div id="page-<%= [document.uuid, index].join('-') %>" class="top-0 bottom-0 left-0 right-0 absolute"></div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
<div class="sticky bottom-8 w-full">
|
||||||
|
<div class="bg-white mx-8 md:mx-32 border p-4 rounded">
|
||||||
|
<submission-form data-submission-slug="<%= @submission.slug %>" data-attachments="<%= attachments.to_json(only: %i[uuid], methods: %i[url filename content_type]) %>" data-fields="<%= @submission.template.fields.to_json %>" data-values="<%= @submission.values.to_json %>" data-authenticity-token="<%= form_authenticity_token %>"></submission-form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
<%= render 'shared/turbo_modal', title: 'New Template' do %>
|
||||||
|
<%= form_for @template, data: { turbo_frame: :_top } do |f| %>
|
||||||
|
<div class="form-control my-6">
|
||||||
|
<%= f.text_field :name, required: true, placeholder: 'Template Name', class: 'base-input' %>
|
||||||
|
</div>
|
||||||
|
<div class="form-control mt-4">
|
||||||
|
<%= f.button button_title('Create'), class: 'base-button' %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
@ -1,8 +1,8 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class CreateFlows < ActiveRecord::Migration[7.0]
|
class CreateTemplates < ActiveRecord::Migration[7.0]
|
||||||
def change
|
def change
|
||||||
create_table :flows do |t|
|
create_table :templates do |t|
|
||||||
t.string :slug, null: false, index: { unique: true }
|
t.string :slug, null: false, index: { unique: true }
|
||||||
t.string :name, null: false
|
t.string :name, null: false
|
||||||
t.string :schema, null: false
|
t.string :schema, null: false
|
||||||
@ -1,20 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module Flows
|
|
||||||
module_function
|
|
||||||
|
|
||||||
def build_field_areas_index(flow)
|
|
||||||
hash = {}
|
|
||||||
|
|
||||||
flow.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
|
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Templates
|
||||||
|
end
|
||||||
@ -1,6 +1,6 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Flows
|
module Templates
|
||||||
module ProcessDocument
|
module ProcessDocument
|
||||||
DPI = 200
|
DPI = 200
|
||||||
FORMAT = '.jpg'
|
FORMAT = '.jpg'
|
||||||
Loading…
Reference in new issue