diff --git a/app/controllers/print_templates_controller.rb b/app/controllers/print_templates_controller.rb index 28bbd48..0bca81d 100644 --- a/app/controllers/print_templates_controller.rb +++ b/app/controllers/print_templates_controller.rb @@ -1,17 +1,14 @@ class PrintTemplatesController < ApplicationController - layout ->{ @project ? 'base' : 'admin' } + layout -> { @project ? 'base' : 'admin' } self.main_menu = false before_action :set_trackers, only: [:new, :create, :edit, :update] - before_action :find_print_template, only: [:edit, :update, :destroy] + before_action :find_print_template, only: [:edit, :update, :destroy, :show] before_action :require_admin, except: [:show, :fields_for_tracker] - # TODO: make this work with Rails.ajax - # before_action :authorize_view_print_templates, only: [:show, :fields_for_tracker] - def index - @print_templates = PrintTemplate.includes(:tracker).all + @print_templates = PrintTemplate.includes(:tracker).all.order(name: :asc) end def new @@ -28,7 +25,6 @@ def create end def edit - # @print_template is set by before_action end def update @@ -48,71 +44,116 @@ def destroy end def show - @print_template = PrintTemplate.find(params[:id]) + # Define the keys that need to be parsed as JSON + json_keys = ['schemas'] + + # Parse specified JSON strings to nested JSON + parsed_json = @print_template.attributes.each_with_object({}) do |(key, value), hash| + hash[key] = if json_keys.include?(key) && value.is_a?(String) + begin + JSON.parse(value) + rescue JSON::ParserError + value + end + else + value + end + end + + fields_data = generate_fields_data(@print_template.tracker) + + # Merge fields data into parsed_json + merged_json = parsed_json.merge(fields_data) + respond_to do |format| - format.json { render json: @print_template } - format.js + format.json { render json: merged_json } end end def fields_for_tracker - @tracker = Tracker.find(params[:tracker_id]) - - # Define core fields - @core_fields = { - 'standard#author.name' => ['text', 'field_author'], - 'standard#status.name' => ['text', 'field_status'], - 'standard#priority.name' => ['text', 'field_priority'], - 'standard#assigned_to.name' => ['text', 'field_assigned_to'], - 'standard#category.name' => ['text', 'field_category'], - 'standard#fixed_version.name' => ['text', 'field_fixed_version'], - 'standard#subject' => ['text', 'field_subject'], - 'standard#description' => ['text', 'field_description'], - 'standard#start_date' => ['date', 'field_start_date'], - 'standard#due_date' => ['date', 'field_due_date'], - 'standard#done_ratio' => ['text', 'field_done_ratio'], - 'standard#estimated_hours' => ['text', 'field_estimated_hours'], - 'standard#total_estimated_hours' => ['text', 'field_total_estimated_hours'], - 'standard#spent_hours' => ['text', 'label_spent_time'], - 'standard#total_spent_hours' => ['text', 'label_total_spent_time'], - 'standard#created_on' => ['date', 'field_created_on'], - 'standard#updated_on' => ['date', 'field_updated_on'], - 'standard#closed_on' => ['date', 'field_closed_on'], + tracker = Tracker.find(params[:tracker_id]) + fields_data = generate_fields_data(tracker) + render json: fields_data + end + + private + + def generate_fields_data(tracker) + # Define the fields that are available for the print template + core_fields = { + 'author.name' => ['string', l(:field_author)], + 'status.name' => ['string', l(:field_status)], + 'priority.name' => ['string', l(:field_priority)], + 'assigned_to.name' => ['string', l(:field_assigned_to)], + 'category.name' => ['string', l(:field_category)], + 'fixed_version.name' => ['string', l(:field_fixed_version)], + 'subject' => ['string', l(:field_subject)], + 'description' => ['text', l(:field_description)], + 'start_date' => ['date', l(:field_start_date)], + 'due_date' => ['date', l(:field_due_date)], + 'done_ratio' => ['float', l(:field_done_ratio)], + 'estimated_hours' => ['float', l(:field_estimated_hours)], + 'total_estimated_hours' => ['float', l(:field_total_estimated_hours)], + 'spent_hours' => ['float', l(:label_spent_time)], + 'total_spent_hours' => ['float', l(:label_total_spent_time)], + 'created_on' => ['date', l(:field_created_on)], + 'updated_on' => ['date', l(:field_updated_on)], + 'closed_on' => ['date', l(:field_closed_on)], }.map { |field, attributes| create_field_hash(field, *attributes) } - # Define custom fields with their names directly - @custom_fields = @tracker.custom_fields.map do |cf| - field_identifier = "custom#issue_custom_field_values_#{cf.id}" + # Custom fields + custom_fields = tracker.custom_fields.map do |cf| + field_key = "cf_#{cf.id}" field_format = cf.field_format - field_name = cf.name + field_label = cf.name - create_field_hash(field_identifier, field_format, field_name) + create_field_hash(field_key, field_format, field_label) end - # Define special fields with localization keys - @special_fields = { - 'special#issue_map' => ['image', 'field_issue_map'], - 'special#issue_url' => ['qrcode', 'field_issue_url'] + # Special fields + special_fields = { + 'issue_map' => ['map', l(:field_issue_map)], + 'issue_url' => ['link', l(:field_issue_url)], }.map { |field, attributes| create_field_hash(field, *attributes) } - # Sorting - @core_fields.sort_by! { |field| field[:name].downcase } - @custom_fields.sort_by! { |field| field[:name].downcase } - @special_fields.sort_by! { |field| field[:name].downcase } + # Field formats + format_list = { + 'bool' => ['boolean', 'Boolean'], + 'date' => ['date', 'Date'], + # 'attachment' => ['file', 'File'], + 'float' => ['float', 'Float'], + 'int' => ['integer', 'Integer'], + # 'enumeration' => ['enumeration', 'Key/value list'], + # 'link' => ['link', 'Link'], + # 'list' => ['list', 'List'], + # 'text' => ['text', 'Long text'], + 'string' => ['string', 'Text'], + # 'user' => ['user', 'User'], + # 'version' => ['version', 'Version'], + }.map { |field, attributes| create_field_hash(field, *attributes) } - respond_to do |format| - format.js - end + # Return the fields data + { + 'fieldKeyOptions': [{ + 'label': l(:label_core_fields), + 'options': core_fields.sort_by! { |field| field[:value].downcase } + }, { + 'label': l(:label_custom_fields), + 'options': custom_fields.sort_by! { |field| field[:value].downcase } + }, { + 'label': l(:label_special_fields), + 'options': special_fields.sort_by! { |field| field[:value].downcase } + }], + 'fieldFormatOptions': format_list + } end - private - def create_field_hash(field, format, name_or_key) name = I18n.exists?(name_or_key) ? I18n.t(name_or_key) : name_or_key { - name: name, - identifier: field, + label: name, + value: field, format: format } end @@ -126,7 +167,7 @@ def find_print_template end def print_template_params - params.require(:print_template).permit(:name, :schemas, :inputs, :basepdf, :tracker_id) + params.require(:print_template).permit(:name, :schemas, :basepdf, :tracker_id, :context) end def require_admin diff --git a/app/controllers/print_templates_pdfme_controller.rb b/app/controllers/print_templates_pdfme_controller.rb index d1f1d97..5ff43bb 100644 --- a/app/controllers/print_templates_pdfme_controller.rb +++ b/app/controllers/print_templates_pdfme_controller.rb @@ -23,7 +23,7 @@ def designer @csrf_token = form_authenticity_token end - def form + def viewer issue_id = params[:issue_id] api_key = User.current.api_key @@ -55,13 +55,6 @@ def form @csrf_token = form_authenticity_token end - # Future actions for viewer, generator, etc. - # def viewer - # end - - # def generator - # end - private def authorize_view_print_templates diff --git a/app/models/print_template.rb b/app/models/print_template.rb index aaac6db..6516930 100644 --- a/app/models/print_template.rb +++ b/app/models/print_template.rb @@ -5,4 +5,9 @@ class PrintTemplate < ActiveRecord::Base validates :name, uniqueness: { scope: :tracker_id } validates :tracker_id, presence: true + + # The context of the print template must be one of the following values. + CONTEXT_OPTIONS = %w(issue issues project).freeze + + validates :context, presence: true, inclusion: { in: CONTEXT_OPTIONS } end diff --git a/app/views/print_templates/_form.html.erb b/app/views/print_templates/_form.html.erb index 811fccb..435f5e3 100644 --- a/app/views/print_templates/_form.html.erb +++ b/app/views/print_templates/_form.html.erb @@ -1,15 +1,28 @@
<%= f.text_field :name, required: true, size: 50 %>
+ ++ <%= f.select :context, + options_for_select([ + [ l(:label_print_template_context_option_issue), 'issue' ], + [ l(:label_print_template_context_option_issues), 'issues', { disabled: true } ], + [ l(:label_print_template_context_option_project), 'project', { disabled: true } ] + ], + @print_template.context || 'issue'), + { required: true } %> +
+ +<%= f.select :tracker_id, - options_from_collection_for_select(@trackers, :id, :name, @print_template.tracker_id || @trackers.first.id), - { required: true }, - { data: { url: url_for(controller: 'print_templates', action: 'fields_for_tracker', format: :js) } } %> + options_from_collection_for_select(@trackers, :id, :name, @print_template.tracker_id || @trackers.first.id), + { required: true }, + { data: { url: url_for(controller: 'print_templates', action: 'fields_for_tracker', format: :json) } } %>
<%= content_tag(:label, l(:label_print_template_basepdf), for: 'pdf-upload') %> - + <%= link_to l(:link_print_template_basepdf_reset), '#', id: 'use-blank-pdf', style: ('display: none;' unless @print_template.basepdf.present?) %>
@@ -24,24 +37,12 @@ <%= f.hidden_field :schemas, value: @print_template.schemas, id: 'print_template_schemas' %> <%= f.hidden_field :basepdf, value: @print_template.basepdf, id: 'print_template_basepdf' %> - <%= f.hidden_field :inputs, value: @print_template.inputs, id: 'print_template_inputs' %><%= l(:label_no_print_template_available) %> diff --git a/app/views/print_templates/_list.html.erb b/app/views/print_templates/_list.html.erb index 72e464a..056dd1e 100644 --- a/app/views/print_templates/_list.html.erb +++ b/app/views/print_templates/_list.html.erb @@ -4,6 +4,7 @@