decidim-templates 0.23.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of decidim-templates might be problematic. Click here for more details.

Files changed (93) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE-AGPLv3.txt +661 -0
  3. data/README.md +31 -0
  4. data/Rakefile +9 -0
  5. data/app/assets/config/decidim_templates_manifest.css +3 -0
  6. data/app/assets/config/decidim_templates_manifest.js +0 -0
  7. data/app/assets/images/decidim/templates/icon.svg +1 -0
  8. data/app/assets/stylesheets/decidim/templates/templates.scss +14 -0
  9. data/app/commands/decidim/templates/admin/apply_questionnaire_template.rb +74 -0
  10. data/app/commands/decidim/templates/admin/copy_questionnaire_template.rb +79 -0
  11. data/app/commands/decidim/templates/admin/create_questionnaire_template.rb +34 -0
  12. data/app/commands/decidim/templates/admin/destroy_template.rb +41 -0
  13. data/app/commands/decidim/templates/admin/update_template.rb +35 -0
  14. data/app/controllers/decidim/templates/admin/application_controller.rb +34 -0
  15. data/app/controllers/decidim/templates/admin/concerns/templatable.rb +46 -0
  16. data/app/controllers/decidim/templates/admin/questionnaire_templates/questionnaires_controller.rb +38 -0
  17. data/app/controllers/decidim/templates/admin/questionnaire_templates_controller.rb +156 -0
  18. data/app/controllers/decidim/templates/application_controller.rb +13 -0
  19. data/app/forms/decidim/templates/admin/template_form.rb +17 -0
  20. data/app/helpers/decidim/templates/admin/templates_helper.rb +32 -0
  21. data/app/helpers/decidim/templates/application_helper.rb +10 -0
  22. data/app/models/concerns/decidim/templates/templatable.rb +24 -0
  23. data/app/models/decidim/templates/application_record.rb +10 -0
  24. data/app/models/decidim/templates/template.rb +33 -0
  25. data/app/permissions/decidim/templates/admin/permissions.rb +26 -0
  26. data/app/views/decidim/templates/admin/questionnaire_templates/_choose.html.erb +35 -0
  27. data/app/views/decidim/templates/admin/questionnaire_templates/_form.html.erb +16 -0
  28. data/app/views/decidim/templates/admin/questionnaire_templates/_preview.html.erb +73 -0
  29. data/app/views/decidim/templates/admin/questionnaire_templates/edit.html.erb +20 -0
  30. data/app/views/decidim/templates/admin/questionnaire_templates/index.html.erb +52 -0
  31. data/app/views/decidim/templates/admin/questionnaire_templates/new.html.erb +7 -0
  32. data/app/views/decidim/templates/admin/questionnaire_templates/preview.js.erb +11 -0
  33. data/app/views/layouts/decidim/admin/templates.html.erb +21 -0
  34. data/config/locales/am-ET.yml +1 -0
  35. data/config/locales/ar.yml +1 -0
  36. data/config/locales/bg.yml +1 -0
  37. data/config/locales/ca.yml +60 -0
  38. data/config/locales/cs.yml +60 -0
  39. data/config/locales/da.yml +1 -0
  40. data/config/locales/de.yml +54 -0
  41. data/config/locales/el.yml +1 -0
  42. data/config/locales/en.yml +61 -0
  43. data/config/locales/eo.yml +1 -0
  44. data/config/locales/es-MX.yml +60 -0
  45. data/config/locales/es-PY.yml +60 -0
  46. data/config/locales/es.yml +60 -0
  47. data/config/locales/et.yml +1 -0
  48. data/config/locales/eu.yml +1 -0
  49. data/config/locales/fi-plain.yml +60 -0
  50. data/config/locales/fi.yml +60 -0
  51. data/config/locales/fr-CA.yml +60 -0
  52. data/config/locales/fr.yml +60 -0
  53. data/config/locales/ga-IE.yml +1 -0
  54. data/config/locales/gl.yml +1 -0
  55. data/config/locales/hr.yml +1 -0
  56. data/config/locales/hu.yml +1 -0
  57. data/config/locales/id-ID.yml +1 -0
  58. data/config/locales/is-IS.yml +1 -0
  59. data/config/locales/it.yml +60 -0
  60. data/config/locales/ja.yml +60 -0
  61. data/config/locales/ko-KR.yml +1 -0
  62. data/config/locales/ko.yml +1 -0
  63. data/config/locales/lt.yml +1 -0
  64. data/config/locales/lv.yml +1 -0
  65. data/config/locales/mt.yml +1 -0
  66. data/config/locales/nl.yml +60 -0
  67. data/config/locales/no.yml +5 -0
  68. data/config/locales/om-ET.yml +1 -0
  69. data/config/locales/pl.yml +1 -0
  70. data/config/locales/pt-BR.yml +1 -0
  71. data/config/locales/pt.yml +1 -0
  72. data/config/locales/ro-RO.yml +1 -0
  73. data/config/locales/ru.yml +1 -0
  74. data/config/locales/sk.yml +1 -0
  75. data/config/locales/sl.yml +1 -0
  76. data/config/locales/so-SO.yml +1 -0
  77. data/config/locales/sr-CS.yml +1 -0
  78. data/config/locales/sv.yml +1 -0
  79. data/config/locales/ti-ER.yml +1 -0
  80. data/config/locales/tr-TR.yml +1 -0
  81. data/config/locales/uk.yml +1 -0
  82. data/config/locales/vi-VN.yml +1 -0
  83. data/config/locales/vi.yml +1 -0
  84. data/config/locales/zh-CN.yml +60 -0
  85. data/config/locales/zh-TW.yml +1 -0
  86. data/lib/decidim/templates.rb +12 -0
  87. data/lib/decidim/templates/admin.rb +10 -0
  88. data/lib/decidim/templates/admin_engine.rb +54 -0
  89. data/lib/decidim/templates/engine.rb +23 -0
  90. data/lib/decidim/templates/test/factories.rb +27 -0
  91. data/lib/decidim/templates/test/shared_examples/uses_questionnaire_templates.rb +108 -0
  92. data/lib/decidim/templates/version.rb +10 -0
  93. metadata +191 -0
@@ -0,0 +1,31 @@
1
+ # Decidim::Templates
2
+
3
+ This module provides a solution to create templates for different Decidim models, such as Proposals and Questionnaires.
4
+
5
+ ## Usage
6
+
7
+ Templates will be available in their own section in the admin
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'decidim-templates'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ ```bash
20
+ bundle
21
+ bundle exec rails decidim_templates:install:migrations
22
+ bundle exec rails db:migrate
23
+ ```
24
+
25
+ ## Contributing
26
+
27
+ See [Decidim](https://github.com/decidim/decidim).
28
+
29
+ ## License
30
+
31
+ This engine is distributed under the GNU AFFERO GENERAL PUBLIC LICENSE.
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "decidim/dev/common_rake"
4
+
5
+ desc "Generates a dummy app for testing"
6
+ task test_app: "decidim:generate_external_test_app"
7
+
8
+ desc "Generates a development app."
9
+ task development_app: "decidim:generate_external_development_app"
@@ -0,0 +1,3 @@
1
+ /*
2
+ *= link decidim/templates/templates.scss
3
+ */
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 35 35"><path d="M17.5 35A17.5 17.5 0 1 1 35 17.5 17.52 17.52 0 0 1 17.5 35zm0-33.06A15.56 15.56 0 1 0 33.06 17.5 15.57 15.57 0 0 0 17.5 1.94zm9.5 13.7H8a1 1 0 0 1 0-1.94h19a1 1 0 0 1 0 1.94zm0 3.68H8a1 1 0 0 1 0-1.94h19a1 1 0 0 1 0 1.94zM22.26 23H8a1 1 0 0 1 0-1.94h14.26a1 1 0 0 1 0 1.94z"/></svg>
@@ -0,0 +1,14 @@
1
+ .questionnaire-template-preview{
2
+ margin: 2rem;
3
+ padding: 1rem;
4
+
5
+ .card{
6
+ width: 75%;
7
+ margin: auto;
8
+ border: none;
9
+ }
10
+ }
11
+
12
+ .choose-template-preview{
13
+ min-height: 10rem;
14
+ }
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Templates
5
+ # A command with all the business logic when duplicating a questionnaire template
6
+ module Admin
7
+ class ApplyQuestionnaireTemplate < Rectify::Command
8
+ # Public: Initializes the command.
9
+ #
10
+ # template - The template we want to apply
11
+ # questionnaire - The questionnaire we want to use the template
12
+ def initialize(questionnaire, template)
13
+ @questionnaire = questionnaire
14
+ @template = template
15
+ end
16
+
17
+ # Executes the command. Broadcasts these events:
18
+ #
19
+ # - :ok when everything is valid.
20
+ # - :invalid if the form wasn't valid and we couldn't proceed.
21
+ #
22
+ # Returns nothing.
23
+ def call
24
+ return broadcast(:invalid) unless @template.valid?
25
+
26
+ Template.transaction do
27
+ apply_template
28
+ copy_questionnaire_questions(@template.templatable, @questionnaire)
29
+ end
30
+
31
+ broadcast(:ok, @questionnaire)
32
+ end
33
+
34
+ private
35
+
36
+ attr_reader :form
37
+
38
+ def apply_template
39
+ @questionnaire.update!(
40
+ title: @template.templatable.title,
41
+ description: @template.templatable.description,
42
+ tos: @template.templatable.tos
43
+ )
44
+ end
45
+
46
+ def copy_questionnaire_questions(original_questionnaire, new_questionnaire)
47
+ original_questionnaire.questions.each do |original_question|
48
+ new_question = original_question.dup
49
+ new_question.questionnaire = new_questionnaire
50
+ new_question.save!
51
+ copy_questionnaire_answer_options(original_question, new_question)
52
+ copy_questionnaire_matrix_rows(original_question, new_question)
53
+ end
54
+ end
55
+
56
+ def copy_questionnaire_answer_options(original_question, new_question)
57
+ original_question.answer_options.each do |original_answer_option|
58
+ new_answer_option = original_answer_option.dup
59
+ new_answer_option.question = new_question
60
+ new_answer_option.save!
61
+ end
62
+ end
63
+
64
+ def copy_questionnaire_matrix_rows(original_question, new_question)
65
+ original_question.matrix_rows.each do |original_matrix_row|
66
+ new_matrix_row = original_matrix_row.dup
67
+ new_matrix_row.question = new_question
68
+ new_matrix_row.save!
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Templates
5
+ # A command with all the business logic when duplicating a questionnaire template
6
+ module Admin
7
+ class CopyQuestionnaireTemplate < Rectify::Command
8
+ # Public: Initializes the command.
9
+ #
10
+ # template - A template we want to duplicate
11
+ def initialize(template)
12
+ @template = template
13
+ end
14
+
15
+ # Executes the command. Broadcasts these events:
16
+ #
17
+ # - :ok when everything is valid.
18
+ # - :invalid if the form wasn't valid and we couldn't proceed.
19
+ #
20
+ # Returns nothing.
21
+ def call
22
+ return broadcast(:invalid) unless @template.valid?
23
+
24
+ Template.transaction do
25
+ copy_template
26
+ copy_questionnaire_questions(@template.templatable, @copied_template.templatable)
27
+ end
28
+
29
+ broadcast(:ok, @copied_template)
30
+ end
31
+
32
+ private
33
+
34
+ attr_reader :form
35
+
36
+ def copy_template
37
+ @copied_template = Template.create!(
38
+ organization: @template.organization,
39
+ name: @template.name,
40
+ description: @template.description
41
+ )
42
+ @resource = Decidim::Forms::Questionnaire.create!(
43
+ @template.templatable.dup.attributes.merge(
44
+ questionnaire_for: @copied_template
45
+ )
46
+ )
47
+
48
+ @copied_template.update!(templatable: @resource)
49
+ end
50
+
51
+ def copy_questionnaire_questions(original_questionnaire, new_questionnaire)
52
+ original_questionnaire.questions.each do |original_question|
53
+ new_question = original_question.dup
54
+ new_question.questionnaire = new_questionnaire
55
+ new_question.save!
56
+ copy_questionnaire_answer_options(original_question, new_question)
57
+ copy_questionnaire_matrix_rows(original_question, new_question)
58
+ end
59
+ end
60
+
61
+ def copy_questionnaire_answer_options(original_question, new_question)
62
+ original_question.answer_options.each do |original_answer_option|
63
+ new_answer_option = original_answer_option.dup
64
+ new_answer_option.question = new_question
65
+ new_answer_option.save!
66
+ end
67
+ end
68
+
69
+ def copy_questionnaire_matrix_rows(original_question, new_question)
70
+ original_question.matrix_rows.each do |original_matrix_row|
71
+ new_matrix_row = original_matrix_row.dup
72
+ new_matrix_row.question = new_question
73
+ new_matrix_row.save!
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Templates
5
+ module Admin
6
+ # Creates a QuestionnaireTemplate.
7
+ class CreateQuestionnaireTemplate < Rectify::Command
8
+ # Initializes the command.
9
+ #
10
+ # form - The source for this QuestionnaireTemplate.
11
+ def initialize(form)
12
+ @form = form
13
+ end
14
+
15
+ def call
16
+ return broadcast(:invalid) unless @form.valid?
17
+
18
+ @template = Decidim.traceability.create!(
19
+ Template,
20
+ @form.current_user,
21
+ name: @form.name,
22
+ description: @form.description,
23
+ organization: @form.current_organization
24
+ )
25
+
26
+ @questionnaire = Decidim::Forms::Questionnaire.create!(questionnaire_for: @template)
27
+ @template.update!(templatable: @questionnaire)
28
+
29
+ broadcast(:ok, @template)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Templates
5
+ module Admin
6
+ # This command deals with destroying a template from the admin panel.
7
+ class DestroyTemplate < Rectify::Command
8
+ # Public: Initializes the command.
9
+ #
10
+ # template - The Template to be destroyed.
11
+ # user - The user that destroys the template.
12
+ def initialize(template, current_user)
13
+ @template = template
14
+ @current_user = current_user
15
+ end
16
+
17
+ # Public: Executes the command.
18
+ #
19
+ # Broadcasts :ok if it got destroyed
20
+ def call
21
+ destroy_template
22
+ broadcast(:ok)
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :template, :current_user
28
+
29
+ def destroy_template
30
+ Decidim.traceability.perform_action!(
31
+ :delete,
32
+ template,
33
+ current_user
34
+ ) do
35
+ template.destroy!
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Templates
5
+ module Admin
6
+ # Updates the questionnaire template given form data.
7
+ class UpdateTemplate < Rectify::Command
8
+ # Initializes the command.
9
+ #
10
+ # template - The Template to update.
11
+ # form - The form object containing the data to update.
12
+ # user - The user that updates the template.
13
+ def initialize(template, form, user)
14
+ @template = template
15
+ @form = form
16
+ @user = user
17
+ end
18
+
19
+ def call
20
+ return broadcast(:invalid) unless @form.valid?
21
+ return broadcast(:invalid) unless @user.organization == @template.organization
22
+
23
+ @template = Decidim.traceability.update!(
24
+ @template,
25
+ @user,
26
+ name: @form.name,
27
+ description: @form.description
28
+ )
29
+
30
+ broadcast(:ok, @template)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Templates
5
+ module Admin
6
+ # This controller is the abstract class from which all other controllers of
7
+ # this engine inherit.
8
+ #
9
+ # Note that it inherits from `Decidim::Admin::ApplicationController`, which
10
+ # override its layout and provide all kinds of useful methods.
11
+ #
12
+ # i18n-tasks-use t('decidim.admin.titles.template_types.questionnaires')
13
+ class ApplicationController < Decidim::Admin::ApplicationController
14
+ layout "decidim/admin/templates"
15
+
16
+ helper_method :template_types
17
+
18
+ register_permissions(::Decidim::Templates::Admin::ApplicationController,
19
+ ::Decidim::Templates::Admin::Permissions,
20
+ ::Decidim::Admin::Permissions)
21
+
22
+ def permission_class_chain
23
+ ::Decidim.permissions_registry.chain_for(::Decidim::Templates::Admin::ApplicationController)
24
+ end
25
+
26
+ def template_types
27
+ @template_types ||= {
28
+ I18n.t("template_types.questionnaires", scope: "decidim.templates") => decidim_admin_templates.questionnaire_templates_path
29
+ }
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+
5
+ module Decidim
6
+ module Templates
7
+ module Admin
8
+ module Concerns
9
+ module Templatable
10
+ # Common logic to load template-related resources in controller
11
+ extend ActiveSupport::Concern
12
+
13
+ included do
14
+ helper_method :templates, :choose_template?
15
+
16
+ def templates
17
+ @templates = current_organization.templates.where(templatable_type: templatable_type)
18
+ @templates = @templates.where.not(id: params[:id]) if templates_path?
19
+ @templates
20
+ end
21
+
22
+ def templates_path?
23
+ controller_path.match?("^decidim/templates/.*")
24
+ end
25
+
26
+ def choose_template?
27
+ return false if templatable.is_a? Decidim::Templates::Template
28
+
29
+ templates.any? && templatable.pristine?
30
+ end
31
+
32
+ protected
33
+
34
+ def templatable
35
+ raise NotImplementedError, "Please set the templatable resource in your controller"
36
+ end
37
+
38
+ def templatable_type
39
+ raise NotImplementedError, "The templatable type is needed to load resources"
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Templates
5
+ module Admin
6
+ module QuestionnaireTemplates
7
+ # This controller allows an admin to manage a questionnaire form for a questionnaire_template
8
+ class QuestionnairesController < Admin::ApplicationController
9
+ include Decidim::Forms::Admin::Concerns::HasQuestionnaire
10
+
11
+ helper Decidim::Admin::ExportsHelper
12
+
13
+ def questionnaire_for
14
+ template
15
+ end
16
+
17
+ def update_url
18
+ questionnaire_path(template)
19
+ end
20
+
21
+ def after_update_url
22
+ edit_questionnaire_template_path(id: template.id)
23
+ end
24
+
25
+ def public_url
26
+ nil
27
+ end
28
+
29
+ private
30
+
31
+ def template
32
+ @template ||= Template.find(params[:id])
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end