decidim-core 0.0.1.alpha9 → 0.0.1

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 (143) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +0 -25
  3. data/app/assets/config/decidim_core_manifest.js +1 -0
  4. data/app/assets/fonts/decidim/Source_Sans_Pro_400.eot +0 -0
  5. data/app/assets/fonts/decidim/Source_Sans_Pro_400.svg +345 -0
  6. data/app/assets/fonts/decidim/Source_Sans_Pro_400.ttf +0 -0
  7. data/app/assets/fonts/decidim/Source_Sans_Pro_400.woff +0 -0
  8. data/app/assets/fonts/decidim/Source_Sans_Pro_400.woff2 +0 -0
  9. data/app/assets/fonts/decidim/Source_Sans_Pro_600.eot +0 -0
  10. data/app/assets/fonts/decidim/Source_Sans_Pro_600.svg +339 -0
  11. data/app/assets/fonts/decidim/Source_Sans_Pro_600.ttf +0 -0
  12. data/app/assets/fonts/decidim/Source_Sans_Pro_600.woff +0 -0
  13. data/app/assets/fonts/decidim/Source_Sans_Pro_600.woff2 +0 -0
  14. data/app/assets/fonts/decidim/Source_Sans_Pro_900.eot +0 -0
  15. data/app/assets/fonts/decidim/Source_Sans_Pro_900.svg +342 -0
  16. data/app/assets/fonts/decidim/Source_Sans_Pro_900.ttf +0 -0
  17. data/app/assets/fonts/decidim/Source_Sans_Pro_900.woff +0 -0
  18. data/app/assets/fonts/decidim/Source_Sans_Pro_900.woff2 +0 -0
  19. data/app/assets/images/decidim/default-avatar.svg +14 -0
  20. data/app/assets/javascripts/decidim.js.es6 +5 -5
  21. data/app/assets/javascripts/decidim/editor.js.es6 +46 -0
  22. data/app/assets/stylesheets/decidim/_variables.scss +12 -13
  23. data/app/assets/stylesheets/decidim/application.sass +4 -1
  24. data/app/assets/stylesheets/decidim/editor.sass +4 -0
  25. data/app/assets/stylesheets/decidim/modules/_card-grid.scss +4 -1
  26. data/app/assets/stylesheets/decidim/modules/_cards.scss +5 -0
  27. data/app/assets/stylesheets/decidim/modules/_navbar.scss +1 -0
  28. data/app/assets/stylesheets/decidim/modules/_process-header.scss +24 -75
  29. data/app/assets/stylesheets/decidim/modules/_process-nav.scss +0 -1
  30. data/app/assets/stylesheets/decidim/modules/_process-phase.scss +80 -0
  31. data/app/assets/stylesheets/decidim/utils/_fontface.scss +39 -1
  32. data/app/assets/stylesheets/decidim/utils/_helpers.scss +25 -0
  33. data/app/assets/stylesheets/decidim/utils/_keyframes.scss +21 -0
  34. data/app/assets/stylesheets/decidim/utils/_mixins.scss +37 -0
  35. data/app/assets/stylesheets/decidim/utils/_settings.scss +11 -5
  36. data/app/commands/decidim/authorize_user.rb +2 -2
  37. data/app/constraints/decidim/current_feature.rb +48 -0
  38. data/app/controllers/concerns/decidim/form_factory.rb +80 -0
  39. data/app/controllers/concerns/decidim/locale_switcher.rb +17 -10
  40. data/app/controllers/concerns/decidim/needs_participatory_process.rb +33 -0
  41. data/app/controllers/decidim/application_controller.rb +1 -1
  42. data/app/controllers/decidim/devise/confirmations_controller.rb +1 -1
  43. data/app/controllers/decidim/devise/passwords_controller.rb +1 -1
  44. data/app/controllers/decidim/devise/registrations_controller.rb +1 -1
  45. data/app/controllers/decidim/devise/sessions_controller.rb +16 -2
  46. data/app/controllers/decidim/pages_controller.rb +14 -0
  47. data/app/controllers/decidim/participatory_processes_controller.rb +7 -0
  48. data/app/forms/decidim/form.rb +15 -0
  49. data/app/forms/translatable_presence_validator.rb +31 -0
  50. data/app/helpers/decidim/application_helper.rb +17 -2
  51. data/app/helpers/decidim/layout_helper.rb +8 -1
  52. data/app/helpers/decidim/localized_locales_helper.rb +43 -0
  53. data/app/helpers/decidim/participatory_process_helper.rb +16 -0
  54. data/app/helpers/decidim/translations_helper.rb +17 -0
  55. data/app/models/decidim/category.rb +35 -0
  56. data/app/models/decidim/component.rb +51 -0
  57. data/app/models/decidim/feature.rb +30 -0
  58. data/app/models/decidim/organization.rb +20 -1
  59. data/app/models/decidim/participatory_process.rb +43 -4
  60. data/app/models/decidim/participatory_process_attachment.rb +56 -0
  61. data/app/models/decidim/scope.rb +14 -0
  62. data/app/models/decidim/static_page.rb +56 -0
  63. data/app/models/decidim/user.rb +2 -0
  64. data/app/queries/decidim/organization_participatory_processes.rb +17 -0
  65. data/app/services/decidim/authorization_handler.rb +2 -2
  66. data/app/types/decidim/process_step_type.rb +24 -0
  67. data/app/types/decidim/process_type.rb +16 -0
  68. data/app/types/decidim/user_type.rb +14 -0
  69. data/app/uploaders/decidim/attachment_uploader.rb +70 -0
  70. data/app/uploaders/decidim/avatar_uploader.rb +14 -0
  71. data/app/uploaders/decidim/banner_image_uploader.rb +1 -1
  72. data/app/uploaders/decidim/hero_image_uploader.rb +1 -1
  73. data/app/uploaders/decidim/homepage_image_uploader.rb +11 -0
  74. data/app/uploaders/decidim/image_uploader.rb +46 -0
  75. data/app/uploaders/decidim/organization_logo_uploader.rb +9 -0
  76. data/app/views/decidim/devise/registrations/new.html.erb +1 -1
  77. data/app/views/decidim/participatory_processes/_documents.html.erb +26 -0
  78. data/app/views/decidim/participatory_processes/_photos.html.erb +16 -0
  79. data/app/views/decidim/participatory_processes/_promoted_process.html.erb +1 -1
  80. data/app/views/decidim/participatory_processes/show.html.erb +16 -11
  81. data/app/views/kaminari/decidim/_first_page.html.erb +11 -0
  82. data/app/views/kaminari/decidim/_gap.html.erb +8 -0
  83. data/app/views/kaminari/decidim/_last_page.html.erb +11 -0
  84. data/app/views/kaminari/decidim/_next_page.html.erb +11 -0
  85. data/app/views/kaminari/decidim/_page.html.erb +12 -0
  86. data/app/views/kaminari/decidim/_paginator.html.erb +25 -0
  87. data/app/views/kaminari/decidim/_prev_page.html.erb +11 -0
  88. data/app/views/layouts/decidim/_application.html.erb +17 -0
  89. data/app/views/layouts/decidim/_footer.html.erb +5 -3
  90. data/app/views/layouts/decidim/_header.html.erb +8 -21
  91. data/app/views/layouts/decidim/_language_chooser.html.erb +14 -0
  92. data/app/views/layouts/decidim/_logo.html.erb +17 -13
  93. data/app/views/layouts/decidim/_process_header.html.erb +34 -0
  94. data/app/views/layouts/decidim/_process_header_steps.html.erb +26 -0
  95. data/app/views/layouts/decidim/_user_menu.html.erb +2 -0
  96. data/app/views/layouts/decidim/application.html.erb +3 -0
  97. data/app/views/layouts/decidim/participatory_process.html.erb +15 -0
  98. data/app/views/pages/decidim_page.html.erb +12 -0
  99. data/app/views/pages/home.html.erb +106 -2
  100. data/config/i18n-tasks.yml +3 -1
  101. data/config/locales/ca.yml +40 -10
  102. data/config/locales/en.yml +39 -4
  103. data/config/locales/es.yml +44 -14
  104. data/config/routes.rb +14 -1
  105. data/db/migrate/20160919104837_create_decidim_organizations.rb +4 -0
  106. data/db/migrate/20161005153007_add_description_to_organizations.rb +1 -3
  107. data/db/migrate/20161010102356_translate_processes.rb +4 -4
  108. data/db/migrate/20161017085822_add_participatory_process_steps.rb +3 -3
  109. data/db/migrate/20161107152228_remove_not_null_on_step_position.rb +5 -0
  110. data/db/migrate/20161108093802_create_decidim_static_pages.rb +11 -0
  111. data/db/migrate/20161110092735_add_index_for_process_slug_organization.rb +8 -0
  112. data/db/migrate/20161110105712_create_decidim_features.rb +9 -0
  113. data/db/migrate/20161116115156_create_attachments.rb +18 -0
  114. data/db/migrate/20161123085134_add_categories.rb +10 -0
  115. data/db/migrate/20161130105257_create_decidim_scopes.rb +9 -0
  116. data/db/migrate/20161209134715_make_organization_description_optional.rb +5 -0
  117. data/db/migrate/20161213094244_add_avatar_to_users.rb +5 -0
  118. data/db/migrate/20161214152811_add_logo_to_organizations.rb +5 -0
  119. data/db/seeds.rb +36 -6
  120. data/db/seeds/Exampledocument.pdf +0 -0
  121. data/{app/assets/images/decidim/hero-home.jpg → db/seeds/homepage_image.jpg} +0 -0
  122. data/lib/decidim/core.rb +55 -2
  123. data/lib/decidim/core/engine.rb +16 -2
  124. data/lib/decidim/core/version.rb +11 -2
  125. data/lib/decidim/feature_manifest.rb +71 -0
  126. data/lib/decidim/features.rb +8 -0
  127. data/lib/decidim/features/base_controller.rb +32 -0
  128. data/lib/decidim/features/namer.rb +35 -0
  129. data/lib/decidim/form_builder.rb +140 -6
  130. data/lib/decidim/page_finder.rb +48 -0
  131. data/lib/decidim/query_extensions.rb +33 -0
  132. data/lib/decidim/translatable_attributes.rb +1 -24
  133. data/vendor/assets/javascripts/quill.min.js +14 -0
  134. data/vendor/assets/javascripts/quill.min.js.map +1 -0
  135. data/vendor/assets/stylesheets/quill.bubble.css +843 -0
  136. data/vendor/assets/stylesheets/quill.core.css +362 -0
  137. data/vendor/assets/stylesheets/quill.snow.css +881 -0
  138. metadata +164 -32
  139. data/LICENSE.txt +0 -619
  140. data/app/views/decidim/participatory_processes/_process_header_home.html.erb +0 -18
  141. data/app/views/pages/terms.ca.html.erb +0 -4
  142. data/app/views/pages/terms.en.html.erb +0 -4
  143. data/app/views/pages/terms.es.html.erb +0 -4
@@ -9,11 +9,10 @@ require "devise"
9
9
  require "devise-i18n"
10
10
  require "devise_invitable"
11
11
  require "jquery-rails"
12
- require "sass-rails"
12
+ require "sassc-rails"
13
13
  require "turbolinks"
14
14
  require "foundation-rails"
15
15
  require "foundation_rails_helper"
16
- require "jbuilder"
17
16
  require "active_link_to"
18
17
  require "rectify"
19
18
  require "roadie-rails"
@@ -23,6 +22,12 @@ require "rails-i18n"
23
22
  require "date_validator"
24
23
  require "sprockets/es6"
25
24
  require "cancancan"
25
+ require "truncato"
26
+ require "file_validators"
27
+
28
+ require "decidim/api"
29
+
30
+ require "decidim/query_extensions"
26
31
 
27
32
  module Decidim
28
33
  module Core
@@ -64,6 +69,15 @@ module Decidim
64
69
  config.abilities << Abilities::Everyone
65
70
  end
66
71
  end
72
+
73
+ initializer "decidim.locales" do |app|
74
+ app.config.i18n.available_locales = Decidim.config.available_locales
75
+ app.config.i18n.fallbacks = true
76
+ end
77
+
78
+ initializer "decidim.query_extensions" do
79
+ QueryExtensions.extend!(Decidim::Api::QueryType)
80
+ end
67
81
  end
68
82
  end
69
83
  end
@@ -2,10 +2,19 @@
2
2
  # This holds Decidim's version and the Rails version on which it depends.
3
3
  module Decidim
4
4
  def self.version
5
- "0.0.1.alpha9"
5
+ "0.0.1"
6
6
  end
7
7
 
8
8
  def self.rails_version
9
- "~> 5.0.0"
9
+ ["~> 5.0.0", ">= 5.0.0.1"]
10
+ end
11
+
12
+ def self.add_default_gemspec_properties(spec)
13
+ spec.version = Decidim.version
14
+ spec.authors = ["Josep Jaume Rey Peroy", "Marc Riera Casals", "Oriol Gual Oliva"]
15
+ spec.email = ["josepjaume@gmail.com", "mrc2407@gmail.com", "oriolgual@gmail.com"]
16
+ spec.license = "AGPLv3"
17
+ spec.homepage = "https://github.com/AjuntamentdeBarcelona/decidim"
18
+ spec.required_ruby_version = ">= 2.3.1"
10
19
  end
11
20
  end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ # This class handles all the logic associated to configuring a feature
4
+ # associated to a participatory process.
5
+ #
6
+ # It's normally not used directly but through the API exposed through
7
+ # `Decidim.register_feature`.
8
+ class FeatureManifest
9
+ include ActiveModel::Model
10
+ include Virtus.model
11
+
12
+ attribute :admin_engine, Rails::Engine
13
+ attribute :engine, Rails::Engine
14
+
15
+ attribute :name, Symbol
16
+ attribute :hooks, Hash[Symbol => Array[Proc]], default: {}
17
+
18
+ validates :name, presence: true
19
+
20
+ # Public: Registers a hook to this manifest. Hooks get fired when some
21
+ # lifecycle events happen, like the creation of a component or its
22
+ # destruction.
23
+ #
24
+ # event_name - A String or Symbol with the event name.
25
+ # &block - The block to run when the hook gets triggered.
26
+ #
27
+ # Returns nothing.
28
+ def on(event_name, &block)
29
+ hooks[event_name.to_sym] ||= []
30
+ hooks[event_name.to_sym] << block
31
+ end
32
+
33
+ # Public: Runs all the hooks associated with this manifest and a particular
34
+ # event.
35
+ #
36
+ # event_name - A String or Symbol with the event name.
37
+ # context - An optional context that will be provided to the block as a
38
+ # parameter. Usually the subject of the hook, mostly the
39
+ # Component.
40
+ #
41
+ # Returns nothing.
42
+ def run_hooks(event_name, context = nil)
43
+ return unless hooks[event_name]
44
+ hooks[event_name.to_sym].each do |hook|
45
+ hook.call(context)
46
+ end
47
+ end
48
+
49
+ # Semiprivate: Resets all the hooks of this manifest. Mostly useful when
50
+ # testing.
51
+ #
52
+ # Returns nothing.
53
+ def reset_hooks!
54
+ self.hooks = {}
55
+ end
56
+
57
+ # Public: A block that gets called when seeding for this feature takes place.
58
+ #
59
+ # Returns nothing.
60
+ def seeds(&block)
61
+ @seeds = block
62
+ end
63
+
64
+ # Public: Creates the seeds for this features in order to populate the database.
65
+ #
66
+ # Returns nothing.
67
+ def seed!
68
+ @seeds&.call
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ # This module contains all logic related to decidim's Features, the main
4
+ # building block to extend functionalities in a participatory process.
5
+ module Features
6
+ autoload :BaseController, "decidim/features/base_controller"
7
+ end
8
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Features
5
+ # Controller from which all feature engines inherit from. It's in charge of
6
+ # setting the appropiate layout, including necessary helpers, and overall
7
+ # fooling the engine into thinking it's isolated.
8
+ class BaseController < Decidim::ApplicationController
9
+ layout "layouts/decidim/participatory_process"
10
+ include NeedsParticipatoryProcess
11
+ helper Decidim::TranslationsHelper
12
+ helper Decidim::ParticipatoryProcessHelper
13
+ helper_method :current_feature
14
+
15
+ skip_authorize_resource
16
+
17
+ before_action do
18
+ authorize! :read, current_participatory_process
19
+ end
20
+
21
+ private
22
+
23
+ def current_feature
24
+ request.env["decidim.current_feature"]
25
+ end
26
+
27
+ def current_participatory_process
28
+ request.env["decidim.current_participatory_process"]
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Features
5
+ # This class automatically names features for the given organization.
6
+ # In order to do so, it uses the i18n keys of the feature, fallback to English,
7
+ # searching for the key `"decidim.features.<feature name>.name"`
8
+ #
9
+ # This is intended to be used from the feature seeds section.
10
+ #
11
+ # Examples:
12
+ #
13
+ # Decidim::Feature.create!(
14
+ # participatory_process: process,
15
+ # name: Decidim::Feature::Namer.new(organization.available_locales, :my_feature_name).i18n_name
16
+ # manifest_name: :my_feature_name
17
+ # )
18
+ class Namer
19
+ def initialize(locales, feature_name)
20
+ @locales = locales
21
+ @feature_name = feature_name
22
+ end
23
+
24
+ def i18n_name
25
+ locales.inject({}) do |names, locale|
26
+ names.update(locale => I18n.t("decidim.features.#{feature_name}.name", locale: locale))
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ attr_reader :locales, :feature_name
33
+ end
34
+ end
35
+ end
@@ -5,6 +5,8 @@ module Decidim
5
5
  # This custom FormBuilder adds fields needed to deal with translatable fields,
6
6
  # following the conventions set on `Decidim::TranslatableAttributes`.
7
7
  class FormBuilder < FoundationRailsHelper::FormBuilder
8
+ include ActionView::Context
9
+
8
10
  # Public: Generates an form field for each locale.
9
11
  #
10
12
  # type - The form field's type, like `text_area` or `text_input`
@@ -13,18 +15,135 @@ module Decidim
13
15
  #
14
16
  # Renders form fields for each locale.
15
17
  def translated(type, name, options = {})
16
- locales.map do |locale|
17
- label = options[:label] || label_for(name)
18
- language = locale
18
+ if locales.count == 1
19
+ return send(
20
+ type,
21
+ "#{name}_#{locales.first.to_s.gsub("-", "__")}",
22
+ options.merge(label: options[:label] || label_for(name))
23
+ )
24
+ end
25
+
26
+ field_label = label_i18n(name, options[:label] || label_for(name))
19
27
 
20
- send(type, "#{name}_#{locale.to_s.gsub("-", "__")}", options.merge(label: "#{label} (#{language})"))
21
- end.join.html_safe
28
+ tabs_panels = "".html_safe
29
+ if options[:label] != false
30
+ tabs_panels = content_tag(:ul, class: "tabs", id: "#{name}-tabs", data: { tabs: true }) do
31
+ locales.each_with_index.inject("".html_safe) do |string, (locale, index)|
32
+ string + content_tag(:li, class: tab_element_class_for("title", index)) do
33
+ title = I18n.t(locale, scope: "locales")
34
+ element_class = ""
35
+ element_class += "alert" if has_error?(name_with_locale(name, locale))
36
+ content_tag(:a, title, href: "##{name}-panel-#{index}", class: element_class)
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ tabs_content = content_tag(:div, class: "tabs-content", data: { tabs_content: "#{name}-tabs" }) do
43
+ locales.each_with_index.inject("".html_safe) do |string, (locale, index)|
44
+ string + content_tag(:div, class: tab_element_class_for("panel", index), id: "#{name}-panel-#{index}") do
45
+ send(type, name_with_locale(name, locale), options.merge(label: false))
46
+ end
47
+ end
48
+ end
49
+
50
+ safe_join [field_label, tabs_panels, tabs_content]
51
+ end
52
+
53
+ # Public: generates a hidden field and a container for WYSIWYG editor
54
+ #
55
+ # name - The name of the field
56
+ # options - The set of options to send to the field
57
+ # :label - The Boolean value to create or not the input label (optional) (default: true)
58
+ # :toolbar - The String value to configure WYSIWYG toolbar. It should be 'basic' or
59
+ # or 'full' (optional) (default: 'basic')
60
+ # :lines - The Integer to indicate how many lines should editor have (optional) (default: 10)
61
+ #
62
+ # Renders a container with both hidden field and editor container
63
+ def editor(name, options = {})
64
+ options[:toolbar] ||= "basic"
65
+ options[:lines] ||= 10
66
+
67
+ content_tag(:div, class: "editor") do
68
+ template = ""
69
+ template += label(name) if options[:label] != false
70
+ template += hidden_field(name, options)
71
+ template += content_tag(:div, nil, class: "editor-container", data: {
72
+ toolbar: options[:toolbar]
73
+ }, style: "height: #{options[:lines]}rem")
74
+ template += error_for(name, options) if has_error?(name)
75
+ template.html_safe
76
+ end
77
+ end
78
+
79
+ # Public: Generates a select field with the categories. Only leaf categories can be set as selected.
80
+ #
81
+ # name - The name of the field (usually category_id)
82
+ # collection - A collection of categories.
83
+ # options - An optional Hash with options:
84
+ # - prompt - An optional String with the text to display as prompt.
85
+ # - disable_parents - A Boolean to disable parent categories. Defaults to `true`.
86
+ #
87
+ # Returns a String.
88
+ def categories_select(name, collection, options = {})
89
+ options = {
90
+ prompt: nil,
91
+ disable_parents: true
92
+ }.merge(options)
93
+
94
+ prompt = options[:prompt]
95
+ disable_parents = options[:disable_parents]
96
+
97
+ selected = object.send(name)
98
+ categories = categories_for_select(collection)
99
+ categories = [[prompt]] + categories if prompt
100
+ disabled = if disable_parents
101
+ disabled_categories_for(collection)
102
+ else
103
+ []
104
+ end
105
+
106
+ select(name, @template.options_for_select(categories, selected: selected, disabled: disabled))
22
107
  end
23
108
 
24
109
  private
25
110
 
111
+ def categories_for_select(scope)
112
+ sorted_main_categories = scope.first_class.includes(:subcategories).sort_by do |category|
113
+ category.name[I18n.locale.to_s]
114
+ end
115
+
116
+ sorted_main_categories.flat_map do |category|
117
+ parent = [[category.name[I18n.locale.to_s], category.id]]
118
+
119
+ sorted_subcategories = category.subcategories.sort_by do |subcategory|
120
+ subcategory.name[I18n.locale.to_s]
121
+ end
122
+
123
+ sorted_subcategories.each do |subcategory|
124
+ parent << ["- #{subcategory.name[I18n.locale.to_s]}", subcategory.id]
125
+ end
126
+
127
+ parent
128
+ end
129
+ end
130
+
131
+ def disabled_categories_for(scope)
132
+ scope.first_class.joins(:subcategories).pluck(:id)
133
+ end
134
+
135
+ def tab_element_class_for(type, index)
136
+ element_class = "tabs-#{type}"
137
+ element_class += " is-active" if index.zero?
138
+ element_class
139
+ end
140
+
26
141
  def locales
27
- I18n.available_locales
142
+ @locales ||= if @template.respond_to?(:available_locales)
143
+ Set.new([@template.current_locale] + @template.available_locales).to_a
144
+ else
145
+ Decidim.available_locales
146
+ end
28
147
  end
29
148
 
30
149
  def label_for(attribute)
@@ -34,5 +153,20 @@ module Decidim
34
153
  attribute.to_s.humanize
35
154
  end
36
155
  end
156
+
157
+ def name_with_locale(name, locale)
158
+ "#{name}_#{locale.to_s.gsub("-", "__")}"
159
+ end
160
+
161
+ def label_i18n(attribute, text = nil, options = {})
162
+ errored = has_error?(attribute) || locales.any? { |locale| has_error?(name_with_locale(attribute, locale)) }
163
+
164
+ if errored
165
+ options[:class] ||= ""
166
+ options[:class] += " is-invalid-label"
167
+ end
168
+
169
+ label(attribute, (text || "").html_safe, options)
170
+ end
37
171
  end
38
172
  end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ # A custom implementation for HighVoltage so we can correctly find which page
4
+ # to render. We need this because we allow rendering pages with content from
5
+ # the database (with Decidim::Page) but also fallback to a template if it
6
+ # exists.
7
+ class PageFinder < HighVoltage::PageFinder
8
+ DECIDIM_PAGE_TEMPLATE = "decidim_page"
9
+
10
+ # Initializes the finder.
11
+ #
12
+ # page_id - A String with the id or slug of the page to render.
13
+ # organization - A Decidim::Organization to look for pages in.
14
+ def initialize(page_id, organization)
15
+ @page_id = page_id
16
+ @organization = organization
17
+ end
18
+
19
+ # Finds a Decidim::Page by slug.
20
+ #
21
+ # Returns a Decidim::Page or nil.
22
+ def page
23
+ @page ||= organization.static_pages.where(slug: page_id).first
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :organization
29
+
30
+ # Overwrite HighVoltage::PageFinder method to return a specific template
31
+ # when we need to render a Decidim::Page.
32
+ #
33
+ # Returns a String.
34
+ def clean_path
35
+ return super unless page.present?
36
+
37
+ DECIDIM_PAGE_TEMPLATE
38
+ end
39
+
40
+ # Overwrite HighVoltage::PageFinder method to not allow rendering the
41
+ # template used to render Decidim::Pages without a page.
42
+ #
43
+ # Returns a Boolean.
44
+ def invalid_page_id?(id)
45
+ super || id == DECIDIM_PAGE_TEMPLATE
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ # This module's job is to extend the API with custom fields related to
4
+ # decidim-core.
5
+ module QueryExtensions
6
+ # Public: Extends a type with `decidim-core`'s fields.
7
+ #
8
+ # type - A GraphQL::BaseType to extend.
9
+ #
10
+ # Returns nothing.
11
+ def self.extend!(type)
12
+ type.define do
13
+ field :processes do
14
+ type !types[ProcessType]
15
+ description "Lists all processes."
16
+
17
+ resolve ->(_obj, _args, ctx) {
18
+ OrganizationParticipatoryProcesses.new(ctx[:current_organization])
19
+ }
20
+ end
21
+
22
+ field :currentUser do
23
+ type UserType
24
+ description "Return's information about the logged in user"
25
+
26
+ resolve ->(_obj, _args, ctx) {
27
+ ctx[:current_user]
28
+ }
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end