forked from decidim/decidim
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add templates support for proposal's answers (decidim#11824)
* Add Templates support for Proposal Answers * Running linters * Fixing failing specs * Check for existing element * Apply suggestions from code review Co-authored-by: Andrés Pereira de Lucena <[email protected]> * Apply review recommendations * Fix lint * Apply suggestions from code review Co-authored-by: Andrés Pereira de Lucena <[email protected]> * Apply review recommendations * Changing spec description for clarity * Lint --------- Co-authored-by: Andrés Pereira de Lucena <[email protected]>
- Loading branch information
1 parent
d397113
commit d814fdc
Showing
24 changed files
with
1,241 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
decidim-templates/app/commands/decidim/templates/admin/copy_proposal_answer_template.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# frozen_string_literal: true | ||
|
||
module Decidim | ||
module Templates | ||
# A command with all the business logic when duplicating a proposal's answer template | ||
module Admin | ||
class CopyProposalAnswerTemplate < CopyTemplate | ||
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 |
47 changes: 47 additions & 0 deletions
47
decidim-templates/app/commands/decidim/templates/admin/create_proposal_answer_template.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# frozen_string_literal: true | ||
|
||
module Decidim | ||
module Templates | ||
module Admin | ||
class CreateProposalAnswerTemplate < Decidim::Command | ||
# Initializes the command. | ||
# | ||
# form - The source for this ProposalAnswerTemplate. | ||
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 | ||
) | ||
|
||
@template.update!(templatable: identify_templateable_resource) | ||
|
||
broadcast(:ok, @template) | ||
end | ||
|
||
private | ||
|
||
def identify_templateable_resource | ||
resource = @form.current_organization | ||
if @form.component_constraint.present? | ||
found_component = Decidim::Component.find_by(id: @form.component_constraint, manifest_name: "proposals") | ||
if found_component.present? | ||
resource = found_component&.participatory_space&.decidim_organization_id == @form.current_organization.id ? found_component : nil | ||
end | ||
end | ||
resource | ||
end | ||
end | ||
end | ||
end | ||
end |
51 changes: 51 additions & 0 deletions
51
decidim-templates/app/commands/decidim/templates/admin/update_proposal_answer_template.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# frozen_string_literal: true | ||
|
||
module Decidim | ||
module Templates | ||
module Admin | ||
class UpdateProposalAnswerTemplate < Decidim::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 | ||
) | ||
|
||
@template.update!(templatable: identify_templateable_resource) | ||
|
||
broadcast(:ok, @template) | ||
end | ||
|
||
private | ||
|
||
def identify_templateable_resource | ||
resource = @form.current_organization | ||
if @form.component_constraint.present? | ||
found_component = Decidim::Component.find_by(id: @form.component_constraint, manifest_name: "proposals") | ||
if found_component.present? | ||
resource = found_component&.participatory_space&.decidim_organization_id == @form.current_organization.id ? found_component : nil | ||
end | ||
end | ||
resource | ||
end | ||
end | ||
end | ||
end | ||
end |
173 changes: 173 additions & 0 deletions
173
...templates/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
# frozen_string_literal: true | ||
|
||
module Decidim | ||
module Templates | ||
module Admin | ||
class ProposalAnswerTemplatesController < Decidim::Templates::Admin::ApplicationController | ||
include Decidim::TranslatableAttributes | ||
include Decidim::Paginable | ||
|
||
helper_method :availability_option_as_text, :availability_options_for_select | ||
|
||
def new | ||
enforce_permission_to :create, :template | ||
@form = form(ProposalAnswerTemplateForm).instance | ||
end | ||
|
||
def edit | ||
enforce_permission_to(:update, :template, template:) | ||
@form = form(ProposalAnswerTemplateForm).from_model(template) | ||
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 proposal_answer_templates_path | ||
end | ||
|
||
on(:invalid) do | ||
flash.now[:alert] = I18n.t("templates.create.error", scope: "decidim.admin") | ||
render :new | ||
end | ||
end | ||
end | ||
|
||
def destroy | ||
enforce_permission_to(:destroy, :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 fetch | ||
enforce_permission_to(:read, :template, template:) | ||
|
||
response_object = { | ||
state: template.field_values["internal_state"], | ||
template: populate_template_interpolations(proposal) | ||
} | ||
|
||
respond_to do |format| | ||
format.json do | ||
render json: response_object.to_json | ||
end | ||
end | ||
end | ||
|
||
def update | ||
enforce_permission_to(:update, :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 proposal_answer_templates_path | ||
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 copy | ||
enforce_permission_to :copy, :template | ||
|
||
CopyProposalAnswerTemplate.call(template, current_user) 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 | ||
|
||
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 populate_template_interpolations(proposal) | ||
template.description.to_h do |language, value| | ||
value.gsub!("%{organization}", proposal.organization.name) | ||
value.gsub!("%{name}", author_name(proposal)) | ||
value.gsub!("%{admin}", current_user.name) | ||
|
||
[language, value] | ||
end | ||
end | ||
|
||
def author_name(proposal) | ||
proposal.creator_author.try(:title) || proposal.creator_author.try(:name) | ||
end | ||
|
||
def proposal | ||
@proposal ||= Decidim::Proposals::Proposal.find(params[:proposalId]) | ||
end | ||
|
||
def availability_option_as_text(template) | ||
return unless template.templatable_type | ||
return t("global_scope", scope: "decidim.templates.admin.proposal_answer_templates.index") if template.templatable == current_organization | ||
|
||
avaliablity_options.select { |a| a.last == template.templatable_id }&.flatten&.first || t("templates.missing_resource", scope: "decidim.admin") | ||
end | ||
|
||
def availability_options_for_select | ||
avaliablity_options | ||
end | ||
|
||
def avaliablity_options | ||
@avaliablity_options = [] | ||
@avaliablity_options.push [t("global_scope", scope: "decidim.templates.admin.proposal_answer_templates.index"), 0] | ||
|
||
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.push [formatted_name(component), component.id] | ||
end | ||
|
||
@avaliablity_options | ||
end | ||
|
||
def formatted_name(component) | ||
space_type = t(component.participatory_space.class.name.underscore, scope: "activerecord.models", count: 1) | ||
"#{space_type}: #{translated_attribute(component.participatory_space.title)} > #{translated_attribute(component.name)}" | ||
end | ||
|
||
def template | ||
@template ||= Template.find_by(id: params[:id]) | ||
end | ||
|
||
def collection | ||
@collection ||= paginate(current_organization.templates.where(target: :proposal_answer).order(:id)) | ||
end | ||
end | ||
end | ||
end | ||
end |
23 changes: 23 additions & 0 deletions
23
decidim-templates/app/forms/decidim/templates/admin/proposal_answer_template_form.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# frozen_string_literal: true | ||
|
||
module Decidim | ||
module Templates | ||
module Admin | ||
class ProposalAnswerTemplateForm < TemplateForm | ||
attribute :internal_state, String | ||
attribute :component_constraint, Integer | ||
|
||
validates :internal_state, presence: true | ||
|
||
def map_model(model) | ||
self.internal_state = model.field_values["internal_state"] | ||
self.component_constraint = if model.templatable_type == "Decidim::Organization" | ||
0 | ||
else | ||
model.templatable&.id | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
3 changes: 2 additions & 1 deletion
3
decidim-templates/app/packs/entrypoints/decidim_templates_admin.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
import "src/decidim/templates/admin/block_template_chooser" | ||
import "src/decidim/templates/admin/block_user_template_chooser" | ||
import "src/decidim/templates/admin/proposal_answer_template_chooser" |
17 changes: 0 additions & 17 deletions
17
decidim-templates/app/packs/src/decidim/templates/admin/block_template_chooser.js
This file was deleted.
Oops, something went wrong.
20 changes: 20 additions & 0 deletions
20
decidim-templates/app/packs/src/decidim/templates/admin/block_user_template_chooser.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// Choose a Block User Message template, get it by AJAX and add the Template in the justification textarea | ||
document.addEventListener("DOMContentLoaded", () => { | ||
const blockTemplateChooser = document.getElementById("block_template_chooser"); | ||
if (blockTemplateChooser) { | ||
blockTemplateChooser.addEventListener("change", () => { | ||
const dropdown = document.getElementById("block_template_chooser"); | ||
const url = dropdown.getAttribute("data-url"); | ||
const templateId = dropdown.value; | ||
|
||
if (templateId === "") { | ||
return; | ||
} | ||
fetch(`${new URL(url).pathname}?${new URLSearchParams({ id: templateId })}`). | ||
then((response) => response.json()). | ||
then((data) => { | ||
document.getElementById("block_user_justification").value = data.template; | ||
}) | ||
}); | ||
} | ||
}); |
Oops, something went wrong.