- <% if has_archived || @pagy.count > 0 || @template_folders.present? %>
-
- <%= render 'dashboard/toggle_view', selected: 'templates' %>
-
+
+ <% unless show_dropzone %>
+ <%= render 'templates/dashboard_dropzone', style: 'height: 114px' %>
<% end %>
-
- <%= t('document_templates_html') %>
-
+
+ <% if has_archived || @pagy.count > 0 || @template_folders.present? %>
+
+ <%= render 'dashboard/toggle_view', selected: 'templates' %>
+
+ <% end %>
+
+ <%= t('document_templates_html') %>
+
+
+
+ <% if params[:q].present? || @pagy.pages > 1 || @template_folders.present? %>
+ <%= render 'shared/search_input' %>
+ <% end %>
+ <% if can?(:create, ::Template) %>
+
+ <%= render 'templates/upload_button' %>
+
+ <%= link_to new_template_path, class: 'white-button !border gap-2', data: { turbo_frame: :modal } do %>
+ <%= svg_icon('plus', class: 'w-6 h-6 stroke-2') %>
+ <%= t('create') %>
+ <% end %>
+ <% end %>
+
-
- <% if params[:q].present? || @pagy.pages > 1 || @template_folders.present? %>
- <%= render 'shared/search_input' %>
+ <% view_archived_html = capture do %>
+ <% if has_archived %>
+
<% end %>
- <% if can?(:create, ::Template) %>
-
- <%= render 'templates/upload_button' %>
-
- <%= link_to new_template_path, class: 'white-button !border gap-2', data: { turbo_frame: :modal } do %>
- <%= svg_icon('plus', class: 'w-6 h-6 stroke-2') %>
-
<%= t('create') %>
- <% end %>
+ <% end %>
+ <% templates_order_select_html = capture do %>
+ <% if params[:q].blank? && @pagy.pages > 1 %>
+ <%= render('shared/templates_order_select', with_recently_used: @pagy.count < 10_000) %>
<% end %>
-
-
-<% view_archived_html = capture do %>
- <% if has_archived %>
-
+ <%= render partial: 'template_folders/folder', collection: @template_folders, as: :folder %>
+
<% end %>
-<% end %>
-<% if @template_folders.present? %>
-
- <%= render partial: 'template_folders/folder', collection: @template_folders, as: :folder %>
-
-<% end %>
-<% if @templates.present? %>
-
- <%= render partial: 'templates/template', collection: @templates %>
- <% if show_dropzone && current_user.created_at > 2.weeks.ago || params[:tour] == 'true' %>
- <% user_config = current_user.user_configs.find_or_initialize_by(key: UserConfig::SHOW_APP_TOUR) %>
- <% if user_config.new_record? || user_config.value || params[:tour] == 'true' %>
-
-
- <% if user_config.new_record? && !params.key?(:tour) %>
-
-
- <%= t('welcome_to_docuseal') %>
-
-
- <%= t('start_a_quick_tour_to_learn_how_to_create_an_send_your_first_document') %>
-
-
- <%= button_to button_title(title: t('skip'), icon_disabled: svg_icon('loader', class: 'w-4 h-4 animate-spin')), user_configs_path, params: { user_config: { key: UserConfig::SHOW_APP_TOUR, value: false } }, class: 'btn btn-sm btn-outline w-full', form_class: 'flex-1', method: :post, form: { onsubmit: 'window.app_tour.parentNode.remove()' } %>
- <%= button_to t('start_tour'), user_configs_path, params: { user_config: { key: UserConfig::SHOW_APP_TOUR, value: true } }, class: 'btn btn-sm btn-warning w-full', form_class: 'flex-1', method: :post, form: { onsubmit: 'window.app_tour.start()' } %>
+ <% if @templates.present? %>
+
+ <%= render partial: 'templates/template', collection: @templates %>
+ <% if show_dropzone && current_user.created_at > 2.weeks.ago || params[:tour] == 'true' %>
+ <% user_config = current_user.user_configs.find_or_initialize_by(key: UserConfig::SHOW_APP_TOUR) %>
+ <% if user_config.new_record? || user_config.value || params[:tour] == 'true' %>
+
+
+ <% if user_config.new_record? && !params.key?(:tour) %>
+
+
+ <%= t('welcome_to_docuseal') %>
+
+
+ <%= t('start_a_quick_tour_to_learn_how_to_create_an_send_your_first_document') %>
+
+
+ <%= button_to button_title(title: t('skip'), icon_disabled: svg_icon('loader', class: 'w-4 h-4 animate-spin')), user_configs_path, params: { user_config: { key: UserConfig::SHOW_APP_TOUR, value: false } }, class: 'btn btn-sm btn-outline w-full', form_class: 'flex-1', method: :post, form: { onsubmit: 'window.app_tour.parentNode.remove()' } %>
+ <%= button_to t('start_tour'), user_configs_path, params: { user_config: { key: UserConfig::SHOW_APP_TOUR, value: true } }, class: 'btn btn-sm btn-warning w-full', form_class: 'flex-1', method: :post, form: { onsubmit: 'window.app_tour.start()' } %>
+
-
- <% end %>
-
+ <% end %>
+
+ <% end %>
<% end %>
- <% end %>
-
-<% end %>
+
+ <% end %>
+
<% if show_dropzone %>
<%= render 'templates/dropzone' %>
<% end %>
diff --git a/config/locales/i18n.yml b/config/locales/i18n.yml
index 537edeb1..dbb83882 100644
--- a/config/locales/i18n.yml
+++ b/config/locales/i18n.yml
@@ -717,7 +717,7 @@ en: &en
name_a_z: Name A-Z
recently_used: Recently used
newest_first: Newest first
- upload_new_based_on_template: Upload new based on template
+ create_base_on_template: Create based on template
submission_sources:
api: API
bulk: Bulk Send
diff --git a/config/routes.rb b/config/routes.rb
index 8adb31f4..ba05e364 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -97,7 +97,7 @@ Rails.application.routes.draw do
resources :templates, only: %i[new create edit update show destroy] do
resource :debug, only: %i[show], controller: 'templates_debug' if Rails.env.development?
resources :documents, only: %i[create], controller: 'template_documents'
- resources :replace_documents, only: %i[create], controller: 'template_replace_documents'
+ resources :clone_and_replace, only: %i[create], controller: 'templates_clone_and_replace'
resources :restore, only: %i[create], controller: 'templates_restore'
resources :archived, only: %i[index], controller: 'templates_archived_submissions'
resources :submissions, only: %i[new create]
diff --git a/lib/templates/clone.rb b/lib/templates/clone.rb
index 2c15858f..0fe3b91b 100644
--- a/lib/templates/clone.rb
+++ b/lib/templates/clone.rb
@@ -4,6 +4,7 @@ module Templates
module Clone
module_function
+ # rubocop:disable Metrics, Style/CombinableLoops
def call(original_template, author:, external_id: nil, name: nil, folder_name: nil)
template = original_template.account.templates.new
@@ -29,10 +30,13 @@ module Templates
template.schema.first['name'] = template.name
end
+ original_template.template_accesses.each do |template_access|
+ template.template_accesses.new(user_id: template_access.user_id)
+ end
+
template
end
- # rubocop:disable Metrics, Style/CombinableLoops
def update_submitters_and_fields_and_schema(cloned_submitters, cloned_fields, cloned_schema, cloned_preferences)
submitter_uuids_replacements = {}
field_uuids_replacements = {}
diff --git a/lib/templates/replace_attachments.rb b/lib/templates/replace_attachments.rb
index e10f6a1d..0333d897 100644
--- a/lib/templates/replace_attachments.rb
+++ b/lib/templates/replace_attachments.rb
@@ -27,7 +27,7 @@ module Templates
end
next if template.fields.any? { |f| f['areas']&.any? { |a| a['attachment_uuid'] == document.uuid } }
- next unless submitter && document.metadata.dig('pdf', 'fields').present?
+ next if submitter.blank? || document.metadata.dig('pdf', 'fields').blank?
pdf_fields = document.metadata['pdf'].delete('fields').to_a
pdf_fields.each { |f| f['submitter_uuid'] = submitter['uuid'] }