decidim-templates 0.27.6 → 0.28.0.rc4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE-AGPLv3.txt +661 -0
  3. data/app/commands/decidim/templates/admin/apply_questionnaire_template.rb +1 -1
  4. data/app/commands/decidim/templates/admin/copy_proposal_answer_template.rb +21 -0
  5. data/app/commands/decidim/templates/admin/copy_questionnaire_template.rb +3 -33
  6. data/app/commands/decidim/templates/admin/copy_template.rb +43 -0
  7. data/app/commands/decidim/templates/admin/create_block_user_template.rb +15 -0
  8. data/app/commands/decidim/templates/admin/create_proposal_answer_template.rb +47 -0
  9. data/app/commands/decidim/templates/admin/create_questionnaire_template.rb +6 -19
  10. data/app/commands/decidim/templates/admin/create_template.rb +54 -0
  11. data/app/commands/decidim/templates/admin/destroy_questionnaire_template.rb +22 -0
  12. data/app/commands/decidim/templates/admin/update_proposal_answer_template.rb +51 -0
  13. data/app/commands/decidim/templates/admin/update_template.rb +6 -0
  14. data/app/controllers/decidim/templates/admin/application_controller.rb +0 -8
  15. data/app/controllers/decidim/templates/admin/block_user_templates_controller.rb +124 -0
  16. data/app/controllers/decidim/templates/admin/concerns/templatable.rb +1 -1
  17. data/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb +173 -0
  18. data/app/controllers/decidim/templates/admin/questionnaire_templates_controller.rb +4 -4
  19. data/app/forms/decidim/templates/admin/proposal_answer_template_form.rb +23 -0
  20. data/app/helpers/decidim/templates/admin/application_helper.rb +18 -0
  21. data/app/models/decidim/templates/template.rb +0 -6
  22. data/app/packs/entrypoints/decidim_templates_admin.js +2 -0
  23. data/app/packs/src/decidim/templates/admin/block_user_template_chooser.js +20 -0
  24. data/app/packs/src/decidim/templates/admin/proposal_answer_template_chooser.js +31 -0
  25. data/app/packs/stylesheets/decidim/templates/templates.scss +3 -12
  26. data/app/presenters/decidim/templates/admin_log/template_presenter.rb +2 -2
  27. data/app/views/decidim/templates/admin/block_user_templates/_form.html.erb +13 -0
  28. data/app/views/decidim/templates/admin/block_user_templates/_template_chooser.html.erb +12 -0
  29. data/app/views/decidim/templates/admin/block_user_templates/edit.html.erb +18 -0
  30. data/app/views/decidim/templates/admin/block_user_templates/index.html.erb +45 -0
  31. data/app/views/decidim/templates/admin/block_user_templates/new.html.erb +18 -0
  32. data/app/views/decidim/templates/admin/proposal_answer_templates/_form.html.erb +38 -0
  33. data/app/views/decidim/templates/admin/proposal_answer_templates/_template_chooser.html.erb +16 -0
  34. data/app/views/decidim/templates/admin/proposal_answer_templates/edit.html.erb +18 -0
  35. data/app/views/decidim/templates/admin/proposal_answer_templates/index.html.erb +51 -0
  36. data/app/views/decidim/templates/admin/proposal_answer_templates/new.html.erb +18 -0
  37. data/app/views/decidim/templates/admin/questionnaire_templates/_choose.html.erb +35 -35
  38. data/app/views/decidim/templates/admin/questionnaire_templates/_form.html.erb +9 -12
  39. data/app/views/decidim/templates/admin/questionnaire_templates/_preview.html.erb +52 -60
  40. data/app/views/decidim/templates/admin/questionnaire_templates/edit.html.erb +31 -16
  41. data/app/views/decidim/templates/admin/questionnaire_templates/index.html.erb +6 -8
  42. data/app/views/decidim/templates/admin/questionnaire_templates/new.html.erb +18 -7
  43. data/app/views/decidim/templates/admin/questionnaire_templates/preview.js.erb +4 -1
  44. data/app/views/layouts/decidim/admin/templates.html.erb +1 -9
  45. data/config/assets.rb +2 -1
  46. data/config/locales/ar.yml +8 -2
  47. data/config/locales/bg.yml +0 -73
  48. data/config/locales/ca.yml +47 -8
  49. data/config/locales/cs.yml +47 -8
  50. data/config/locales/de.yml +47 -8
  51. data/config/locales/en.yml +47 -8
  52. data/config/locales/es-MX.yml +47 -8
  53. data/config/locales/es-PY.yml +47 -8
  54. data/config/locales/es.yml +47 -8
  55. data/config/locales/eu.yml +47 -8
  56. data/config/locales/fi-plain.yml +47 -8
  57. data/config/locales/fi.yml +47 -8
  58. data/config/locales/fr-CA.yml +33 -8
  59. data/config/locales/fr.yml +47 -8
  60. data/config/locales/ga-IE.yml +6 -2
  61. data/config/locales/gl.yml +6 -10
  62. data/config/locales/hu.yml +6 -10
  63. data/config/locales/it.yml +6 -10
  64. data/config/locales/ja.yml +28 -8
  65. data/config/locales/kaa.yml +4 -1
  66. data/config/locales/lt.yml +18 -8
  67. data/config/locales/nl.yml +6 -11
  68. data/config/locales/no.yml +6 -10
  69. data/config/locales/pl.yml +6 -10
  70. data/config/locales/pt-BR.yml +6 -16
  71. data/config/locales/pt.yml +6 -10
  72. data/config/locales/ro-RO.yml +18 -8
  73. data/config/locales/sv.yml +6 -2
  74. data/config/locales/tr-TR.yml +8 -10
  75. data/config/locales/zh-CN.yml +6 -11
  76. data/config/locales/zh-TW.yml +18 -8
  77. data/db/migrate/20221006055954_add_field_values_and_target_to_decidim_templates.rb +21 -0
  78. data/db/seeds.rb +6 -6
  79. data/lib/decidim/templates/admin_engine.rb +22 -17
  80. data/lib/decidim/templates/engine.rb +4 -0
  81. data/lib/decidim/templates/menu.rb +48 -0
  82. data/lib/decidim/templates/test/factories.rb +23 -15
  83. data/lib/decidim/templates/test/shared_examples/copies_all_questionnaire_contents_examples.rb +3 -3
  84. data/lib/decidim/templates/test/shared_examples/uses_questionnaire_templates.rb +10 -8
  85. data/lib/decidim/templates/version.rb +1 -1
  86. metadata +52 -50
  87. data/config/locales/he-IL.yml +0 -1
  88. data/decidim-templates.gemspec +0 -33
@@ -0,0 +1,173 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Templates
5
+ module Admin
6
+ class ProposalAnswerTemplatesController < Decidim::Templates::Admin::ApplicationController
7
+ include Decidim::TranslatableAttributes
8
+ include Decidim::Paginable
9
+
10
+ helper_method :availability_option_as_text, :availability_options_for_select
11
+
12
+ def new
13
+ enforce_permission_to :create, :template
14
+ @form = form(ProposalAnswerTemplateForm).instance
15
+ end
16
+
17
+ def edit
18
+ enforce_permission_to(:update, :template, template:)
19
+ @form = form(ProposalAnswerTemplateForm).from_model(template)
20
+ end
21
+
22
+ def create
23
+ enforce_permission_to :create, :template
24
+
25
+ @form = form(ProposalAnswerTemplateForm).from_params(params)
26
+
27
+ CreateProposalAnswerTemplate.call(@form) do
28
+ on(:ok) do |_template|
29
+ flash[:notice] = I18n.t("templates.create.success", scope: "decidim.admin")
30
+ redirect_to proposal_answer_templates_path
31
+ end
32
+
33
+ on(:invalid) do
34
+ flash.now[:alert] = I18n.t("templates.create.error", scope: "decidim.admin")
35
+ render :new
36
+ end
37
+ end
38
+ end
39
+
40
+ def destroy
41
+ enforce_permission_to(:destroy, :template, template:)
42
+
43
+ DestroyTemplate.call(template, current_user) do
44
+ on(:ok) do
45
+ flash[:notice] = I18n.t("templates.destroy.success", scope: "decidim.admin")
46
+ redirect_to action: :index
47
+ end
48
+ end
49
+ end
50
+
51
+ def fetch
52
+ enforce_permission_to(:read, :template, template:)
53
+
54
+ response_object = {
55
+ state: template.field_values["internal_state"],
56
+ template: populate_template_interpolations(proposal)
57
+ }
58
+
59
+ respond_to do |format|
60
+ format.json do
61
+ render json: response_object.to_json
62
+ end
63
+ end
64
+ end
65
+
66
+ def update
67
+ enforce_permission_to(:update, :template, template:)
68
+ @form = form(ProposalAnswerTemplateForm).from_params(params)
69
+ UpdateProposalAnswerTemplate.call(template, @form, current_user) do
70
+ on(:ok) do |_questionnaire_template|
71
+ flash[:notice] = I18n.t("templates.update.success", scope: "decidim.admin")
72
+ redirect_to proposal_answer_templates_path
73
+ end
74
+
75
+ on(:invalid) do |template|
76
+ @template = template
77
+ flash.now[:error] = I18n.t("templates.update.error", scope: "decidim.admin")
78
+ render action: :edit
79
+ end
80
+ end
81
+ end
82
+
83
+ def copy
84
+ enforce_permission_to :copy, :template
85
+
86
+ CopyProposalAnswerTemplate.call(template, current_user) do
87
+ on(:ok) do
88
+ flash[:notice] = I18n.t("templates.copy.success", scope: "decidim.admin")
89
+ redirect_to action: :index
90
+ end
91
+
92
+ on(:invalid) do
93
+ flash[:alert] = I18n.t("templates.copy.error", scope: "decidim.admin")
94
+ redirect_to action: :index
95
+ end
96
+ end
97
+ end
98
+
99
+ def index
100
+ enforce_permission_to :index, :templates
101
+ @templates = collection
102
+
103
+ respond_to do |format|
104
+ format.html { render :index }
105
+ format.json do
106
+ term = params[:term]
107
+
108
+ @templates = search(term)
109
+
110
+ render json: @templates.map { |t| { value: t.id, label: translated_attribute(t.name) } }
111
+ end
112
+ end
113
+ end
114
+
115
+ private
116
+
117
+ def populate_template_interpolations(proposal)
118
+ template.description.to_h do |language, value|
119
+ value.gsub!("%{organization}", proposal.organization.name)
120
+ value.gsub!("%{name}", author_name(proposal))
121
+ value.gsub!("%{admin}", current_user.name)
122
+
123
+ [language, value]
124
+ end
125
+ end
126
+
127
+ def author_name(proposal)
128
+ proposal.creator_author.try(:title) || proposal.creator_author.try(:name)
129
+ end
130
+
131
+ def proposal
132
+ @proposal ||= Decidim::Proposals::Proposal.find(params[:proposalId])
133
+ end
134
+
135
+ def availability_option_as_text(template)
136
+ return unless template.templatable_type
137
+ return t("global_scope", scope: "decidim.templates.admin.proposal_answer_templates.index") if template.templatable == current_organization
138
+
139
+ avaliablity_options.select { |a| a.last == template.templatable_id }&.flatten&.first || t("templates.missing_resource", scope: "decidim.admin")
140
+ end
141
+
142
+ def availability_options_for_select
143
+ avaliablity_options
144
+ end
145
+
146
+ def avaliablity_options
147
+ @avaliablity_options = []
148
+ @avaliablity_options.push [t("global_scope", scope: "decidim.templates.admin.proposal_answer_templates.index"), 0]
149
+
150
+ Decidim::Component.includes(:participatory_space).where(manifest_name: [:proposals])
151
+ .select { |a| a.participatory_space.decidim_organization_id == current_organization.id }.each do |component|
152
+ @avaliablity_options.push [formatted_name(component), component.id]
153
+ end
154
+
155
+ @avaliablity_options
156
+ end
157
+
158
+ def formatted_name(component)
159
+ space_type = t(component.participatory_space.class.name.underscore, scope: "activerecord.models", count: 1)
160
+ "#{space_type}: #{translated_attribute(component.participatory_space.title)} > #{translated_attribute(component.name)}"
161
+ end
162
+
163
+ def template
164
+ @template ||= Template.find_by(id: params[:id])
165
+ end
166
+
167
+ def collection
168
+ @collection ||= paginate(current_organization.templates.where(target: :proposal_answer).order(:id))
169
+ end
170
+ end
171
+ end
172
+ end
173
+ end
@@ -66,13 +66,13 @@ module Decidim
66
66
  end
67
67
 
68
68
  def edit
69
- enforce_permission_to :update, :template, template: template
69
+ enforce_permission_to(:update, :template, template:)
70
70
  @form = form(TemplateForm).from_model(template)
71
71
  @preview_form = form(Decidim::Forms::QuestionnaireForm).from_model(template.templatable)
72
72
  end
73
73
 
74
74
  def update
75
- enforce_permission_to :update, :template, template: template
75
+ enforce_permission_to(:update, :template, template:)
76
76
  @form = form(TemplateForm).from_params(params)
77
77
  UpdateTemplate.call(template, @form, current_user) do
78
78
  on(:ok) do |questionnaire_template|
@@ -89,9 +89,9 @@ module Decidim
89
89
  end
90
90
 
91
91
  def destroy
92
- enforce_permission_to :destroy, :template, template: template
92
+ enforce_permission_to(:destroy, :template, template:)
93
93
 
94
- DestroyTemplate.call(template, current_user) do
94
+ DestroyQuestionnaireTemplate.call(template, current_user) do
95
95
  on(:ok) do
96
96
  flash[:notice] = I18n.t("templates.destroy.success", scope: "decidim.admin")
97
97
  redirect_to action: :index
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Templates
5
+ module Admin
6
+ class ProposalAnswerTemplateForm < TemplateForm
7
+ attribute :internal_state, String
8
+ attribute :component_constraint, Integer
9
+
10
+ validates :internal_state, presence: true
11
+
12
+ def map_model(model)
13
+ self.internal_state = model.field_values["internal_state"]
14
+ self.component_constraint = if model.templatable_type == "Decidim::Organization"
15
+ 0
16
+ else
17
+ model.templatable&.id
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Templates
5
+ # Custom helpers, scoped to the templates engine.
6
+ #
7
+ module Admin
8
+ module ApplicationHelper
9
+ def block_user_templates
10
+ Decidim::Templates::Template.where(
11
+ target: :user_block,
12
+ templatable: [current_organization]
13
+ ).order(:templatable_id)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -19,18 +19,12 @@ module Decidim
19
19
 
20
20
  belongs_to :templatable, foreign_type: "templatable_type", polymorphic: true, optional: true
21
21
 
22
- before_destroy :destroy_templatable
23
-
24
22
  validates :name, presence: true
25
23
 
26
24
  def resource_name
27
25
  [templatable_type.demodulize.tableize.singularize, "templates"].join("_")
28
26
  end
29
27
 
30
- def destroy_templatable
31
- templatable.destroy
32
- end
33
-
34
28
  def self.log_presenter_class_for(_log)
35
29
  Decidim::Templates::AdminLog::TemplatePresenter
36
30
  end
@@ -0,0 +1,2 @@
1
+ import "src/decidim/templates/admin/block_user_template_chooser"
2
+ import "src/decidim/templates/admin/proposal_answer_template_chooser"
@@ -0,0 +1,20 @@
1
+ // Choose a Block User Message template, get it by AJAX and add the Template in the justification textarea
2
+ document.addEventListener("DOMContentLoaded", () => {
3
+ const blockTemplateChooser = document.getElementById("block_template_chooser");
4
+ if (blockTemplateChooser) {
5
+ blockTemplateChooser.addEventListener("change", () => {
6
+ const dropdown = document.getElementById("block_template_chooser");
7
+ const url = dropdown.getAttribute("data-url");
8
+ const templateId = dropdown.value;
9
+
10
+ if (templateId === "") {
11
+ return;
12
+ }
13
+ fetch(`${new URL(url).pathname}?${new URLSearchParams({ id: templateId })}`).
14
+ then((response) => response.json()).
15
+ then((data) => {
16
+ document.getElementById("block_user_justification").value = data.template;
17
+ })
18
+ });
19
+ }
20
+ });
@@ -0,0 +1,31 @@
1
+ // Choose a Proposal Answer template, get it by AJAX and add the Template in the Proposal Answer textarea
2
+ document.addEventListener("DOMContentLoaded", () => {
3
+ const proposalAnswerTemplateChooser = document.getElementById("proposal_answer_template_chooser");
4
+ if (proposalAnswerTemplateChooser) {
5
+
6
+ proposalAnswerTemplateChooser.addEventListener("change", () => {
7
+ const dropdown = document.getElementById("proposal_answer_template_chooser");
8
+ const url = dropdown.getAttribute("data-url");
9
+ const templateId = dropdown.value;
10
+ const proposalId = dropdown.dataset.proposal;
11
+
12
+ if (templateId === "") {
13
+ return;
14
+ }
15
+ fetch(`${new URL(url).pathname}?${new URLSearchParams({ id: templateId, proposalId: proposalId })}`).
16
+ then((response) => response.json()).
17
+ then((data) => {
18
+ document.getElementById(`proposal_answer_internal_state_${data.state}`).click();
19
+
20
+ let editorContainer = null;
21
+ for (const [key, value] of Object.entries(data.template)) {
22
+ editorContainer = document.querySelector(`[name="proposal_answer[answer_${key}]"]`).nextElementSibling;
23
+ let editor = editorContainer.querySelector(".ProseMirror").editor;
24
+
25
+ editor.commands.setContent(value, true);
26
+ }
27
+ })
28
+ });
29
+
30
+ }
31
+ });
@@ -1,14 +1,5 @@
1
- .questionnaire-template-preview{
2
- margin: 2rem;
3
- padding: 1rem;
4
-
5
- .card{
6
- width: 75%;
7
- margin: auto;
8
- border: none;
1
+ .questionnaire-template-preview {
2
+ .card {
3
+ @apply w-full m-auto border-0;
9
4
  }
10
5
  }
11
-
12
- .choose-template-preview{
13
- min-height: 10rem;
14
- }
@@ -6,8 +6,8 @@ module Decidim
6
6
  # This class holds the logic to present a `Decidim::Template`
7
7
  # for the `AdminLog` log.
8
8
  #
9
- # Usage should be automatic and you shouldn't need to call this class
10
- # directly, but here's an example:
9
+ # Usage should be automatic and you should not need to call this class
10
+ # directly, but here is an example:
11
11
  #
12
12
  # action_log = Decidim::ActionLog.last
13
13
  # view_helpers # => this comes from the views
@@ -0,0 +1,13 @@
1
+ <div class="form__wrapper">
2
+ <div class="card pt-4">
3
+ <div class="card-section">
4
+ <div class="row column">
5
+ <%= form.translated :text_field, :name, aria: { label: :name } %>
6
+ </div>
7
+
8
+ <div class="row column">
9
+ <%= form.translated :text_area, :description, rows: 3, aria: { label: :description } %>
10
+ </div>
11
+ </div>
12
+ </div>
13
+ </div>
@@ -0,0 +1,12 @@
1
+ <% if block_user_templates.any? %>
2
+ <div class="row column">
3
+ <%= append_javascript_pack_tag "decidim_templates_admin" %>
4
+
5
+ <select id="block_template_chooser" data-locale="en" data-url="<%= decidim_admin_templates.fetch_block_user_templates_url %>">
6
+ <option value=""><%= t(".select_template") %></option>
7
+ <% block_user_templates.each do |template| %>
8
+ <option value="<%= template.id %>"><%= translated_attribute(template.name) %></option>
9
+ <% end %>
10
+ </select>
11
+ </div>
12
+ <% end %>
@@ -0,0 +1,18 @@
1
+ <% add_decidim_page_title(t(".title")) %>
2
+ <div class="item_show__header">
3
+ <h2 class="item_show__header-title">
4
+ <%= t(".title") %>
5
+ </h2>
6
+ </div>
7
+ <div class="item__edit item__edit-1col">
8
+ <div class="item__edit-form">
9
+ <%= decidim_form_for(@form, url: block_user_template_path, html: { class: "form-defaults form edit_user_block_template" }) do |f| %>
10
+ <%= render partial: "form", object: f %>
11
+ <div class="item__edit-sticky">
12
+ <div class="item__edit-sticky-container">
13
+ <%= f.submit t("save", scope: "decidim.templates.admin.block_user_templates.form"), class: "button button__sm button__secondary" %>
14
+ </div>
15
+ </div>
16
+ <% end %>
17
+ </div>
18
+ </div>
@@ -0,0 +1,45 @@
1
+ <% add_decidim_page_title(t(".title")) %>
2
+ <div class="card">
3
+ <div class="item_show__header">
4
+ <h2 class="item_show__header-title">
5
+ <%= t ".title" %>
6
+ <% if allowed_to?(:create, :template) %>
7
+ <%= link_to t("actions.new_template", scope: "decidim.admin.templates"), [:new, :block_user_template], class: "button button__sm button__secondary new" %>
8
+ <% end %>
9
+ </h2>
10
+ </div>
11
+ <% if @templates.any? %>
12
+ <div class="table-scroll">
13
+ <table class="table-list user_block-templates">
14
+ <thead>
15
+ <tr>
16
+ <th><%= t("template.name", scope: "decidim.models") %></th>
17
+ <th><%= t("template.fields.created_at", scope: "decidim.models") %></th>
18
+ <th></th>
19
+ </tr>
20
+ </thead>
21
+ <tbody>
22
+ <% @templates.each do |template| %>
23
+ <tr data-questionnaire_template-id="<%= template.id %>">
24
+ <td><%= link_to translated_attribute(template.name), edit_block_user_template_path(template) %></td>
25
+ <td><%= l template.created_at, format: :long %></td>
26
+ <td class="table-list__actions">
27
+ <% if allowed_to?(:update, :template, questionnaire_template: template) %>
28
+ <%= icon_link_to "pencil-line", edit_block_user_template_path(template), t("actions.edit", scope: "decidim.admin"), class: "edit" %>
29
+ <% end %>
30
+ <% if allowed_to?(:copy, :template, questionnaire_template: template) %>
31
+ <%= icon_link_to "file-copy-line", copy_block_user_template_path(template), t("actions.duplicate", scope: "decidim.admin"), method: :post %>
32
+ <% end %>
33
+ <% if allowed_to?(:destroy, :template, questionnaire_template: template) %>
34
+ <%= icon_link_to "delete-bin-line", block_user_template_path(template), t("actions.destroy", scope: "decidim.admin"), method: :delete, data: { confirm: t(".confirm_delete") }, class: "action-icon--remove" %>
35
+ <% end %>
36
+ </td>
37
+ </tr>
38
+ <% end %>
39
+ </tbody>
40
+ </table>
41
+ </div>
42
+ <% else %>
43
+ <%= t("templates.empty", scope: "decidim.admin") %>
44
+ <% end %>
45
+ </div>
@@ -0,0 +1,18 @@
1
+ <% add_decidim_page_title(t(".title")) %>
2
+ <div class="item_show__header">
3
+ <h2 class="item_show__header-title">
4
+ <%= t(".title") %>
5
+ </h2>
6
+ </div>
7
+ <div class="item__edit item__edit-1col">
8
+ <div class="item__edit-form">
9
+ <%= decidim_form_for(@form, url: block_user_templates_path, html: { class: "form-defaults form new_user_block_template" }) do |f| %>
10
+ <%= render partial: "form", object: f %>
11
+ <div class="item__edit-sticky">
12
+ <div class="item__edit-sticky-container">
13
+ <%= f.submit t("save", scope: "decidim.templates.admin.block_user_templates.form"), class: "button button__sm button__secondary" %>
14
+ </div>
15
+ </div>
16
+ <% end %>
17
+ </div>
18
+ </div>
@@ -0,0 +1,38 @@
1
+ <div class="form__wrapper">
2
+ <div class="card pt-4">
3
+ <div class="card-section">
4
+ <div class="row column">
5
+ <%= form.translated :text_field, :name, aria: { label: :name } %>
6
+ </div>
7
+
8
+ <div class="row column">
9
+ <%= form.translated :editor, :description, rows: 3, aria: { label: :description } %>
10
+ <%= t(".hint_html") %>
11
+ <ul>
12
+ <li><%= t(".hint1_html") %></li>
13
+ <li><%= t(".hint2_html") %></li>
14
+ <li><%= t(".hint3_html") %></li>
15
+ </ul>
16
+ </div>
17
+
18
+ <div class="row column">
19
+ <%= form.label :internal_state %>
20
+ <div class="flex items-center gap-x-4 my-2">
21
+ <%= form.collection_radio_buttons :internal_state,
22
+ Decidim::Proposals::Proposal::STATES.keys - [:withdrawn],
23
+ :to_s,
24
+ ->(mode) { t(mode, scope: "decidim.proposals.admin.proposal_answers.form") },
25
+ prompt: true do |builder|
26
+ builder.label { builder.radio_button + builder.text }
27
+ end %>
28
+ </div>
29
+ </div>
30
+
31
+ <div class="row column">
32
+ <%= form.select :component_constraint, availability_options_for_select,
33
+ sselected: form.object.component_constraint,
34
+ help_text: t(".component_constraint_help") %>
35
+ </div>
36
+ </div>
37
+ </div>
38
+ </div>
@@ -0,0 +1,16 @@
1
+ <% templates = Decidim::Templates::Template.where(
2
+ target: :proposal_answer,
3
+ templatable: [current_organization, current_component]
4
+ ).order(:templatable_id) %>
5
+ <% if templates.any? %>
6
+ <div class="row column">
7
+ <%= append_javascript_pack_tag "decidim_templates_admin" %>
8
+
9
+ <select id="proposal_answer_template_chooser" data-locale="en" data-proposal="<%= proposal.id %>" data-url="<%= decidim_admin_templates.fetch_proposal_answer_templates_url %>">
10
+ <option value=""><%= t(".select_template") %></option>
11
+ <% templates.each do |template| %>
12
+ <option value="<%= template.id %>"><%= translated_attribute(template.name) %></option>
13
+ <% end %>
14
+ </select>
15
+ </div>
16
+ <% end %>
@@ -0,0 +1,18 @@
1
+ <% add_decidim_page_title(t(".title")) %>
2
+ <div class="item_show__header">
3
+ <h2 class="item_show__header-title">
4
+ <%= t(".title") %>
5
+ </h2>
6
+ </div>
7
+ <div class="item__edit item__edit-1col">
8
+ <div class="item__edit-form">
9
+ <%= decidim_form_for(@form, url: proposal_answer_template_path, html: { class: "form-defaults form edit_proposal_answer_template" }) do |f| %>
10
+ <%= render partial: "form", object: f %>
11
+ <div class="item__edit-sticky">
12
+ <div class="item__edit-sticky-container">
13
+ <%= f.submit t("save", scope: "decidim.templates.admin.proposal_answer_templates.form"), class: "button button__sm button__secondary" %>
14
+ </div>
15
+ </div>
16
+ <% end %>
17
+ </div>
18
+ </div>
@@ -0,0 +1,51 @@
1
+ <% add_decidim_page_title(t(".title")) %>
2
+
3
+ <div class="card">
4
+ <div class="item_show__header">
5
+ <h2 class="item_show__header-title">
6
+ <%= t ".title" %>
7
+ <% if allowed_to?(:create, :template) %>
8
+ <%= link_to t("actions.new_template", scope: "decidim.admin.templates"), [:new, :proposal_answer_template], class: "button button__sm button__secondary new" %>
9
+ <% end %>
10
+ </h2>
11
+ </div>
12
+ <% if @templates.any? %>
13
+ <div class="table-scroll">
14
+ <table class="table-list">
15
+ <thead>
16
+ <tr>
17
+ <th><%= t("template.name", scope: "decidim.models") %></th>
18
+ <th><%= t(".internal_state") %></th>
19
+ <th><%= t(".component_constraint") %></th>
20
+ <th><%= t("template.fields.created_at", scope: "decidim.models") %></th>
21
+ <th></th>
22
+ </tr>
23
+ </thead>
24
+ <tbody>
25
+ <% @templates.each do |template| %>
26
+ <tr data-proposal_answer-id="<%= template.id %>">
27
+ <td><%= link_to_if allowed_to?(:update, :template, template:) , translated_attribute(template.name), edit_proposal_answer_template_path(template) %></td>
28
+ <td> <%= t(template.field_values.dig("internal_state"), scope: "decidim.proposals.admin.proposal_answers.form") %></td>
29
+ <td><%= availability_option_as_text(template) %></td>
30
+ <td><%= l template.created_at, format: :long %></td>
31
+
32
+ <td class="table-list__actions">
33
+ <% if allowed_to?(:update, :template, template:) %>
34
+ <%= icon_link_to "pencil-line", edit_proposal_answer_template_path(template), t("actions.edit", scope: "decidim.admin"), class: "edit" %>
35
+ <% end %>
36
+ <% if allowed_to?(:copy, :template, template:) %>
37
+ <%= icon_link_to "file-copy-line", copy_proposal_answer_template_path(template), t("actions.duplicate", scope: "decidim.admin"), method: :post %>
38
+ <% end %>
39
+ <% if allowed_to?(:destroy, :template, template:) %>
40
+ <%= icon_link_to "delete-bin-line", proposal_answer_template_path(template), t("actions.destroy", scope: "decidim.admin"), method: :delete, data: { confirm: t(".confirm_delete") }, class: "action-icon--remove" %>
41
+ <% end %>
42
+ </td>
43
+ </tr>
44
+ <% end %>
45
+ </tbody>
46
+ </table>
47
+ </div>
48
+ <% else %>
49
+ <%= t("templates.empty", scope: "decidim.admin") %>
50
+ <% end %>
51
+ </div>
@@ -0,0 +1,18 @@
1
+ <% add_decidim_page_title(t(".title")) %>
2
+ <div class="item_show__header">
3
+ <h2 class="item_show__header-title">
4
+ <%= t(".title") %>
5
+ </h2>
6
+ </div>
7
+ <div class="item__edit item__edit-1col">
8
+ <div class="item__edit-form">
9
+ <%= decidim_form_for(@form, url: proposal_answer_templates_path, html: { class: "form-defaults form new_proposal_answer_template" }) do |f| %>
10
+ <%= render partial: "form", object: f %>
11
+ <div class="item__edit-sticky">
12
+ <div class="item__edit-sticky-container">
13
+ <%= f.submit t("save", scope: "decidim.templates.admin.proposal_answer_templates.form"), class: "button button__sm button__secondary" %>
14
+ </div>
15
+ </div>
16
+ <% end %>
17
+ </div>
18
+ </div>