From 66ea1010b5c9d16ebbbd5fda655bd37a2f089f67 Mon Sep 17 00:00:00 2001 From: Alexandru-Emil Lupu Date: Thu, 6 Oct 2022 23:13:11 +0300 Subject: [PATCH 01/17] Add Proposal Answer Template basic functionality --- decidim-core/app/models/decidim/component.rb | 1 + .../admin/copy_questionnaire_template.rb | 3 +- .../admin/create_proposal_answer_template.rb | 47 +++++++++ .../admin/create_questionnaire_template.rb | 3 +- .../admin/update_proposal_answer_template.rb | 51 ++++++++++ ...te.rb => update_questionnaire_template.rb} | 2 +- .../templates/admin/application_controller.rb | 3 +- .../proposal_answer_templates_controller.rb | 99 +++++++++++++++++++ .../questionnaire_templates_controller.rb | 4 +- .../admin/proposal_answer_template_form.rb | 21 ++++ .../proposal_answer_templates/_form.html.erb | 35 +++++++ .../proposal_answer_templates/edit.html.erb | 20 ++++ .../proposal_answer_templates/index.html.erb | 52 ++++++++++ .../proposal_answer_templates/new.html.erb | 7 ++ decidim-templates/config/locales/en.yml | 13 +++ ...4_add_field_values_to_decidim_templates.rb | 5 + ...d_target_to_decidim_templates_templates.rb | 5 + .../20221006184905_migrate_templateable.rb | 10 ++ .../lib/decidim/templates/admin_engine.rb | 3 + 19 files changed, 378 insertions(+), 6 deletions(-) create mode 100644 decidim-templates/app/commands/decidim/templates/admin/create_proposal_answer_template.rb create mode 100644 decidim-templates/app/commands/decidim/templates/admin/update_proposal_answer_template.rb rename decidim-templates/app/commands/decidim/templates/admin/{update_template.rb => update_questionnaire_template.rb} (93%) create mode 100644 decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb create mode 100644 decidim-templates/app/forms/decidim/templates/admin/proposal_answer_template_form.rb create mode 100644 decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/_form.html.erb create mode 100644 decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/edit.html.erb create mode 100644 decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/index.html.erb create mode 100644 decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/new.html.erb create mode 100644 decidim-templates/db/migrate/20221006055954_add_field_values_to_decidim_templates.rb create mode 100644 decidim-templates/db/migrate/20221006184809_add_target_to_decidim_templates_templates.rb create mode 100644 decidim-templates/db/migrate/20221006184905_migrate_templateable.rb diff --git a/decidim-core/app/models/decidim/component.rb b/decidim-core/app/models/decidim/component.rb index 04a82f959917..e6e2b7dcf574 100644 --- a/decidim-core/app/models/decidim/component.rb +++ b/decidim-core/app/models/decidim/component.rb @@ -11,6 +11,7 @@ class Component < ApplicationRecord include Loggable include Decidim::ShareableWithToken include ScopableComponent + include Decidim::Templates::Templatable if defined? Decidim::Templates::Templatable belongs_to :participatory_space, polymorphic: true diff --git a/decidim-templates/app/commands/decidim/templates/admin/copy_questionnaire_template.rb b/decidim-templates/app/commands/decidim/templates/admin/copy_questionnaire_template.rb index d8379d196abf..7161eb1e0c41 100644 --- a/decidim-templates/app/commands/decidim/templates/admin/copy_questionnaire_template.rb +++ b/decidim-templates/app/commands/decidim/templates/admin/copy_questionnaire_template.rb @@ -39,7 +39,8 @@ def copy_template @copied_template = Template.create!( organization: @template.organization, name: @template.name, - description: @template.description + description: @template.description, + target: :questionnaire, ) @resource = Decidim::Forms::Questionnaire.create!( @template.templatable.dup.attributes.merge( diff --git a/decidim-templates/app/commands/decidim/templates/admin/create_proposal_answer_template.rb b/decidim-templates/app/commands/decidim/templates/admin/create_proposal_answer_template.rb new file mode 100644 index 000000000000..b4e822b503c8 --- /dev/null +++ b/decidim-templates/app/commands/decidim/templates/admin/create_proposal_answer_template.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +module Decidim + module Templates + module Admin + class CreateProposalAnswerTemplate < Rectify::Command + # Initializes the command. + # + # form - The source for this QuestionnaireTemplate. + def initialize(form) + @form = form + end + + def call + return broadcast(:invalid) unless @form.valid? + + @template = Decidim.traceability.create!( + Template, + @form.current_user, + name: @form.name, + description: @form.description, + organization: @form.current_organization, + field_values: { internal_state: @form.internal_state}, + target: :proposal_answer + ) + + resource = identify_templateable_resource + @template.update!(templatable: resource) + + broadcast(:ok, @template) + end + + private + def identify_templateable_resource + resource = @form.scope_for_availability.split("-") + case resource.first + when "organization" + @form.current_organization + when "components" + component = Decidim::Component.where(manifest_name: :proposals).find(resource.last) + component.participatory_space.decidim_organization_id == @form.current_organization.id ? component : nil + end + end + end + end + end +end diff --git a/decidim-templates/app/commands/decidim/templates/admin/create_questionnaire_template.rb b/decidim-templates/app/commands/decidim/templates/admin/create_questionnaire_template.rb index 24632e30c6d8..bbf5e10a0530 100644 --- a/decidim-templates/app/commands/decidim/templates/admin/create_questionnaire_template.rb +++ b/decidim-templates/app/commands/decidim/templates/admin/create_questionnaire_template.rb @@ -20,7 +20,8 @@ def call @form.current_user, name: @form.name, description: @form.description, - organization: @form.current_organization + organization: @form.current_organization, + target: :questionnaire ) @questionnaire = Decidim::Forms::Questionnaire.create!(questionnaire_for: @template) diff --git a/decidim-templates/app/commands/decidim/templates/admin/update_proposal_answer_template.rb b/decidim-templates/app/commands/decidim/templates/admin/update_proposal_answer_template.rb new file mode 100644 index 000000000000..43d684042db6 --- /dev/null +++ b/decidim-templates/app/commands/decidim/templates/admin/update_proposal_answer_template.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module Decidim + module Templates + module Admin + class UpdateProposalAnswerTemplate < Rectify::Command + # Initializes the command. + # + # template - The Template to update. + # form - The form object containing the data to update. + # user - The user that updates the template. + def initialize(template, form, user) + @template = template + @form = form + @user = user + end + + def call + return broadcast(:invalid) unless @form.valid? + return broadcast(:invalid) unless @user.organization == @template.organization + + @template = Decidim.traceability.update!( + @template, + @user, + name: @form.name, + description: @form.description, + field_values: { internal_state: @form.internal_state}, + target: :proposal_answer + ) + + resource = identify_templateable_resource + @template.update!(templatable: resource) + + broadcast(:ok, @template) + end + + private + def identify_templateable_resource + resource = @form.scope_for_availability.split("-") + case resource.first + when "organization" + @form.current_organization + when "components" + component = Decidim::Component.where(manifest_name: :proposals).find(resource.last) + component.participatory_space.decidim_organization_id == @form.current_organization.id ? component : nil + end + end + end + end + end +end diff --git a/decidim-templates/app/commands/decidim/templates/admin/update_template.rb b/decidim-templates/app/commands/decidim/templates/admin/update_questionnaire_template.rb similarity index 93% rename from decidim-templates/app/commands/decidim/templates/admin/update_template.rb rename to decidim-templates/app/commands/decidim/templates/admin/update_questionnaire_template.rb index 94ba7be7a19c..8ac029baa5cb 100644 --- a/decidim-templates/app/commands/decidim/templates/admin/update_template.rb +++ b/decidim-templates/app/commands/decidim/templates/admin/update_questionnaire_template.rb @@ -4,7 +4,7 @@ module Decidim module Templates module Admin # Updates the questionnaire template given form data. - class UpdateTemplate < Rectify::Command + class UpdateQuestionnaireTemplate < Rectify::Command # Initializes the command. # # template - The Template to update. diff --git a/decidim-templates/app/controllers/decidim/templates/admin/application_controller.rb b/decidim-templates/app/controllers/decidim/templates/admin/application_controller.rb index e76405ec6282..417267ceda18 100644 --- a/decidim-templates/app/controllers/decidim/templates/admin/application_controller.rb +++ b/decidim-templates/app/controllers/decidim/templates/admin/application_controller.rb @@ -25,7 +25,8 @@ def permission_class_chain def template_types @template_types ||= { - I18n.t("template_types.questionnaires", scope: "decidim.templates") => decidim_admin_templates.questionnaire_templates_path + I18n.t("template_types.questionnaires", scope: "decidim.templates") => decidim_admin_templates.questionnaire_templates_path, + I18n.t("template_types.proposal_answer_templates", scope: "decidim.templates") => decidim_admin_templates.proposal_answer_templates_path } end end diff --git a/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb b/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb new file mode 100644 index 000000000000..446df9c0a346 --- /dev/null +++ b/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb @@ -0,0 +1,99 @@ +# frozen_string_literal: true + +module Decidim + module Templates + module Admin + class ProposalAnswerTemplatesController < Decidim::Templates::Admin::ApplicationController + include Decidim::TranslatableAttributes + + helper_method :avaliablity_options + + def new + enforce_permission_to :create, :template + @form = form(ProposalAnswerTemplateForm).instance + end + + def edit + enforce_permission_to :update, :template, template: template + @form = form(ProposalAnswerTemplateForm).from_model(template) + # @preview_form = form(Decidim::Forms::QuestionnaireForm).from_model(template.templatable) + end + + def create + enforce_permission_to :create, :template + + @form = form(ProposalAnswerTemplateForm).from_params(params) + + CreateProposalAnswerTemplate.call(@form) do + on(:ok) do |template| + flash[:notice] = I18n.t("templates.create.success", scope: "decidim.admin") + redirect_to edit_proposal_answer_template_path(template) + end + + on(:invalid) do + flash.now[:alert] = I18n.t("templates.create.error", scope: "decidim.admin") + render :new + end + end + end + + + def update + enforce_permission_to :update, :template, template: template + @form = form(ProposalAnswerTemplateForm).from_params(params) + UpdateProposalAnswerTemplate.call(template, @form, current_user) do + on(:ok) do |questionnaire_template| + flash[:notice] = I18n.t("templates.update.success", scope: "decidim.admin") + redirect_to edit_proposal_answer_template_path(questionnaire_template) + end + + on(:invalid) do |template| + @template = template + flash.now[:error] = I18n.t("templates.update.error", scope: "decidim.admin") + render action: :edit + end + end + end + + def index + enforce_permission_to :index, :templates + @templates = collection + + respond_to do |format| + format.html { render :index } + format.json do + term = params[:term] + + @templates = search(term) + + render json: @templates.map { |t| { value: t.id, label: translated_attribute(t.name) } } + end + end + end + + private + + def avaliablity_options + options = [ ['Global scope', "organization-%d" % [current_organization.id] ] ] + options += Decidim::Component.includes(:participatory_space).where(manifest_name: :proposals) + .select{|a| a.participatory_space.decidim_organization_id == current_organization.id }.map do |component| + [ formated_name(component), "components-%d" % component.id] + end + options + end + + def formated_name(component) + "%s ( %s )" % [translated_attribute(component.name), translated_attribute(component.participatory_space.title)] + end + + def template + @template ||= Template.find_by(id: params[:id]) + end + + def collection + @collection ||= current_organization.templates.where(target: :proposal_answer) + end + end + end + end +end diff --git a/decidim-templates/app/controllers/decidim/templates/admin/questionnaire_templates_controller.rb b/decidim-templates/app/controllers/decidim/templates/admin/questionnaire_templates_controller.rb index 1fcfdcb4e386..8bb03c8db5e6 100644 --- a/decidim-templates/app/controllers/decidim/templates/admin/questionnaire_templates_controller.rb +++ b/decidim-templates/app/controllers/decidim/templates/admin/questionnaire_templates_controller.rb @@ -22,7 +22,7 @@ def index term = params[:term] @templates = search(term) - +identify_resource render json: @templates.map { |t| { value: t.id, label: translated_attribute(t.name) } } end end @@ -76,7 +76,7 @@ def edit def update enforce_permission_to :update, :template, template: template @form = form(TemplateForm).from_params(params) - UpdateTemplate.call(template, @form, current_user) do + UpdateQuestionnaireTemplate.call(template, @form, current_user) do on(:ok) do |questionnaire_template| flash[:notice] = I18n.t("templates.update.success", scope: "decidim.admin") redirect_to edit_questionnaire_template_path(questionnaire_template) diff --git a/decidim-templates/app/forms/decidim/templates/admin/proposal_answer_template_form.rb b/decidim-templates/app/forms/decidim/templates/admin/proposal_answer_template_form.rb new file mode 100644 index 000000000000..b7970e2ffb61 --- /dev/null +++ b/decidim-templates/app/forms/decidim/templates/admin/proposal_answer_template_form.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Decidim + module Templates + module Admin + class ProposalAnswerTemplateForm < TemplateForm + attribute :internal_state, String + attribute :scope_for_availability, String + + validates :internal_state, presence: true + + def map_model(model) + self.scope_for_availability = "%s-%d" % [model.templatable_type.demodulize.tableize,model.templatable_id] + (model.field_values || []).to_h.map do |k, v| + self[k.to_sym] = v + end + end + end + end + end +end diff --git a/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/_form.html.erb b/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/_form.html.erb new file mode 100644 index 000000000000..c04923808d96 --- /dev/null +++ b/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/_form.html.erb @@ -0,0 +1,35 @@ +
+
+

<%= t(".template_title") %>

+ <%= form.submit t(".save"), class: "button tiny button--title" %> +
+ +
+
+ <%= form.translated :text_field, :name %> +
+ +
+ <%= form.translated :text_area, :description, rows: 3, label: t('.answer_template') %> + + <%= t('.hint').html_safe %> +
    +
  • <%= t(".hint1").html_safe %>
  • +
  • <%= t(".hint2").html_safe %>
  • +
  • <%= t(".hint3").html_safe %>
  • +
+
+ +
+ <%= form.label :internal_state %> + <%= form.collection_radio_buttons :internal_state, + Decidim::Proposals::Proposal::POSSIBLE_STATES - %w(withdrawn), + :to_s, + ->(mode) { t(mode, scope: 'decidim.proposals.admin.proposal_answers.form') } %> +
+ +
+ <%= form.select :scope_for_availability, avaliablity_options %> +
+
+
diff --git a/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/edit.html.erb b/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/edit.html.erb new file mode 100644 index 000000000000..0ebebb2fb777 --- /dev/null +++ b/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/edit.html.erb @@ -0,0 +1,20 @@ +<%= decidim_form_for(@form, url: proposal_answer_template_path, html: { class: "form edit_proposal_answer_template" }) do |f| %> + <%= render partial: "form", object: f %> +<% end %> + +
+
+

<%#= t(".questionnaire") %>

+ <%#= link_to t(".edit"), edit_questionnaire_path(template), class: "button tiny button--title" %> +
+ +
+
+ <%# if template.templatable.questions.any? %> + <%#= render partial: "preview", locals: { questionnaire: template.templatable } %> + <%# else %> + <%#= t(".empty") %> + <%# end %> +
+
+
diff --git a/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/index.html.erb b/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/index.html.erb new file mode 100644 index 000000000000..55a8704ef8e5 --- /dev/null +++ b/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/index.html.erb @@ -0,0 +1,52 @@ +
+
+

+ <%= t ".title" %> + <% if allowed_to?(:create, :template) %> + <%= link_to t("actions.new", scope: "decidim.admin", name: t("template.name", scope: "decidim.models").downcase), [:new, :proposal_answer_template], class: "button tiny button--title new" %> + <% end %> +

+
+
+ <% if @templates.any? %> +
+ + + + + + + + + + + + <% @templates.each do |template| %> + + + + + + + + <% end %> + +
<%= t("template.name", scope: "decidim.models") %><%= t("questionnaire_template.fields.title", scope: "decidim.models") %><%= t("questionnaire_template.fields.questions", scope: "decidim.models") %><%= t("template.fields.created_at", scope: "decidim.models") %>
<%= link_to translated_attribute(template.name), edit_questionnaire_template_path(template) %><%= link_to translated_attribute(template.templatable.title), edit_questionnaire_path(template) %><%= template.templatable.questions.count.to_i %><%= l template.created_at, format: :long %> + <% if allowed_to?(:update, :template, questionnaire_template: template) %> + <%= icon_link_to "pencil", edit_questionnaire_template_path(template), t("actions.edit", scope: "decidim.admin"), class: "edit" %> + <% end %> + + <% if allowed_to?(:copy, :template, questionnaire_template: template) %> + <%= icon_link_to "clipboard", copy_questionnaire_template_path(template), t("actions.duplicate", scope: "decidim.admin"), method: :post %> + <% end %> + + <% if allowed_to?(:destroy, :template, questionnaire_template: template) %> + <%= icon_link_to "circle-x", questionnaire_template_path(template), t("actions.destroy", scope: "decidim.admin"), method: :delete, data: { confirm: t(".confirm_delete") }, class: "action-icon--remove" %> + <% end %> +
+
+ <% else %> + <%= t("templates.empty", scope: "decidim.admin") %> + <% end %> +
+
diff --git a/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/new.html.erb b/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/new.html.erb new file mode 100644 index 000000000000..3be1fd1edb83 --- /dev/null +++ b/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/new.html.erb @@ -0,0 +1,7 @@ +<% content_for :title do %> + <%= t("templates", scope: "decidim.admin.titles") %> +<% end %> + +<%= decidim_form_for(@form, url: proposal_answer_templates_path, html: { class: "form new_proposal_answer_template" }) do |f| %> + <%= render partial: "form", object: f %> +<% end %> diff --git a/decidim-templates/config/locales/en.yml b/decidim-templates/config/locales/en.yml index cb86a07b4783..d77b27dda524 100644 --- a/decidim-templates/config/locales/en.yml +++ b/decidim-templates/config/locales/en.yml @@ -1,4 +1,5 @@ --- + en: activemodel: attributes: @@ -42,6 +43,17 @@ en: name: Template templates: admin: + proposal_answer_templates: + form: + save: Save + template_title: Template information + answer_template: Answer template + hint: Hint: You can use theese variables anywhere on the answer template that will be replaced when using the template + hint1: "%{organization}" will be replaced by the organization's name + hint2: "%{name}" will be replaced by the author's name + hint3: "%{admin}" will be replaced by the admin's name (the one answering the proposal) + index: + title: Proposal answers questionnaire_templates: choose: create_from_template: Create from template @@ -66,3 +78,4 @@ en: tos_agreement: By participating you accept its Terms of Service template_types: questionnaires: Questionnaires + proposal_answer_templates: Proposal Answers diff --git a/decidim-templates/db/migrate/20221006055954_add_field_values_to_decidim_templates.rb b/decidim-templates/db/migrate/20221006055954_add_field_values_to_decidim_templates.rb new file mode 100644 index 000000000000..b806c6866aac --- /dev/null +++ b/decidim-templates/db/migrate/20221006055954_add_field_values_to_decidim_templates.rb @@ -0,0 +1,5 @@ +class AddFieldValuesToDecidimTemplates < ActiveRecord::Migration[6.0] + def change + add_column :decidim_templates_templates, :field_values, :json, default: {} + end +end diff --git a/decidim-templates/db/migrate/20221006184809_add_target_to_decidim_templates_templates.rb b/decidim-templates/db/migrate/20221006184809_add_target_to_decidim_templates_templates.rb new file mode 100644 index 000000000000..8db9cc05dc7a --- /dev/null +++ b/decidim-templates/db/migrate/20221006184809_add_target_to_decidim_templates_templates.rb @@ -0,0 +1,5 @@ +class AddTargetToDecidimTemplatesTemplates < ActiveRecord::Migration[6.0] + def change + add_column :decidim_templates_templates, :target, :string + end +end diff --git a/decidim-templates/db/migrate/20221006184905_migrate_templateable.rb b/decidim-templates/db/migrate/20221006184905_migrate_templateable.rb new file mode 100644 index 000000000000..b15bac191ec3 --- /dev/null +++ b/decidim-templates/db/migrate/20221006184905_migrate_templateable.rb @@ -0,0 +1,10 @@ +class MigrateTemplateable < ActiveRecord::Migration[6.0] + def self.up + Decidim::Templates::Template.find_each do |template| + template.update_attribute(:target, template.templatable_type.demodulize.tableize.singularize) + end + end + + def self.down + end +end diff --git a/decidim-templates/lib/decidim/templates/admin_engine.rb b/decidim-templates/lib/decidim/templates/admin_engine.rb index b1e6328b8c42..cce12464aebc 100644 --- a/decidim-templates/lib/decidim/templates/admin_engine.rb +++ b/decidim-templates/lib/decidim/templates/admin_engine.rb @@ -11,6 +11,9 @@ class AdminEngine < ::Rails::Engine routes do ## Routes for Questionnaire Templates + resources :proposal_answer_templates do + + end resources :questionnaire_templates do member do post :copy From 2fcd98b63dcaca823f3d05a3f3cb7fe41397f655 Mon Sep 17 00:00:00 2001 From: Alexandru-Emil Lupu Date: Fri, 7 Oct 2022 00:24:39 +0300 Subject: [PATCH 02/17] Apply pagination, add functionality for copy + delete --- .../admin/copy_proposal_answer_template.rb | 36 +++++++++++++ .../admin/destroy_questionnaire_template.rb | 22 ++++++++ .../templates/admin/destroy_template.rb | 2 +- .../proposal_answer_templates_controller.rb | 50 ++++++++++++++++--- .../questionnaire_templates_controller.rb | 4 +- .../app/models/decidim/templates/template.rb | 6 --- .../proposal_answer_templates/_form.html.erb | 2 +- .../proposal_answer_templates/index.html.erb | 22 ++++---- decidim-templates/config/locales/en.yml | 1 + .../lib/decidim/templates/admin_engine.rb | 4 +- 10 files changed, 121 insertions(+), 28 deletions(-) create mode 100644 decidim-templates/app/commands/decidim/templates/admin/copy_proposal_answer_template.rb create mode 100644 decidim-templates/app/commands/decidim/templates/admin/destroy_questionnaire_template.rb diff --git a/decidim-templates/app/commands/decidim/templates/admin/copy_proposal_answer_template.rb b/decidim-templates/app/commands/decidim/templates/admin/copy_proposal_answer_template.rb new file mode 100644 index 000000000000..83b217590317 --- /dev/null +++ b/decidim-templates/app/commands/decidim/templates/admin/copy_proposal_answer_template.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module Decidim + module Templates + # A command with all the business logic when duplicating a questionnaire template + module Admin + class CopyProposalAnswerTemplate < Rectify::Command + def initialize(template) + @template = template + end + + def call + return broadcast(:invalid) unless @template.valid? + + Template.transaction do + copy_template + end + + broadcast(:ok, @copied_template) + end + + def copy_template + @copied_template = Template.create!( + organization: @template.organization, + name: @template.name, + description: @template.description, + target: :proposal_answer, + field_values: @template.field_values, + templatable: @template.templatable + ) + end + + end + end + end +end diff --git a/decidim-templates/app/commands/decidim/templates/admin/destroy_questionnaire_template.rb b/decidim-templates/app/commands/decidim/templates/admin/destroy_questionnaire_template.rb new file mode 100644 index 000000000000..c7ac0da2f8e0 --- /dev/null +++ b/decidim-templates/app/commands/decidim/templates/admin/destroy_questionnaire_template.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Decidim + module Templates + module Admin + class DestroyQuestionnaireTemplate < DestroyTemplate + + protected + def destroy_template + Decidim.traceability.perform_action!( + :delete, + template, + current_user + ) do + template.destroy! + template.templatable.destroy + end + end + end + end + end +end diff --git a/decidim-templates/app/commands/decidim/templates/admin/destroy_template.rb b/decidim-templates/app/commands/decidim/templates/admin/destroy_template.rb index 1d692955ce57..000ef22dd968 100644 --- a/decidim-templates/app/commands/decidim/templates/admin/destroy_template.rb +++ b/decidim-templates/app/commands/decidim/templates/admin/destroy_template.rb @@ -22,7 +22,7 @@ def call broadcast(:ok) end - private + protected attr_reader :template, :current_user diff --git a/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb b/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb index 446df9c0a346..7a847149671f 100644 --- a/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb +++ b/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb @@ -5,8 +5,9 @@ module Templates module Admin class ProposalAnswerTemplatesController < Decidim::Templates::Admin::ApplicationController include Decidim::TranslatableAttributes + include Decidim::Paginable - helper_method :avaliablity_options + helper_method :availability_option_as_text, :availability_options_for_select def new enforce_permission_to :create, :template @@ -37,6 +38,16 @@ def create end end + def destroy + enforce_permission_to :destroy, :template, template: template + + DestroyTemplate.call(template, current_user) do + on(:ok) do + flash[:notice] = I18n.t("templates.destroy.success", scope: "decidim.admin") + redirect_to action: :index + end + end + end def update enforce_permission_to :update, :template, template: template @@ -55,6 +66,22 @@ def update end end + def copy + enforce_permission_to :copy, :template + + CopyProposalAnswerTemplate.call(template) do + on(:ok) do + flash[:notice] = I18n.t("templates.copy.success", scope: "decidim.admin") + redirect_to action: :index + end + + on(:invalid) do + flash[:alert] = I18n.t("templates.copy.error", scope: "decidim.admin") + redirect_to action: :index + end + end + end + def index enforce_permission_to :index, :templates @templates = collection @@ -73,13 +100,22 @@ def index private + def availability_option_as_text(template) + key = "%s-%d" % [template.templatable_type.demodulize.tableize,template.templatable_id] + avaliablity_options.fetch(key) + end + + def availability_options_for_select + avaliablity_options.collect {|key, value| [value, key] }.to_a + end + def avaliablity_options - options = [ ['Global scope', "organization-%d" % [current_organization.id] ] ] - options += Decidim::Component.includes(:participatory_space).where(manifest_name: :proposals) - .select{|a| a.participatory_space.decidim_organization_id == current_organization.id }.map do |component| - [ formated_name(component), "components-%d" % component.id] + @avaliablity_options = { "organizations-%d" % [current_organization.id] => 'Global scope'} + Decidim::Component.includes(:participatory_space).where(manifest_name: :proposals) + .select{|a| a.participatory_space.decidim_organization_id == current_organization.id }.each do |component| + @avaliablity_options["components-%d" % component.id] = formated_name(component) end - options + @avaliablity_options end def formated_name(component) @@ -91,7 +127,7 @@ def template end def collection - @collection ||= current_organization.templates.where(target: :proposal_answer) + @collection ||= paginate(current_organization.templates.where(target: :proposal_answer)) end end end diff --git a/decidim-templates/app/controllers/decidim/templates/admin/questionnaire_templates_controller.rb b/decidim-templates/app/controllers/decidim/templates/admin/questionnaire_templates_controller.rb index 8bb03c8db5e6..5ee8e73c48d5 100644 --- a/decidim-templates/app/controllers/decidim/templates/admin/questionnaire_templates_controller.rb +++ b/decidim-templates/app/controllers/decidim/templates/admin/questionnaire_templates_controller.rb @@ -22,7 +22,7 @@ def index term = params[:term] @templates = search(term) -identify_resource + render json: @templates.map { |t| { value: t.id, label: translated_attribute(t.name) } } end end @@ -93,7 +93,7 @@ def update def destroy enforce_permission_to :destroy, :template, template: template - DestroyTemplate.call(template, current_user) do + DestroyQuestionnaireTemplate.call(template, current_user) do on(:ok) do flash[:notice] = I18n.t("templates.destroy.success", scope: "decidim.admin") redirect_to action: :index diff --git a/decidim-templates/app/models/decidim/templates/template.rb b/decidim-templates/app/models/decidim/templates/template.rb index 48cfbbce260a..5bb914c600f9 100644 --- a/decidim-templates/app/models/decidim/templates/template.rb +++ b/decidim-templates/app/models/decidim/templates/template.rb @@ -17,17 +17,11 @@ class Template < ApplicationRecord belongs_to :templatable, foreign_type: "templatable_type", polymorphic: true, optional: true - before_destroy :destroy_templatable - validates :name, presence: true def resource_name [templatable_type.demodulize.tableize.singularize, "templates"].join("_") end - - def destroy_templatable - templatable.destroy - end end end end diff --git a/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/_form.html.erb b/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/_form.html.erb index c04923808d96..9820217ef68a 100644 --- a/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/_form.html.erb +++ b/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/_form.html.erb @@ -29,7 +29,7 @@
- <%= form.select :scope_for_availability, avaliablity_options %> + <%= form.select :scope_for_availability, availability_options_for_select %>
diff --git a/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/index.html.erb b/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/index.html.erb index 55a8704ef8e5..8ac8593a31aa 100644 --- a/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/index.html.erb +++ b/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/index.html.erb @@ -22,28 +22,30 @@ <% @templates.each do |template| %> - - <%= link_to translated_attribute(template.name), edit_questionnaire_template_path(template) %> - <%= link_to translated_attribute(template.templatable.title), edit_questionnaire_path(template) %> - <%= template.templatable.questions.count.to_i %> + + <%= link_to_if allowed_to?(:update, :template, template: template) , translated_attribute(template.name), edit_proposal_answer_template_path(template) %> + <%= t(template.field_values.dig("internal_state"), scope: 'decidim.proposals.admin.proposal_answers.form') %> + <%= availability_option_as_text(template) %> <%= l template.created_at, format: :long %> - <% if allowed_to?(:update, :template, questionnaire_template: template) %> - <%= icon_link_to "pencil", edit_questionnaire_template_path(template), t("actions.edit", scope: "decidim.admin"), class: "edit" %> + <% if allowed_to?(:update, :template, template: template) %> + <%= icon_link_to "pencil", edit_proposal_answer_template_path(template), t("actions.edit", scope: "decidim.admin"), class: "edit" %> <% end %> - <% if allowed_to?(:copy, :template, questionnaire_template: template) %> - <%= icon_link_to "clipboard", copy_questionnaire_template_path(template), t("actions.duplicate", scope: "decidim.admin"), method: :post %> + <% if allowed_to?(:copy, :template, template: template) %> + <%= icon_link_to "clipboard", copy_proposal_answer_template_path(template), t("actions.duplicate", scope: "decidim.admin"), method: :post %> <% end %> - <% if allowed_to?(:destroy, :template, questionnaire_template: template) %> - <%= icon_link_to "circle-x", questionnaire_template_path(template), t("actions.destroy", scope: "decidim.admin"), method: :delete, data: { confirm: t(".confirm_delete") }, class: "action-icon--remove" %> + <% if allowed_to?(:destroy, :template, template: template) %> + <%= icon_link_to "circle-x", proposal_answer_template_path(template), t("actions.destroy", scope: "decidim.admin"), method: :delete, data: { confirm: t(".confirm_delete") }, class: "action-icon--remove" %> <% end %> <% end %> + + <%= paginate @templates, theme: "decidim" %> <% else %> <%= t("templates.empty", scope: "decidim.admin") %> diff --git a/decidim-templates/config/locales/en.yml b/decidim-templates/config/locales/en.yml index d77b27dda524..7a7cbc8e3f7b 100644 --- a/decidim-templates/config/locales/en.yml +++ b/decidim-templates/config/locales/en.yml @@ -54,6 +54,7 @@ en: hint3: "%{admin}" will be replaced by the admin's name (the one answering the proposal) index: title: Proposal answers + confirm_delete: Are you sure you want to delete this template? questionnaire_templates: choose: create_from_template: Create from template diff --git a/decidim-templates/lib/decidim/templates/admin_engine.rb b/decidim-templates/lib/decidim/templates/admin_engine.rb index cce12464aebc..893d59a8fea1 100644 --- a/decidim-templates/lib/decidim/templates/admin_engine.rb +++ b/decidim-templates/lib/decidim/templates/admin_engine.rb @@ -12,7 +12,9 @@ class AdminEngine < ::Rails::Engine routes do ## Routes for Questionnaire Templates resources :proposal_answer_templates do - + member do + post :copy + end end resources :questionnaire_templates do member do From d887eb91c8bb4b5bea70442e50feab5cbd21a977 Mon Sep 17 00:00:00 2001 From: Alexandru-Emil Lupu Date: Sat, 8 Oct 2022 15:32:16 +0300 Subject: [PATCH 03/17] Add Answer Template to Proposal --- .../admin/proposal_answers/_form.html.erb | 4 +++ .../admin/create_proposal_answer_template.rb | 2 +- .../admin/update_proposal_answer_template.rb | 2 +- .../concerns/templatable_poposal_answer.rb | 24 ++++++++++++++ .../proposal_answer_templates_controller.rb | 33 +++++++++++++++++-- .../admin/proposal_answer_template_form.rb | 2 +- .../entrypoints/decidim_templates_admin.js | 1 + .../admin/proposal_answer_template_chooser.js | 18 ++++++++++ .../_template_chooser.html.erb | 17 ++++++++++ .../proposal_answer_templates/edit.html.erb | 17 ---------- decidim-templates/config/assets.rb | 3 +- decidim-templates/config/locales/en.yml | 14 ++++---- .../lib/decidim/templates/admin_engine.rb | 3 ++ 13 files changed, 111 insertions(+), 29 deletions(-) create mode 100644 decidim-templates/app/controllers/decidim/templates/admin/concerns/templatable_poposal_answer.rb create mode 100644 decidim-templates/app/packs/entrypoints/decidim_templates_admin.js create mode 100644 decidim-templates/app/packs/src/decidim/templates/admin/proposal_answer_template_chooser.js create mode 100644 decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/_template_chooser.html.erb diff --git a/decidim-proposals/app/views/decidim/proposals/admin/proposal_answers/_form.html.erb b/decidim-proposals/app/views/decidim/proposals/admin/proposal_answers/_form.html.erb index 279585ff412b..a26372c01036 100644 --- a/decidim-proposals/app/views/decidim/proposals/admin/proposal_answers/_form.html.erb +++ b/decidim-proposals/app/views/decidim/proposals/admin/proposal_answers/_form.html.erb @@ -5,6 +5,10 @@
+ <% if defined?(Decidim::Templates) %> + <%= render "decidim/templates/admin/proposal_answer_templates/template_chooser", form: f %> + <% end %> +
<%= f.collection_radio_buttons :internal_state, [["not_answered", t(".not_answered")], ["accepted", t(".accepted")], ["rejected", t(".rejected")], ["evaluating", t(".evaluating")]], :first, :last, prompt: true %>
diff --git a/decidim-templates/app/commands/decidim/templates/admin/create_proposal_answer_template.rb b/decidim-templates/app/commands/decidim/templates/admin/create_proposal_answer_template.rb index b4e822b503c8..f81a1c84f653 100644 --- a/decidim-templates/app/commands/decidim/templates/admin/create_proposal_answer_template.rb +++ b/decidim-templates/app/commands/decidim/templates/admin/create_proposal_answer_template.rb @@ -34,7 +34,7 @@ def call def identify_templateable_resource resource = @form.scope_for_availability.split("-") case resource.first - when "organization" + when "organizations" @form.current_organization when "components" component = Decidim::Component.where(manifest_name: :proposals).find(resource.last) diff --git a/decidim-templates/app/commands/decidim/templates/admin/update_proposal_answer_template.rb b/decidim-templates/app/commands/decidim/templates/admin/update_proposal_answer_template.rb index 43d684042db6..2a66aa229871 100644 --- a/decidim-templates/app/commands/decidim/templates/admin/update_proposal_answer_template.rb +++ b/decidim-templates/app/commands/decidim/templates/admin/update_proposal_answer_template.rb @@ -38,7 +38,7 @@ def call def identify_templateable_resource resource = @form.scope_for_availability.split("-") case resource.first - when "organization" + when "organizations" @form.current_organization when "components" component = Decidim::Component.where(manifest_name: :proposals).find(resource.last) diff --git a/decidim-templates/app/controllers/decidim/templates/admin/concerns/templatable_poposal_answer.rb b/decidim-templates/app/controllers/decidim/templates/admin/concerns/templatable_poposal_answer.rb new file mode 100644 index 000000000000..2847e99db8ae --- /dev/null +++ b/decidim-templates/app/controllers/decidim/templates/admin/concerns/templatable_poposal_answer.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require "active_support/concern" + +module Decidim + module Templates + module Admin + module Concerns + module TemplatablePoposalAnswer + # Common logic to load template-related resources in controller + extend ActiveSupport::Concern + + included do + helper_method :proposal_answers_template_options + + def proposal_answers_template_options + + end + end + end + end + end + end +end diff --git a/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb b/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb index 7a847149671f..2e8a0e666327 100644 --- a/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb +++ b/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb @@ -49,6 +49,22 @@ def destroy end end + def fetch + enforce_permission_to :read, :template, template: template + # enforce_permission_to :create, :proposal_answer, proposal: proposal + + response_object = { + state: template.field_values["internal_state"], + template: populate_template_interpolations(proposal) + } + + respond_to do |format| + format.json { + render json: response_object.to_json + } + end + end + def update enforce_permission_to :update, :template, template: template @form = form(ProposalAnswerTemplateForm).from_params(params) @@ -100,6 +116,19 @@ def index private + def populate_template_interpolations(proposal) + template.description.each do |row| + row.last.gsub!('%{organization}', proposal.organization.name) + row.last.gsub!('%{name}', proposal.creator_author.name) + row.last.gsub!('%{admin}', current_user.name) + [row.first, row.last] + end.to_h + end + + def proposal + @proposal ||= Decidim::Proposals::Proposal.find(params[:proposal_id]) + end + def availability_option_as_text(template) key = "%s-%d" % [template.templatable_type.demodulize.tableize,template.templatable_id] avaliablity_options.fetch(key) @@ -110,7 +139,7 @@ def availability_options_for_select end def avaliablity_options - @avaliablity_options = { "organizations-%d" % [current_organization.id] => 'Global scope'} + @avaliablity_options = { "organizations-%d" % [current_organization.id] => t('global_scope', scope: 'decidim.templates.admin.proposal_answer_templates.index')} Decidim::Component.includes(:participatory_space).where(manifest_name: :proposals) .select{|a| a.participatory_space.decidim_organization_id == current_organization.id }.each do |component| @avaliablity_options["components-%d" % component.id] = formated_name(component) @@ -127,7 +156,7 @@ def template end def collection - @collection ||= paginate(current_organization.templates.where(target: :proposal_answer)) + @collection ||= paginate(current_organization.templates.where(target: :proposal_answer).order(:id)) end end end diff --git a/decidim-templates/app/forms/decidim/templates/admin/proposal_answer_template_form.rb b/decidim-templates/app/forms/decidim/templates/admin/proposal_answer_template_form.rb index b7970e2ffb61..b472e5aaefc8 100644 --- a/decidim-templates/app/forms/decidim/templates/admin/proposal_answer_template_form.rb +++ b/decidim-templates/app/forms/decidim/templates/admin/proposal_answer_template_form.rb @@ -10,7 +10,7 @@ class ProposalAnswerTemplateForm < TemplateForm validates :internal_state, presence: true def map_model(model) - self.scope_for_availability = "%s-%d" % [model.templatable_type.demodulize.tableize,model.templatable_id] + self.scope_for_availability = "%s-%d" % [model.templatable_type.try(:demodulize).try(:tableize),model.templatable_id.to_i] (model.field_values || []).to_h.map do |k, v| self[k.to_sym] = v end diff --git a/decidim-templates/app/packs/entrypoints/decidim_templates_admin.js b/decidim-templates/app/packs/entrypoints/decidim_templates_admin.js new file mode 100644 index 000000000000..73f2f27d7b33 --- /dev/null +++ b/decidim-templates/app/packs/entrypoints/decidim_templates_admin.js @@ -0,0 +1 @@ +import "src/decidim/templates/admin/proposal_answer_template_chooser" diff --git a/decidim-templates/app/packs/src/decidim/templates/admin/proposal_answer_template_chooser.js b/decidim-templates/app/packs/src/decidim/templates/admin/proposal_answer_template_chooser.js new file mode 100644 index 000000000000..7dcd4544b939 --- /dev/null +++ b/decidim-templates/app/packs/src/decidim/templates/admin/proposal_answer_template_chooser.js @@ -0,0 +1,18 @@ +$(() => { + $("#proposal_answer_template_chooser").change(function(){ + $.getJSON($(this).data('url'), { + id: $(this).val(), + proposal_id: $(this).data('proposal') + }).done(function(data){ + $("#proposal_answer_internal_state_" + data.state).trigger('click'); + + let $editors = $("#proposal_answer_template_chooser").parent().parent().find('.tabs-panel').find('.editor-container'); + $editors.each(function(index, element){ + local_element = $(element); + let $locale = local_element.siblings('input[type=hidden]').attr('id').replace('proposal_answer_answer_', ''); + let editor = Quill.find(element); + editor.setText(data.template[$locale]); + }); + }); + }); +}); diff --git a/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/_template_chooser.html.erb b/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/_template_chooser.html.erb new file mode 100644 index 000000000000..e6ca4d8a7083 --- /dev/null +++ b/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/_template_chooser.html.erb @@ -0,0 +1,17 @@ +<% templates = Decidim::Templates::Template .where( + target: :proposal_answer, + templatable: [current_organization, current_component] +).order(:templatable_id) %> + +<% if templates.any? %> +
+ <%= javascript_pack_tag "decidim_templates_admin" %> + + +
+<% end %> diff --git a/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/edit.html.erb b/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/edit.html.erb index 0ebebb2fb777..27daf7ef3627 100644 --- a/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/edit.html.erb +++ b/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/edit.html.erb @@ -1,20 +1,3 @@ <%= decidim_form_for(@form, url: proposal_answer_template_path, html: { class: "form edit_proposal_answer_template" }) do |f| %> <%= render partial: "form", object: f %> <% end %> - -
-
-

<%#= t(".questionnaire") %>

- <%#= link_to t(".edit"), edit_questionnaire_path(template), class: "button tiny button--title" %> -
- -
-
- <%# if template.templatable.questions.any? %> - <%#= render partial: "preview", locals: { questionnaire: template.templatable } %> - <%# else %> - <%#= t(".empty") %> - <%# end %> -
-
-
diff --git a/decidim-templates/config/assets.rb b/decidim-templates/config/assets.rb index 7c60dfefc6a8..b755f0cdad02 100644 --- a/decidim-templates/config/assets.rb +++ b/decidim-templates/config/assets.rb @@ -4,5 +4,6 @@ Decidim::Webpacker.register_path("#{base_path}/app/packs") Decidim::Webpacker.register_entrypoints( - decidim_templates: "#{base_path}/app/packs/entrypoints/decidim_templates.js" + decidim_templates: "#{base_path}/app/packs/entrypoints/decidim_templates.js", + decidim_templates_admin: "#{base_path}/app/packs/entrypoints/decidim_templates_admin.js" ) diff --git a/decidim-templates/config/locales/en.yml b/decidim-templates/config/locales/en.yml index 7a7cbc8e3f7b..c82703427d83 100644 --- a/decidim-templates/config/locales/en.yml +++ b/decidim-templates/config/locales/en.yml @@ -1,5 +1,4 @@ --- - en: activemodel: attributes: @@ -45,16 +44,19 @@ en: admin: proposal_answer_templates: form: - save: Save - template_title: Template information answer_template: Answer template - hint: Hint: You can use theese variables anywhere on the answer template that will be replaced when using the template + hint: "Hint: You can use theese variables anywhere on the answer template that will be replaced when using the template" hint1: "%{organization}" will be replaced by the organization's name hint2: "%{name}" will be replaced by the author's name hint3: "%{admin}" will be replaced by the admin's name (the one answering the proposal) + save: Save + template_title: Template information index: - title: Proposal answers confirm_delete: Are you sure you want to delete this template? + global_scope: Global scope + title: Proposal answers + template_chooser: + select_template: Select a template answer questionnaire_templates: choose: create_from_template: Create from template @@ -78,5 +80,5 @@ en: of_total_steps: of %{total_steps} tos_agreement: By participating you accept its Terms of Service template_types: - questionnaires: Questionnaires proposal_answer_templates: Proposal Answers + questionnaires: Questionnaires diff --git a/decidim-templates/lib/decidim/templates/admin_engine.rb b/decidim-templates/lib/decidim/templates/admin_engine.rb index 893d59a8fea1..389d61e251f9 100644 --- a/decidim-templates/lib/decidim/templates/admin_engine.rb +++ b/decidim-templates/lib/decidim/templates/admin_engine.rb @@ -15,6 +15,9 @@ class AdminEngine < ::Rails::Engine member do post :copy end + collection do + get :fetch + end end resources :questionnaire_templates do member do From 1f5a98f73438dfb3c6baca4a816c8cae60184d69 Mon Sep 17 00:00:00 2001 From: Alexandru-Emil Lupu Date: Sat, 8 Oct 2022 17:26:51 +0300 Subject: [PATCH 04/17] Linting decidim-templates --- .../admin/copy_proposal_answer_template.rb | 1 - .../admin/copy_questionnaire_template.rb | 2 +- .../admin/create_proposal_answer_template.rb | 3 +- .../admin/destroy_questionnaire_template.rb | 2 +- .../admin/update_proposal_answer_template.rb | 3 +- .../concerns/templatable_poposal_answer.rb | 4 +- .../proposal_answer_templates_controller.rb | 29 ++++++++------ .../admin/proposal_answer_template_form.rb | 2 +- ...4_add_field_values_to_decidim_templates.rb | 2 + ...d_target_to_decidim_templates_templates.rb | 2 + .../20221006184905_migrate_templateable.rb | 7 ++-- .../lib/decidim/templates/test/factories.rb | 6 +++ .../copy_proposal_answer_template_spec.rb | 40 +++++++++++++++++++ .../destroy_questionnaire_template_spec.rb | 25 ++++++++++++ .../templates/admin/destroy_template_spec.rb | 20 ++++++++++ .../models/decidim/templates/template_spec.rb | 16 ++++---- decidim-templates/spec/spec_helper.rb | 2 +- 17 files changed, 132 insertions(+), 34 deletions(-) create mode 100644 decidim-templates/spec/commands/decidim/templates/admin/copy_proposal_answer_template_spec.rb create mode 100644 decidim-templates/spec/commands/decidim/templates/admin/destroy_questionnaire_template_spec.rb create mode 100644 decidim-templates/spec/commands/decidim/templates/admin/destroy_template_spec.rb diff --git a/decidim-templates/app/commands/decidim/templates/admin/copy_proposal_answer_template.rb b/decidim-templates/app/commands/decidim/templates/admin/copy_proposal_answer_template.rb index 83b217590317..38c53d78f793 100644 --- a/decidim-templates/app/commands/decidim/templates/admin/copy_proposal_answer_template.rb +++ b/decidim-templates/app/commands/decidim/templates/admin/copy_proposal_answer_template.rb @@ -29,7 +29,6 @@ def copy_template templatable: @template.templatable ) end - end end end diff --git a/decidim-templates/app/commands/decidim/templates/admin/copy_questionnaire_template.rb b/decidim-templates/app/commands/decidim/templates/admin/copy_questionnaire_template.rb index 7161eb1e0c41..909dba99c3d3 100644 --- a/decidim-templates/app/commands/decidim/templates/admin/copy_questionnaire_template.rb +++ b/decidim-templates/app/commands/decidim/templates/admin/copy_questionnaire_template.rb @@ -40,7 +40,7 @@ def copy_template organization: @template.organization, name: @template.name, description: @template.description, - target: :questionnaire, + target: :questionnaire ) @resource = Decidim::Forms::Questionnaire.create!( @template.templatable.dup.attributes.merge( diff --git a/decidim-templates/app/commands/decidim/templates/admin/create_proposal_answer_template.rb b/decidim-templates/app/commands/decidim/templates/admin/create_proposal_answer_template.rb index f81a1c84f653..dd27b71325d4 100644 --- a/decidim-templates/app/commands/decidim/templates/admin/create_proposal_answer_template.rb +++ b/decidim-templates/app/commands/decidim/templates/admin/create_proposal_answer_template.rb @@ -20,7 +20,7 @@ def call name: @form.name, description: @form.description, organization: @form.current_organization, - field_values: { internal_state: @form.internal_state}, + field_values: { internal_state: @form.internal_state }, target: :proposal_answer ) @@ -31,6 +31,7 @@ def call end private + def identify_templateable_resource resource = @form.scope_for_availability.split("-") case resource.first diff --git a/decidim-templates/app/commands/decidim/templates/admin/destroy_questionnaire_template.rb b/decidim-templates/app/commands/decidim/templates/admin/destroy_questionnaire_template.rb index c7ac0da2f8e0..8df5e09fcd3a 100644 --- a/decidim-templates/app/commands/decidim/templates/admin/destroy_questionnaire_template.rb +++ b/decidim-templates/app/commands/decidim/templates/admin/destroy_questionnaire_template.rb @@ -4,8 +4,8 @@ module Decidim module Templates module Admin class DestroyQuestionnaireTemplate < DestroyTemplate - protected + def destroy_template Decidim.traceability.perform_action!( :delete, diff --git a/decidim-templates/app/commands/decidim/templates/admin/update_proposal_answer_template.rb b/decidim-templates/app/commands/decidim/templates/admin/update_proposal_answer_template.rb index 2a66aa229871..0e93ad376751 100644 --- a/decidim-templates/app/commands/decidim/templates/admin/update_proposal_answer_template.rb +++ b/decidim-templates/app/commands/decidim/templates/admin/update_proposal_answer_template.rb @@ -24,7 +24,7 @@ def call @user, name: @form.name, description: @form.description, - field_values: { internal_state: @form.internal_state}, + field_values: { internal_state: @form.internal_state }, target: :proposal_answer ) @@ -35,6 +35,7 @@ def call end private + def identify_templateable_resource resource = @form.scope_for_availability.split("-") case resource.first diff --git a/decidim-templates/app/controllers/decidim/templates/admin/concerns/templatable_poposal_answer.rb b/decidim-templates/app/controllers/decidim/templates/admin/concerns/templatable_poposal_answer.rb index 2847e99db8ae..02e799fa457d 100644 --- a/decidim-templates/app/controllers/decidim/templates/admin/concerns/templatable_poposal_answer.rb +++ b/decidim-templates/app/controllers/decidim/templates/admin/concerns/templatable_poposal_answer.rb @@ -13,9 +13,7 @@ module TemplatablePoposalAnswer included do helper_method :proposal_answers_template_options - def proposal_answers_template_options - - end + def proposal_answers_template_options; end end end end diff --git a/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb b/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb index 2e8a0e666327..1d4137e28a99 100644 --- a/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb +++ b/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb @@ -59,9 +59,9 @@ def fetch } respond_to do |format| - format.json { + format.json do render json: response_object.to_json - } + end end end @@ -117,11 +117,14 @@ def index private def populate_template_interpolations(proposal) - template.description.each do |row| - row.last.gsub!('%{organization}', proposal.organization.name) - row.last.gsub!('%{name}', proposal.creator_author.name) - row.last.gsub!('%{admin}', current_user.name) - [row.first, row.last] + template.description.map do |row| + language = row.first + value = row.last + value.gsub!("%{organization}", proposal.organization.name) + value.gsub!("%{name}", proposal.creator_author.name) + value.gsub!("%{admin}", current_user.name) + + [language, value] end.to_h end @@ -130,25 +133,25 @@ def proposal end def availability_option_as_text(template) - key = "%s-%d" % [template.templatable_type.demodulize.tableize,template.templatable_id] + key = "#{template.templatable_type.demodulize.tableize}-#{template.templatable_id}" avaliablity_options.fetch(key) end def availability_options_for_select - avaliablity_options.collect {|key, value| [value, key] }.to_a + avaliablity_options.collect { |key, value| [value, key] }.to_a end def avaliablity_options - @avaliablity_options = { "organizations-%d" % [current_organization.id] => t('global_scope', scope: 'decidim.templates.admin.proposal_answer_templates.index')} + @avaliablity_options = { "organizations-#{current_organization.id}" => t("global_scope", scope: "decidim.templates.admin.proposal_answer_templates.index") } Decidim::Component.includes(:participatory_space).where(manifest_name: :proposals) - .select{|a| a.participatory_space.decidim_organization_id == current_organization.id }.each do |component| - @avaliablity_options["components-%d" % component.id] = formated_name(component) + .select { |a| a.participatory_space.decidim_organization_id == current_organization.id }.each do |component| + @avaliablity_options["components-#{component.id}"] = formated_name(component) end @avaliablity_options end def formated_name(component) - "%s ( %s )" % [translated_attribute(component.name), translated_attribute(component.participatory_space.title)] + "#{translated_attribute(component.name)} ( #{translated_attribute(component.participatory_space.title)} )" end def template diff --git a/decidim-templates/app/forms/decidim/templates/admin/proposal_answer_template_form.rb b/decidim-templates/app/forms/decidim/templates/admin/proposal_answer_template_form.rb index b472e5aaefc8..2278a96964d9 100644 --- a/decidim-templates/app/forms/decidim/templates/admin/proposal_answer_template_form.rb +++ b/decidim-templates/app/forms/decidim/templates/admin/proposal_answer_template_form.rb @@ -10,7 +10,7 @@ class ProposalAnswerTemplateForm < TemplateForm validates :internal_state, presence: true def map_model(model) - self.scope_for_availability = "%s-%d" % [model.templatable_type.try(:demodulize).try(:tableize),model.templatable_id.to_i] + self.scope_for_availability = "#{model.templatable_type.try(:demodulize).try(:tableize)}-#{model.templatable_id.to_i}" (model.field_values || []).to_h.map do |k, v| self[k.to_sym] = v end diff --git a/decidim-templates/db/migrate/20221006055954_add_field_values_to_decidim_templates.rb b/decidim-templates/db/migrate/20221006055954_add_field_values_to_decidim_templates.rb index b806c6866aac..0d129239f85a 100644 --- a/decidim-templates/db/migrate/20221006055954_add_field_values_to_decidim_templates.rb +++ b/decidim-templates/db/migrate/20221006055954_add_field_values_to_decidim_templates.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddFieldValuesToDecidimTemplates < ActiveRecord::Migration[6.0] def change add_column :decidim_templates_templates, :field_values, :json, default: {} diff --git a/decidim-templates/db/migrate/20221006184809_add_target_to_decidim_templates_templates.rb b/decidim-templates/db/migrate/20221006184809_add_target_to_decidim_templates_templates.rb index 8db9cc05dc7a..e4e1ffba58b8 100644 --- a/decidim-templates/db/migrate/20221006184809_add_target_to_decidim_templates_templates.rb +++ b/decidim-templates/db/migrate/20221006184809_add_target_to_decidim_templates_templates.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddTargetToDecidimTemplatesTemplates < ActiveRecord::Migration[6.0] def change add_column :decidim_templates_templates, :target, :string diff --git a/decidim-templates/db/migrate/20221006184905_migrate_templateable.rb b/decidim-templates/db/migrate/20221006184905_migrate_templateable.rb index b15bac191ec3..0034e8821aa0 100644 --- a/decidim-templates/db/migrate/20221006184905_migrate_templateable.rb +++ b/decidim-templates/db/migrate/20221006184905_migrate_templateable.rb @@ -1,10 +1,11 @@ +# frozen_string_literal: true + class MigrateTemplateable < ActiveRecord::Migration[6.0] def self.up Decidim::Templates::Template.find_each do |template| - template.update_attribute(:target, template.templatable_type.demodulize.tableize.singularize) + template.update(target: template.templatable_type.demodulize.tableize.singularize) end end - def self.down - end + def self.down; end end diff --git a/decidim-templates/lib/decidim/templates/test/factories.rb b/decidim-templates/lib/decidim/templates/test/factories.rb index ed94c23d09fe..dc82e7a4e528 100644 --- a/decidim-templates/lib/decidim/templates/test/factories.rb +++ b/decidim-templates/lib/decidim/templates/test/factories.rb @@ -9,6 +9,12 @@ templatable { build(:dummy_resource) } name { Decidim::Faker::Localized.sentence } + trait :proposal_answer do + templatable { organization } + target { :proposal_answer } + field_values { { internal_state: :answered } } + end + ## Questionnaire templates factory :questionnaire_template do trait :with_questions do diff --git a/decidim-templates/spec/commands/decidim/templates/admin/copy_proposal_answer_template_spec.rb b/decidim-templates/spec/commands/decidim/templates/admin/copy_proposal_answer_template_spec.rb new file mode 100644 index 000000000000..aac40c964496 --- /dev/null +++ b/decidim-templates/spec/commands/decidim/templates/admin/copy_proposal_answer_template_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require "spec_helper" + +module Decidim + module Templates + module Admin + describe CopyProposalAnswerTemplateSpec do + let(:template) { create(:template, :proposal_answer) } + + describe "when the template is invalid" do + before do + template.update(name: nil) + end + + it "broadcasts invalid" do + expect { described_class.call(template) }.to broadcast(:invalid) + end + end + + describe "when the template is valid" do + let(:destination_template) do + events = described_class.call(template) + # events => { :ok => copied_template } + expect(events).to have_key(:ok) + events[:ok].template + end + + it "applies template attributes to the questionnaire" do + expect(destination_template.title).to eq(template.title) + expect(destination_template.description).to eq(template.description) + expect(destination_template.field_values).to eq(template.field_values) + expect(destination_template.templatable).to eq(template.templatable) + expect(destination_template.target).to eq(template.target) + end + end + end + end + end +end diff --git a/decidim-templates/spec/commands/decidim/templates/admin/destroy_questionnaire_template_spec.rb b/decidim-templates/spec/commands/decidim/templates/admin/destroy_questionnaire_template_spec.rb new file mode 100644 index 000000000000..a3a0dfe00d5f --- /dev/null +++ b/decidim-templates/spec/commands/decidim/templates/admin/destroy_questionnaire_template_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require "spec_helper" + +module Decidim + module Templates + module Admin + describe DestroyQuestionnaireTemplate do + let(:template) { create(:questionnaire_template) } + let(:admin) { create(:user, :admin) } + let!(:templatable) { template.templatable } + + it "destroy the templatable" do + described_class.call(template, admin) + expect { templatable.reload }.to raise_error(ActiveRecord::RecordNotFound) + end + + it "destroy the template" do + described_class.call(template, admin) + expect { template.reload }.to raise_error(ActiveRecord::RecordNotFound) + end + end + end + end +end diff --git a/decidim-templates/spec/commands/decidim/templates/admin/destroy_template_spec.rb b/decidim-templates/spec/commands/decidim/templates/admin/destroy_template_spec.rb new file mode 100644 index 000000000000..59a67f238c28 --- /dev/null +++ b/decidim-templates/spec/commands/decidim/templates/admin/destroy_template_spec.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require "spec_helper" + +module Decidim + module Templates + module Admin + describe DestroyTemplate do + let(:template) { create(:questionnaire_template) } + let(:admin) { create(:user, :admin) } + let!(:templatable) { template.templatable } + + it "destroy the template" do + described_class.call(template, admin) + expect { template.reload }.to raise_error(ActiveRecord::RecordNotFound) + end + end + end + end +end diff --git a/decidim-templates/spec/models/decidim/templates/template_spec.rb b/decidim-templates/spec/models/decidim/templates/template_spec.rb index edc3f35122ee..cbe58b813391 100644 --- a/decidim-templates/spec/models/decidim/templates/template_spec.rb +++ b/decidim-templates/spec/models/decidim/templates/template_spec.rb @@ -27,14 +27,14 @@ module Templates expect(subject.templatable).to be_a(Decidim::DummyResources::DummyResource) end - describe "on destroy" do - let(:templatable) { template.templatable } - - it "destroys the templatable" do - template.destroy! - expect { templatable.reload }.to raise_error(ActiveRecord::RecordNotFound) - end - end + # describe "on destroy" do + # let(:templatable) { template.templatable } + # + # it "destroys the templatable" do + # template.destroy! + # expect { templatable.reload }.to raise_error(ActiveRecord::RecordNotFound) + # end + # end describe "#resource_name" do it "returns the templatable model name without namespace, downcased and postfixed with _templates" do diff --git a/decidim-templates/spec/spec_helper.rb b/decidim-templates/spec/spec_helper.rb index db3a51cf80ab..aff3fb19406c 100644 --- a/decidim-templates/spec/spec_helper.rb +++ b/decidim-templates/spec/spec_helper.rb @@ -4,6 +4,6 @@ ENV["ENGINE_ROOT"] = File.dirname(__dir__) -Decidim::Dev.dummy_app_path = File.expand_path(File.join("..", "spec", "decidim_dummy_app")) +Decidim::Dev.dummy_app_path = File.expand_path(File.join( "spec", "decidim_dummy_app")) require "decidim/dev/test/base_spec_helper" From 78bc913d79eb2f1afd9e403ebb288c6deea9260a Mon Sep 17 00:00:00 2001 From: Alexandru-Emil Lupu Date: Mon, 10 Oct 2022 11:13:17 +0300 Subject: [PATCH 05/17] Add more tests --- .../lib/decidim/templates/test/factories.rb | 2 +- .../proposal_answer_template_form_spec.rb | 63 ++++++++ ...ire_form_spec.rb => template_form_spec.rb} | 0 decidim-templates/spec/spec_helper.rb | 2 +- ..._manages_proposal_answer_templates_spec.rb | 151 ++++++++++++++++++ 5 files changed, 216 insertions(+), 2 deletions(-) create mode 100644 decidim-templates/spec/forms/decidim/templates/admin/proposal_answer_template_form_spec.rb rename decidim-templates/spec/forms/decidim/templates/admin/{questionnaire_form_spec.rb => template_form_spec.rb} (100%) create mode 100644 decidim-templates/spec/system/admin/admin_manages_proposal_answer_templates_spec.rb diff --git a/decidim-templates/lib/decidim/templates/test/factories.rb b/decidim-templates/lib/decidim/templates/test/factories.rb index dc82e7a4e528..a96618a0adbd 100644 --- a/decidim-templates/lib/decidim/templates/test/factories.rb +++ b/decidim-templates/lib/decidim/templates/test/factories.rb @@ -12,7 +12,7 @@ trait :proposal_answer do templatable { organization } target { :proposal_answer } - field_values { { internal_state: :answered } } + field_values { { internal_state: :accepted } } end ## Questionnaire templates diff --git a/decidim-templates/spec/forms/decidim/templates/admin/proposal_answer_template_form_spec.rb b/decidim-templates/spec/forms/decidim/templates/admin/proposal_answer_template_form_spec.rb new file mode 100644 index 000000000000..974d7f6de6cb --- /dev/null +++ b/decidim-templates/spec/forms/decidim/templates/admin/proposal_answer_template_form_spec.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +require "spec_helper" + +module Decidim + module Templates + module Admin + describe ProposalAnswerTemplateForm do + subject do + described_class.from_params(attributes).with_context( + current_organization: current_organization + ) + end + + let(:current_organization) { create(:organization) } + + let(:name) do + { + "en" => name_english, + "ca" => "Nom", + "es" => "Nombre" + } + end + + let(:description) do + { + "en" => "

Content

", + "ca" => "

Contingut

", + "es" => "

Contenido

" + } + end + + let(:internal_state) { :accepted } + + let(:name_english) { "Name" } + + let(:attributes) do + { + "name" => name, + "description" => description, + "internal_state" => internal_state + } + end + + context "when everything is OK" do + it { is_expected.to be_valid } + end + + context "when name is not valid" do + let(:name_english) { "" } + + it { is_expected.not_to be_valid } + end + + context "when internal_state is not valid" do + let(:internal_state) { "" } + + it { is_expected.not_to be_valid } + end + end + end + end +end diff --git a/decidim-templates/spec/forms/decidim/templates/admin/questionnaire_form_spec.rb b/decidim-templates/spec/forms/decidim/templates/admin/template_form_spec.rb similarity index 100% rename from decidim-templates/spec/forms/decidim/templates/admin/questionnaire_form_spec.rb rename to decidim-templates/spec/forms/decidim/templates/admin/template_form_spec.rb diff --git a/decidim-templates/spec/spec_helper.rb b/decidim-templates/spec/spec_helper.rb index aff3fb19406c..cb14fdb3a104 100644 --- a/decidim-templates/spec/spec_helper.rb +++ b/decidim-templates/spec/spec_helper.rb @@ -4,6 +4,6 @@ ENV["ENGINE_ROOT"] = File.dirname(__dir__) -Decidim::Dev.dummy_app_path = File.expand_path(File.join( "spec", "decidim_dummy_app")) +Decidim::Dev.dummy_app_path = File.expand_path(File.join( "..","spec", "decidim_dummy_app")) require "decidim/dev/test/base_spec_helper" diff --git a/decidim-templates/spec/system/admin/admin_manages_proposal_answer_templates_spec.rb b/decidim-templates/spec/system/admin/admin_manages_proposal_answer_templates_spec.rb new file mode 100644 index 000000000000..6cd3c34ba4f6 --- /dev/null +++ b/decidim-templates/spec/system/admin/admin_manages_proposal_answer_templates_spec.rb @@ -0,0 +1,151 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe "Admin manages proposal answer templates", type: :system do + let!(:organization) { create :organization } + let!(:user) { create :user, :confirmed, organization: organization } + + before do + switch_to_host(organization.host) + login_as user, scope: :user + visit decidim_admin_templates.proposal_answer_templates_path + end + + describe "listing templates" do + let!(:template) { create(:template, :proposal_answer, organization: organization) } + + before do + visit decidim_admin_templates.proposal_answer_templates_path + end + + it "shows a table with the templates info" do + within ".questionnaire-templates" do + expect(page).to have_i18n_content(template.name) + expect(page).to have_i18n_content("Global scope") + end + end + end + + describe "creating a questionnaire_template" do + before do + within ".layout-content" do + click_link("New") + end + end + + it "creates a new template with a questionnaire as templatable" do + within ".new_proposal_answer_template" do + fill_in_i18n( + :proposal_answer_template_name, + "#proposal_answer_template-name-tabs", + en: "My template", + es: "Mi plantilla", + ca: "La meva plantilla" + ) + fill_in_i18n( + :proposal_answer_template_description, + "#proposal_answer_template-description-tabs", + en: "Description", + es: "Descripción", + ca: "Descripció" + ) + + choose "Not answered" + + page.find("*[type=submit]").click + end + + expect(page).to have_admin_callout("successfully") + end + end + + describe "updating a template" do + let!(:template) { create(:template, :proposal_answer, organization: organization) } + + before do + visit decidim_admin_templates.proposal_answer_templates_path + click_link translated(template.name) + end + + it "updates a template" do + fill_in_i18n( + :proposal_answer_template_name, + "#proposal_answer_template-name-tabs", + en: "My new name", + es: "Mi nuevo nombre", + ca: "El meu nou nom" + ) + + within ".edit_proposal_answer_template" do + page.find("*[type=submit]").click + end + + expect(page).to have_admin_callout("successfully") + + within ".container" do + expect(page).to have_current_path decidim_admin_templates.edit_proposal_answer_template_path(template) + expect(page.find("#proposal_answer_template_name_en").value).to eq("My new name") + end + end + end + + describe "updating a template with invalid values" do + let!(:template) { create(:template, :proposal_answer, organization: organization) } + + before do + visit decidim_admin_templates.proposal_answer_templates_path + click_link translated(template.name) + end + + it "does not update the template" do + fill_in_i18n( + :proposal_answer_template_name, + "#proposal_answer_template-name-tabs", + en: "", + es: "", + ca: "" + ) + + within ".edit_proposal_answer_template" do + find("*[type=submit]").click + end + + expect(page).to have_admin_callout("problem") + end + end + + describe "copying a template" do + let!(:template) { create(:template, :proposal_answer, organization: organization) } + + before do + visit decidim_admin_templates.proposal_answer_templates_path + end + + it "copies the template" do + within find("tr", text: translated(template.name)) do + click_link "Duplicate" + end + + expect(page).to have_admin_callout("successfully") + expect(page).to have_content(template.name["en"], count: 2) + end + end + + describe "destroying a template" do + let!(:template) { create(:template, :proposal_answer, organization: organization) } + + before do + visit decidim_admin_templates.proposal_answer_templates_path + end + + it "destroys the template" do + within find("tr", text: translated(template.name)) do + accept_confirm { click_link "Delete" } + end + + expect(page).to have_admin_callout("successfully") + expect(page).to have_no_i18n_content(template.name) + end + end +end From 5437ae1f396760751aeba2c00d7f8fbf989185e9 Mon Sep 17 00:00:00 2001 From: Alexandru-Emil Lupu Date: Mon, 10 Oct 2022 11:25:20 +0300 Subject: [PATCH 06/17] Linting --- .../templates/admin/proposal_answer_template_form_spec.rb | 6 +++--- decidim-templates/spec/spec_helper.rb | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/decidim-templates/spec/forms/decidim/templates/admin/proposal_answer_template_form_spec.rb b/decidim-templates/spec/forms/decidim/templates/admin/proposal_answer_template_form_spec.rb index 974d7f6de6cb..622ad8d4a619 100644 --- a/decidim-templates/spec/forms/decidim/templates/admin/proposal_answer_template_form_spec.rb +++ b/decidim-templates/spec/forms/decidim/templates/admin/proposal_answer_template_form_spec.rb @@ -36,9 +36,9 @@ module Admin let(:attributes) do { - "name" => name, - "description" => description, - "internal_state" => internal_state + "name" => name, + "description" => description, + "internal_state" => internal_state } end diff --git a/decidim-templates/spec/spec_helper.rb b/decidim-templates/spec/spec_helper.rb index cb14fdb3a104..db3a51cf80ab 100644 --- a/decidim-templates/spec/spec_helper.rb +++ b/decidim-templates/spec/spec_helper.rb @@ -4,6 +4,6 @@ ENV["ENGINE_ROOT"] = File.dirname(__dir__) -Decidim::Dev.dummy_app_path = File.expand_path(File.join( "..","spec", "decidim_dummy_app")) +Decidim::Dev.dummy_app_path = File.expand_path(File.join("..", "spec", "decidim_dummy_app")) require "decidim/dev/test/base_spec_helper" From 354879c80091b9b1afe9a2b7fade46298b5c1e02 Mon Sep 17 00:00:00 2001 From: Alexandru-Emil Lupu Date: Mon, 10 Oct 2022 11:27:07 +0300 Subject: [PATCH 07/17] Fix class name --- .../templates/admin/copy_proposal_answer_template_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/decidim-templates/spec/commands/decidim/templates/admin/copy_proposal_answer_template_spec.rb b/decidim-templates/spec/commands/decidim/templates/admin/copy_proposal_answer_template_spec.rb index aac40c964496..c341a2f1572f 100644 --- a/decidim-templates/spec/commands/decidim/templates/admin/copy_proposal_answer_template_spec.rb +++ b/decidim-templates/spec/commands/decidim/templates/admin/copy_proposal_answer_template_spec.rb @@ -5,7 +5,7 @@ module Decidim module Templates module Admin - describe CopyProposalAnswerTemplateSpec do + describe CopyProposalAnswerTemplate do let(:template) { create(:template, :proposal_answer) } describe "when the template is invalid" do From 6c8b62599c6eee721546d7efc8aea7cd18b51bef Mon Sep 17 00:00:00 2001 From: Alexandru-Emil Lupu Date: Mon, 10 Oct 2022 13:19:11 +0300 Subject: [PATCH 08/17] Add latest review changes --- .../admin/proposal_answer_templates_controller.rb | 7 ++++--- .../templates/admin/proposal_answer_template_chooser.js | 3 ++- .../admin/proposal_answer_templates/_form.html.erb | 2 +- decidim-templates/config/locales/en.yml | 6 +++--- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb b/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb index 1d4137e28a99..c006df6f2222 100644 --- a/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb +++ b/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb @@ -142,16 +142,17 @@ def availability_options_for_select end def avaliablity_options - @avaliablity_options = { "organizations-#{current_organization.id}" => t("global_scope", scope: "decidim.templates.admin.proposal_answer_templates.index") } + @avaliablity_options = {} Decidim::Component.includes(:participatory_space).where(manifest_name: :proposals) .select { |a| a.participatory_space.decidim_organization_id == current_organization.id }.each do |component| @avaliablity_options["components-#{component.id}"] = formated_name(component) end - @avaliablity_options + global_scope = { "organizations-#{current_organization.id}" => t("global_scope", scope: "decidim.templates.admin.proposal_answer_templates.index") } + @avaliablity_options = global_scope.merge(Hash[@avaliablity_options.sort_by{ |_, val| val } ]) end def formated_name(component) - "#{translated_attribute(component.name)} ( #{translated_attribute(component.participatory_space.title)} )" + "#{t(component.participatory_space.class.name.underscore, scope: 'activerecord.models', count: 1)}: #{translated_attribute(component.participatory_space.title)} " end def template diff --git a/decidim-templates/app/packs/src/decidim/templates/admin/proposal_answer_template_chooser.js b/decidim-templates/app/packs/src/decidim/templates/admin/proposal_answer_template_chooser.js index 7dcd4544b939..3d636be09fc1 100644 --- a/decidim-templates/app/packs/src/decidim/templates/admin/proposal_answer_template_chooser.js +++ b/decidim-templates/app/packs/src/decidim/templates/admin/proposal_answer_template_chooser.js @@ -11,7 +11,8 @@ $(() => { local_element = $(element); let $locale = local_element.siblings('input[type=hidden]').attr('id').replace('proposal_answer_answer_', ''); let editor = Quill.find(element); - editor.setText(data.template[$locale]); + let delta = editor.clipboard.convert(data.template[$locale]); + editor.setContents(delta, 'silent'); }); }); }); diff --git a/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/_form.html.erb b/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/_form.html.erb index 9820217ef68a..32edf046d34d 100644 --- a/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/_form.html.erb +++ b/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/_form.html.erb @@ -10,7 +10,7 @@
- <%= form.translated :text_area, :description, rows: 3, label: t('.answer_template') %> + <%= form.translated :editor, :description, rows: 15, label: t('.answer_template') %> <%= t('.hint').html_safe %>
    diff --git a/decidim-templates/config/locales/en.yml b/decidim-templates/config/locales/en.yml index c82703427d83..f234d3a8c996 100644 --- a/decidim-templates/config/locales/en.yml +++ b/decidim-templates/config/locales/en.yml @@ -46,9 +46,9 @@ en: form: answer_template: Answer template hint: "Hint: You can use theese variables anywhere on the answer template that will be replaced when using the template" - hint1: "%{organization}" will be replaced by the organization's name - hint2: "%{name}" will be replaced by the author's name - hint3: "%{admin}" will be replaced by the admin's name (the one answering the proposal) + hint1: %{organization} will be replaced by the organization's name + hint2: %{name} will be replaced by the author's name + hint3: %{admin} will be replaced by the admin's name (the one answering the proposal) save: Save template_title: Template information index: From 83c33218cd7999db664f386dfb74783dd293a2a0 Mon Sep 17 00:00:00 2001 From: Alexandru-Emil Lupu Date: Tue, 11 Oct 2022 16:00:22 +0300 Subject: [PATCH 09/17] Implement code review recommendations --- .../templates/admin/copy_proposal_answer_template.rb | 2 +- .../templates/admin/create_proposal_answer_template.rb | 2 +- .../templates/admin/proposal_answer_templates_controller.rb | 6 ++---- decidim-templates/config/locales/en.yml | 6 +++--- .../templates/admin/copy_proposal_answer_template_spec.rb | 4 ++-- .../admin/admin_manages_proposal_answer_templates_spec.rb | 6 +++--- 6 files changed, 12 insertions(+), 14 deletions(-) diff --git a/decidim-templates/app/commands/decidim/templates/admin/copy_proposal_answer_template.rb b/decidim-templates/app/commands/decidim/templates/admin/copy_proposal_answer_template.rb index 38c53d78f793..1942e4446fd7 100644 --- a/decidim-templates/app/commands/decidim/templates/admin/copy_proposal_answer_template.rb +++ b/decidim-templates/app/commands/decidim/templates/admin/copy_proposal_answer_template.rb @@ -2,7 +2,7 @@ module Decidim module Templates - # A command with all the business logic when duplicating a questionnaire template + # A command with all the business logic when duplicating a proposal's answer template module Admin class CopyProposalAnswerTemplate < Rectify::Command def initialize(template) diff --git a/decidim-templates/app/commands/decidim/templates/admin/create_proposal_answer_template.rb b/decidim-templates/app/commands/decidim/templates/admin/create_proposal_answer_template.rb index dd27b71325d4..16c896a21e72 100644 --- a/decidim-templates/app/commands/decidim/templates/admin/create_proposal_answer_template.rb +++ b/decidim-templates/app/commands/decidim/templates/admin/create_proposal_answer_template.rb @@ -6,7 +6,7 @@ module Admin class CreateProposalAnswerTemplate < Rectify::Command # Initializes the command. # - # form - The source for this QuestionnaireTemplate. + # form - The source for this ProposalAnswerTemplate. def initialize(form) @form = form end diff --git a/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb b/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb index c006df6f2222..fafa34bb7aab 100644 --- a/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb +++ b/decidim-templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb @@ -17,7 +17,6 @@ def new def edit enforce_permission_to :update, :template, template: template @form = form(ProposalAnswerTemplateForm).from_model(template) - # @preview_form = form(Decidim::Forms::QuestionnaireForm).from_model(template.templatable) end def create @@ -51,7 +50,6 @@ def destroy def fetch enforce_permission_to :read, :template, template: template - # enforce_permission_to :create, :proposal_answer, proposal: proposal response_object = { state: template.field_values["internal_state"], @@ -148,11 +146,11 @@ def avaliablity_options @avaliablity_options["components-#{component.id}"] = formated_name(component) end global_scope = { "organizations-#{current_organization.id}" => t("global_scope", scope: "decidim.templates.admin.proposal_answer_templates.index") } - @avaliablity_options = global_scope.merge(Hash[@avaliablity_options.sort_by{ |_, val| val } ]) + @avaliablity_options = global_scope.merge(Hash[@avaliablity_options.sort_by { |_, val| val }]) end def formated_name(component) - "#{t(component.participatory_space.class.name.underscore, scope: 'activerecord.models', count: 1)}: #{translated_attribute(component.participatory_space.title)} " + "#{t(component.participatory_space.class.name.underscore, scope: "activerecord.models", count: 1)}: #{translated_attribute(component.participatory_space.title)} " end def template diff --git a/decidim-templates/config/locales/en.yml b/decidim-templates/config/locales/en.yml index f234d3a8c996..6593c2f1193c 100644 --- a/decidim-templates/config/locales/en.yml +++ b/decidim-templates/config/locales/en.yml @@ -46,9 +46,9 @@ en: form: answer_template: Answer template hint: "Hint: You can use theese variables anywhere on the answer template that will be replaced when using the template" - hint1: %{organization} will be replaced by the organization's name - hint2: %{name} will be replaced by the author's name - hint3: %{admin} will be replaced by the admin's name (the one answering the proposal) + hint1: "%{organization} will be replaced by the organization's name" + hint2: "%{name} will be replaced by the author's name" + hint3: "%{admin} will be replaced by the admin's name (the one answering the proposal)" save: Save template_title: Template information index: diff --git a/decidim-templates/spec/commands/decidim/templates/admin/copy_proposal_answer_template_spec.rb b/decidim-templates/spec/commands/decidim/templates/admin/copy_proposal_answer_template_spec.rb index c341a2f1572f..cc1156b89fa8 100644 --- a/decidim-templates/spec/commands/decidim/templates/admin/copy_proposal_answer_template_spec.rb +++ b/decidim-templates/spec/commands/decidim/templates/admin/copy_proposal_answer_template_spec.rb @@ -23,11 +23,11 @@ module Admin events = described_class.call(template) # events => { :ok => copied_template } expect(events).to have_key(:ok) - events[:ok].template + events[:ok] end it "applies template attributes to the questionnaire" do - expect(destination_template.title).to eq(template.title) + expect(destination_template.name).to eq(template.name) expect(destination_template.description).to eq(template.description) expect(destination_template.field_values).to eq(template.field_values) expect(destination_template.templatable).to eq(template.templatable) diff --git a/decidim-templates/spec/system/admin/admin_manages_proposal_answer_templates_spec.rb b/decidim-templates/spec/system/admin/admin_manages_proposal_answer_templates_spec.rb index 6cd3c34ba4f6..26eb0dc506f7 100644 --- a/decidim-templates/spec/system/admin/admin_manages_proposal_answer_templates_spec.rb +++ b/decidim-templates/spec/system/admin/admin_manages_proposal_answer_templates_spec.rb @@ -27,14 +27,14 @@ end end - describe "creating a questionnaire_template" do + describe "creating a proposal_answer_template" do before do within ".layout-content" do click_link("New") end end - it "creates a new template with a questionnaire as templatable" do + it "creates a new template with a Organization as templatable" do within ".new_proposal_answer_template" do fill_in_i18n( :proposal_answer_template_name, @@ -43,7 +43,7 @@ es: "Mi plantilla", ca: "La meva plantilla" ) - fill_in_i18n( + fill_in_i18n_editor( :proposal_answer_template_description, "#proposal_answer_template-description-tabs", en: "Description", From b3af388819b49cb3275c4c3b3cb67b7fb19a11cc Mon Sep 17 00:00:00 2001 From: Alexandru-Emil Lupu Date: Tue, 11 Oct 2022 16:13:20 +0300 Subject: [PATCH 10/17] Add corect labels to table header --- .../templates/admin/proposal_answer_templates/index.html.erb | 4 ++-- decidim-templates/config/locales/en.yml | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/index.html.erb b/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/index.html.erb index 8ac8593a31aa..10c0ce25f603 100644 --- a/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/index.html.erb +++ b/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/index.html.erb @@ -14,8 +14,8 @@ <%= t("template.name", scope: "decidim.models") %> - <%= t("questionnaire_template.fields.title", scope: "decidim.models") %> - <%= t("questionnaire_template.fields.questions", scope: "decidim.models") %> + <%= t(".internal_state") %> + <%= t(".scope_for_availability") %> <%= t("template.fields.created_at", scope: "decidim.models") %> diff --git a/decidim-templates/config/locales/en.yml b/decidim-templates/config/locales/en.yml index 6593c2f1193c..fdbbc86935da 100644 --- a/decidim-templates/config/locales/en.yml +++ b/decidim-templates/config/locales/en.yml @@ -54,6 +54,8 @@ en: index: confirm_delete: Are you sure you want to delete this template? global_scope: Global scope + internal_state: Internal State + scope_for_availability: Scope title: Proposal answers template_chooser: select_template: Select a template answer From 904dc0e468998821af6da9a5643fda5fcfff6210 Mon Sep 17 00:00:00 2001 From: Alexandru-Emil Lupu Date: Tue, 11 Oct 2022 19:56:21 +0300 Subject: [PATCH 11/17] Running EsLint --- .../admin/proposal_answer_template_chooser.js | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/decidim-templates/app/packs/src/decidim/templates/admin/proposal_answer_template_chooser.js b/decidim-templates/app/packs/src/decidim/templates/admin/proposal_answer_template_chooser.js index 3d636be09fc1..0d2ecaf3ad35 100644 --- a/decidim-templates/app/packs/src/decidim/templates/admin/proposal_answer_template_chooser.js +++ b/decidim-templates/app/packs/src/decidim/templates/admin/proposal_answer_template_chooser.js @@ -1,19 +1,21 @@ $(() => { - $("#proposal_answer_template_chooser").change(function(){ - $.getJSON($(this).data('url'), { - id: $(this).val(), - proposal_id: $(this).data('proposal') - }).done(function(data){ - $("#proposal_answer_internal_state_" + data.state).trigger('click'); + $("#proposal_answer_template_chooser").change(function() { + let dropDown = $("#proposal_answer_template_chooser"); + $.getJSON(dropDown.data("url"), { + id: dropDown.val(), + /* eslint camelcase: [0] */ + proposal_id: dropDown.data("proposal") + }).done(function(data) { + $(`#proposal_answer_internal_state_${data.state}`).trigger("click"); - let $editors = $("#proposal_answer_template_chooser").parent().parent().find('.tabs-panel').find('.editor-container'); - $editors.each(function(index, element){ - local_element = $(element); - let $locale = local_element.siblings('input[type=hidden]').attr('id').replace('proposal_answer_answer_', ''); - let editor = Quill.find(element); - let delta = editor.clipboard.convert(data.template[$locale]); - editor.setContents(delta, 'silent'); - }); + let $editors = dropDown.parent().parent().find(".tabs-panel").find(".editor-container"); + $editors.each(function(index, element) { + let localElement = $(element); + let $locale = localElement.siblings("input[type=hidden]").attr("id").replace("proposal_answer_answer_", ""); + let editor = Quill.find(element); + let delta = editor.clipboard.convert(data.template[$locale]); + editor.setContents(delta, "silent"); }); }); + }); }); From 68e52041cb730de43c3da4cfc0dbb25ef51f8d24 Mon Sep 17 00:00:00 2001 From: Alexandru-Emil Lupu Date: Tue, 11 Oct 2022 22:11:13 +0300 Subject: [PATCH 12/17] Running ERBLinter --- .../admin/proposal_answer_templates/_form.html.erb | 6 +++--- .../proposal_answer_templates/_template_chooser.html.erb | 2 +- .../admin/proposal_answer_templates/index.html.erb | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/_form.html.erb b/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/_form.html.erb index 32edf046d34d..41950171611c 100644 --- a/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/_form.html.erb +++ b/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/_form.html.erb @@ -10,9 +10,9 @@
- <%= form.translated :editor, :description, rows: 15, label: t('.answer_template') %> + <%= form.translated :editor, :description, rows: 15, label: t(".answer_template") %> - <%= t('.hint').html_safe %> + <%= t(".hint").html_safe %>
  • <%= t(".hint1").html_safe %>
  • <%= t(".hint2").html_safe %>
  • @@ -25,7 +25,7 @@ <%= form.collection_radio_buttons :internal_state, Decidim::Proposals::Proposal::POSSIBLE_STATES - %w(withdrawn), :to_s, - ->(mode) { t(mode, scope: 'decidim.proposals.admin.proposal_answers.form') } %> + ->(mode) { t(mode, scope: "decidim.proposals.admin.proposal_answers.form") } %>
diff --git a/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/_template_chooser.html.erb b/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/_template_chooser.html.erb index e6ca4d8a7083..3852039ab595 100644 --- a/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/_template_chooser.html.erb +++ b/decidim-templates/app/views/decidim/templates/admin/proposal_answer_templates/_template_chooser.html.erb @@ -8,7 +8,7 @@ <%= javascript_pack_tag "decidim_templates_admin" %>