decidim-templates 0.27.10 → 0.28.0.rc4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 -24
  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 +8 -20
  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 +49 -61
  87. data/config/locales/he-IL.yml +0 -1
  88. data/decidim-templates.gemspec +0 -34
@@ -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>