diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index c2c317e5..0b6c25f9 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -12,10 +12,15 @@ on: type: string required: false default: tonistiigi/binfmt:latest + os: + description: OS + type: string + required: false + default: ubuntu-24.04-arm jobs: build: - runs-on: ubuntu-24.04-arm + runs-on: ${{ inputs.os }} timeout-minutes: 20 steps: @@ -29,7 +34,7 @@ jobs: uses: docker/metadata-action@v4 with: images: docuseal/docuseal - tags: type=semver,pattern={{version}} + tags: latest,${{ inputs.version }} - name: Set up QEMU uses: docker/setup-qemu-action@v3 diff --git a/app/controllers/api/attachments_controller.rb b/app/controllers/api/attachments_controller.rb index 37e827b5..dca89f67 100644 --- a/app/controllers/api/attachments_controller.rb +++ b/app/controllers/api/attachments_controller.rb @@ -10,10 +10,21 @@ module Api def create submitter = Submitter.find_by!(slug: params[:submitter_slug]) - if params[:type].in?(%w[initials signature]) && ImageUtils.blank?(Vips::Image.new_from_file(params[:file].path)) - Rollbar.error("Empty signature: #{submitter.id}") if defined?(Rollbar) + if params[:type].in?(%w[initials signature]) + image = Vips::Image.new_from_file(params[:file].path) - return render json: { error: "#{params[:type]} is empty" }, status: :unprocessable_entity + if ImageUtils.blank?(image) + Rollbar.error("Empty signature: #{submitter.id}") if defined?(Rollbar) + + return render json: { error: "#{params[:type]} is empty" }, status: :unprocessable_entity + end + + if ImageUtils.error?(image) + Rollbar.error("Error signature: #{submitter.id}") if defined?(Rollbar) + + return render json: { error: "#{params[:type]} error, try to sign on another device" }, + status: :unprocessable_entity + end end attachment = Submitters.create_attachment!(submitter, params) diff --git a/app/controllers/api/submissions_controller.rb b/app/controllers/api/submissions_controller.rb index 77751066..f75d7299 100644 --- a/app/controllers/api/submissions_controller.rb +++ b/app/controllers/api/submissions_controller.rb @@ -185,7 +185,7 @@ module Api message: %i[subject body], submitters: [[:send_email, :send_sms, :completed_redirect_url, :uuid, :name, :email, :role, :completed, :phone, :application_key, :external_id, :reply_to, :go_to_last, - :require_phone_2fa, + :require_phone_2fa, :order, { metadata: {}, values: {}, roles: [], readonly_fields: [], message: %i[subject body], fields: [:name, :uuid, :default_value, :value, :title, :description, :readonly, :required, :validation_pattern, :invalid_message, diff --git a/app/controllers/api/templates_controller.rb b/app/controllers/api/templates_controller.rb index 88a606f4..7847e599 100644 --- a/app/controllers/api/templates_controller.rb +++ b/app/controllers/api/templates_controller.rb @@ -106,7 +106,7 @@ module Api :external_id, :shared_link, { - submitters: [%i[name uuid is_requester invite_by_uuid optional_invite_by_uuid linked_to_uuid email]], + submitters: [%i[name uuid is_requester invite_by_uuid optional_invite_by_uuid linked_to_uuid email order]], fields: [[:uuid, :submitter_uuid, :name, :type, :required, :readonly, :default_value, :title, :description, :prefillable, diff --git a/app/controllers/templates_controller.rb b/app/controllers/templates_controller.rb index 73e68e85..a3d78606 100644 --- a/app/controllers/templates_controller.rb +++ b/app/controllers/templates_controller.rb @@ -117,7 +117,7 @@ class TemplatesController < ApplicationController params.require(:template).permit( :name, { schema: [[:attachment_uuid, :name, { conditions: [%i[field_uuid value action operation]] }]], - submitters: [%i[name uuid is_requester linked_to_uuid invite_by_uuid optional_invite_by_uuid email]], + submitters: [%i[name uuid is_requester linked_to_uuid invite_by_uuid optional_invite_by_uuid email order]], fields: [[:uuid, :submitter_uuid, :name, :type, :required, :readonly, :default_value, :title, :description, :prefillable, diff --git a/app/controllers/templates_recipients_controller.rb b/app/controllers/templates_recipients_controller.rb index a1298094..17a4bbb8 100644 --- a/app/controllers/templates_recipients_controller.rb +++ b/app/controllers/templates_recipients_controller.rb @@ -9,6 +9,10 @@ class TemplatesRecipientsController < ApplicationController @template.submitters = submitters_params.map { |s| s.reject { |_, v| v.is_a?(String) && v.blank? } } + if @template.submitters.each_with_index.all? { |s, index| s['order'] == index } + @template.submitters.each { |s| s.delete('order') } + end + @template.save! render json: { submitters: @template.submitters } @@ -18,7 +22,7 @@ class TemplatesRecipientsController < ApplicationController def submitters_params permit_params = { submitters: [%i[name uuid is_requester optional_invite_by_uuid - invite_by_uuid linked_to_uuid email option]] } + invite_by_uuid linked_to_uuid email option order]] } params.require(:template).permit(permit_params).fetch(:submitters, {}).values.filter_map do |s| next if s[:uuid].blank? @@ -29,6 +33,7 @@ class TemplatesRecipientsController < ApplicationController s.delete(:is_requester) end + s[:order] = s[:order].to_i if s[:order].present? s.delete(:invite_by_uuid) if s[:invite_by_uuid].blank? s.delete(:optional_invite_by_uuid) if s[:optional_invite_by_uuid].blank? diff --git a/app/javascript/application.js b/app/javascript/application.js index dda88f7a..7b51186d 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -38,6 +38,7 @@ import DashboardDropzone from './elements/dashboard_dropzone' import RequiredCheckboxGroup from './elements/required_checkbox_group' import PageContainer from './elements/page_container' import EmailEditor from './elements/email_editor' +import MountOnClick from './elements/mount_on_click' import * as TurboInstantClick from './lib/turbo_instant_click' @@ -111,6 +112,7 @@ safeRegisterElement('check-on-click', CheckOnClick) safeRegisterElement('required-checkbox-group', RequiredCheckboxGroup) safeRegisterElement('page-container', PageContainer) safeRegisterElement('email-editor', EmailEditor) +safeRegisterElement('mount-on-click', MountOnClick) safeRegisterElement('template-builder', class extends HTMLElement { connectedCallback () { diff --git a/app/javascript/elements/mount_on_click.js b/app/javascript/elements/mount_on_click.js new file mode 100644 index 00000000..3a71f8ff --- /dev/null +++ b/app/javascript/elements/mount_on_click.js @@ -0,0 +1,11 @@ +export default class extends HTMLElement { + connectedCallback () { + this.addEventListener('click', () => { + document.body.append(this.template.content) + }) + } + + get template () { + return document.getElementById(this.dataset.templateId) + } +} diff --git a/app/javascript/submission_form/signature_step.vue b/app/javascript/submission_form/signature_step.vue index d1625726..519b77fe 100644 --- a/app/javascript/submission_form/signature_step.vue +++ b/app/javascript/submission_form/signature_step.vue @@ -21,7 +21,7 @@
-