decidim-decidim_awesome 0.6.4 → 0.6.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +14 -6
- data/app/assets/stylesheets/decidim/decidim_awesome/admin.scss +4 -0
- data/app/awesome_overrides/presenters/decidim/menu_presenter_override.rb +31 -0
- data/app/commands/decidim/decidim_awesome/admin/create_menu_hack.rb +51 -0
- data/app/commands/decidim/decidim_awesome/admin/destroy_menu_hack.rb +47 -0
- data/app/commands/decidim/decidim_awesome/admin/update_config.rb +1 -1
- data/app/commands/decidim/decidim_awesome/admin/update_menu_hack.rb +47 -0
- data/app/controllers/decidim/decidim_awesome/admin/application_controller.rb +4 -3
- data/app/controllers/decidim/decidim_awesome/admin/config_controller.rb +9 -0
- data/app/controllers/decidim/decidim_awesome/admin/constraints_controller.rb +13 -0
- data/app/controllers/decidim/decidim_awesome/admin/menu_hacks_controller.rb +116 -0
- data/app/forms/decidim/decidim_awesome/admin/config_form.rb +5 -7
- data/app/forms/decidim/decidim_awesome/admin/constraint_form.rb +0 -2
- data/app/forms/decidim/decidim_awesome/admin/intergram_form.rb +0 -2
- data/app/forms/decidim/decidim_awesome/admin/menu_form.rb +39 -0
- data/app/helpers/decidim/decidim_awesome/admin/config_constraints_helpers.rb +5 -1
- data/app/permissions/decidim/decidim_awesome/admin/permissions.rb +19 -0
- data/app/permissions/decidim/decidim_awesome/permissions.rb +2 -0
- data/app/views/decidim/decidim_awesome/admin/config/_form_styles.html.erb +0 -1
- data/app/views/decidim/decidim_awesome/admin/menu_hacks/_form.html.erb +7 -0
- data/app/views/decidim/decidim_awesome/admin/menu_hacks/edit.html.erb +13 -0
- data/app/views/decidim/decidim_awesome/admin/menu_hacks/index.html.erb +44 -0
- data/app/views/decidim/decidim_awesome/admin/menu_hacks/new.html.erb +13 -0
- data/app/views/layouts/decidim/admin/decidim_awesome.html.erb +5 -0
- data/config/locales/ca.yml +45 -4
- data/config/locales/cs.yml +46 -5
- data/config/locales/en.yml +47 -4
- data/config/locales/es.yml +45 -4
- data/config/locales/eu.yml +45 -4
- data/config/locales/fr.yml +45 -4
- data/config/locales/nl.yml +212 -0
- data/config/locales/sv.yml +45 -4
- data/lib/decidim/decidim_awesome.rb +15 -0
- data/lib/decidim/decidim_awesome/admin_engine.rb +1 -0
- data/lib/decidim/decidim_awesome/checksums.yml +6 -0
- data/lib/decidim/decidim_awesome/engine.rb +1 -1
- data/lib/decidim/decidim_awesome/menu_hacker.rb +88 -0
- data/lib/decidim/decidim_awesome/test/shared_examples/config_examples.rb +4 -2
- data/lib/decidim/decidim_awesome/test/shared_examples/menu_hack_contexts.rb +71 -0
- data/lib/decidim/decidim_awesome/version.rb +1 -1
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2be39606cbd0f92bc8232bbd4a1c8b04a27aed18e9a0732668af6f37126d66f4
|
4
|
+
data.tar.gz: 5034f9d65042871ec4be47c313e90c46390e40751003666ea8a93166df087d31
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b2219e00f0a35206d772032e1f259e5283e2085a39bf5f45e47af09a784ece3776c0824ed7dc6d191cdcbf036b34a647fb5c9c172e13f86ef21394f54275fc9a
|
7
|
+
data.tar.gz: e2abb579c41c61b11377c986f692cba8b944671e1876616bf771309b8e62900a05b57582f72f1f458ef17309b55d8030c15727993ad99092c40ac4c4e31fd94a
|
data/README.md
CHANGED
@@ -33,7 +33,7 @@ Each hack can be scoped to one or more specific participatory spaces or componen
|
|
33
33
|
|
34
34
|
#### 1. Image support for the Quill editor
|
35
35
|
|
36
|
-
Modifies the WYSIWYG editor in Decidim by adding the possibility to insert images. When uploading images, Drag & Drop is supported. Images will be uploaded to the server and inserted as external resources (it doesn't use base64
|
36
|
+
Modifies the WYSIWYG editor in Decidim by adding the possibility to insert images. When uploading images, Drag & Drop is supported. Images will be uploaded to the server and inserted as external resources (it doesn't use base64 in-line encoding).
|
37
37
|
|
38
38
|
This feature allows you use images in newsletters as well.
|
39
39
|
|
@@ -71,13 +71,13 @@ Many scopes can be defined for every tweak.
|
|
71
71
|
|
72
72
|
This is a component you can add in any participatory space. It retrieves all the geolocated content in that participatory space (meetings or proposals) and displays it in a big map.
|
73
73
|
|
74
|
-
It also provides a simple search by category, each category is
|
74
|
+
It also provides a simple search by category, each category is assigned to a different color.
|
75
75
|
|
76
76
|
![Awesome map](examples/awesome-map.png)
|
77
77
|
|
78
78
|
#### 7. Allow Decidim to use custom CSS themes for every tenant
|
79
79
|
|
80
|
-
When
|
80
|
+
When customizing CSS for a Decidim installation, each change affects all the organizations (tenant).
|
81
81
|
|
82
82
|
This feature allows to customize each organization css without affecting the others in the same Decidim installation.
|
83
83
|
|
@@ -106,12 +106,20 @@ With this feature you can have a support chat in Decidim. It is linked to a [Tel
|
|
106
106
|
|
107
107
|
![Intergram screenshot](examples/intergram.png)
|
108
108
|
|
109
|
-
#### 10. Custom CSS applied only according
|
109
|
+
#### 10. Custom CSS applied only according scoped restrictions
|
110
110
|
|
111
|
-
|
111
|
+
With this feature you can create directly in the admin a CSS snipped that is only applied globally, in a particular assembly or even a single proposal!
|
112
112
|
|
113
113
|
![CSS screenshot](examples/custom_styles.png)
|
114
114
|
|
115
|
+
#### 11. Change the main menu of Decidim entirely!
|
116
|
+
|
117
|
+
Feel free to hide, modify or add items in the Decidim's main menu. You can also change the order, establish some conditions (like showing only for logged users) or open in a new window.
|
118
|
+
|
119
|
+
![Menu hacks screenshot](examples/menu-1.png)
|
120
|
+
![Menu hacks screenshot](examples/menu-2.png)
|
121
|
+
![Menu hacks screenshot](examples/menu-3.png)
|
122
|
+
![Menu hacks screenshot](examples/menu-4.png)
|
115
123
|
|
116
124
|
#### To be continued...
|
117
125
|
|
@@ -127,7 +135,7 @@ Some things in the road-map:
|
|
127
135
|
Add this line to your application's Gemfile:
|
128
136
|
|
129
137
|
```ruby
|
130
|
-
gem "decidim-decidim_awesome", "~> 0.6.
|
138
|
+
gem "decidim-decidim_awesome", "~> 0.6.5"
|
131
139
|
```
|
132
140
|
|
133
141
|
And then execute:
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Decidim::MenuPresenter.class_eval do
|
4
|
+
def evaluated_menu
|
5
|
+
@evaluated_menu ||= if Decidim::DecidimAwesome.config.send(@name) == :disabled
|
6
|
+
begin
|
7
|
+
menu = Decidim::Menu.new(@name)
|
8
|
+
menu.build_for(@view)
|
9
|
+
menu
|
10
|
+
end
|
11
|
+
else
|
12
|
+
Decidim::DecidimAwesome::MenuHacker.new(@name, @view)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
Decidim::MenuItemPresenter.class_eval do
|
18
|
+
def link_to(name = nil, options = nil, html_options = nil, &block)
|
19
|
+
html_options ||= {}
|
20
|
+
html_options[:target] = @menu_item.try(:target)
|
21
|
+
|
22
|
+
options ||= html_options
|
23
|
+
@view.link_to(name, options, html_options, &block)
|
24
|
+
end
|
25
|
+
|
26
|
+
def active
|
27
|
+
return @menu_item.active.call(url, @view) if @menu_item.try(:active).respond_to?(:call)
|
28
|
+
|
29
|
+
@menu_item&.active
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module DecidimAwesome
|
5
|
+
module Admin
|
6
|
+
class CreateMenuHack < Rectify::Command
|
7
|
+
# Public: Initializes the command.
|
8
|
+
#
|
9
|
+
def initialize(form, menu_name)
|
10
|
+
@form = form
|
11
|
+
@menu = AwesomeConfig.find_or_initialize_by(var: menu_name, organization: form.current_organization)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Executes the command. Broadcasts these events:
|
15
|
+
#
|
16
|
+
# - :ok when everything is valid.
|
17
|
+
# - :invalid if we couldn't proceed.
|
18
|
+
#
|
19
|
+
# Returns nothing.
|
20
|
+
def call
|
21
|
+
return broadcast(:invalid) if form.invalid?
|
22
|
+
return broadcast(:invalid, I18n.t("menu_hacks.url_exists", scope: "decidim.decidim_awesome.admin")) if url_exists?
|
23
|
+
|
24
|
+
menu.value = [] unless menu.value.is_a? Array
|
25
|
+
menu.value << to_params
|
26
|
+
menu.save!
|
27
|
+
broadcast(:ok, menu)
|
28
|
+
rescue StandardError => e
|
29
|
+
broadcast(:invalid, e.message)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
attr_reader :form, :menu
|
35
|
+
|
36
|
+
def url_exists?
|
37
|
+
return false unless menu
|
38
|
+
|
39
|
+
menu.value&.detect { |i| i["url"] == form.url.gsub(/\?.*/, "") }
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_params
|
43
|
+
params = form.to_params
|
44
|
+
url = Addressable::URI.parse(params[:url])
|
45
|
+
params[:url] = url.path if url.host == form.current_organization.host
|
46
|
+
params
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module DecidimAwesome
|
5
|
+
module Admin
|
6
|
+
class DestroyMenuHack < Rectify::Command
|
7
|
+
# Public: Initializes the command.
|
8
|
+
#
|
9
|
+
# item - the menu item to destroy
|
10
|
+
# organization
|
11
|
+
def initialize(item, menu_name, organization)
|
12
|
+
@item = item
|
13
|
+
@organization = organization
|
14
|
+
@menu = AwesomeConfig.find_by(var: menu_name, organization: organization)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Executes the command. Broadcasts these events:
|
18
|
+
#
|
19
|
+
# - :ok when everything is valid.
|
20
|
+
# - :invalid if we couldn't proceed.
|
21
|
+
#
|
22
|
+
# Returns nothing.
|
23
|
+
def call
|
24
|
+
return broadcast(:invalid) unless url_exists?
|
25
|
+
|
26
|
+
menu.value&.reject! { |i| i["url"] == item.url }
|
27
|
+
menu.save!
|
28
|
+
|
29
|
+
broadcast(:ok, @item)
|
30
|
+
rescue StandardError => e
|
31
|
+
broadcast(:invalid, e.message)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
attr_reader :organization, :item, :menu
|
37
|
+
|
38
|
+
def url_exists?
|
39
|
+
return false unless menu
|
40
|
+
return false unless menu.value.is_a? Array
|
41
|
+
|
42
|
+
menu.value&.detect { |i| i["url"] == item.url }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -23,7 +23,7 @@ module Decidim
|
|
23
23
|
begin
|
24
24
|
form.attributes.each do |key, val|
|
25
25
|
# ignore nil attributes (must specifically be set to false if necessary)
|
26
|
-
next
|
26
|
+
next unless form.valid_keys.include?(key)
|
27
27
|
|
28
28
|
setting = AwesomeConfig.find_or_initialize_by(var: key, organization: form.current_organization)
|
29
29
|
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module DecidimAwesome
|
5
|
+
module Admin
|
6
|
+
class UpdateMenuHack < Rectify::Command
|
7
|
+
# Public: Initializes the command.
|
8
|
+
#
|
9
|
+
def initialize(form, menu_name)
|
10
|
+
@form = form
|
11
|
+
@menu = AwesomeConfig.find_or_initialize_by(var: menu_name, organization: form.current_organization)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Executes the command. Broadcasts these events:
|
15
|
+
#
|
16
|
+
# - :ok when everything is valid.
|
17
|
+
# - :invalid if we couldn't proceed.
|
18
|
+
#
|
19
|
+
# Returns nothing.
|
20
|
+
def call
|
21
|
+
return broadcast(:invalid) if form.invalid?
|
22
|
+
|
23
|
+
menu.value = [] unless menu.value.is_a? Array
|
24
|
+
menu.value = menu.value.filter { |i| i.is_a? Hash }
|
25
|
+
found = false
|
26
|
+
menu.value.map! do |item|
|
27
|
+
if item["url"] == form.url
|
28
|
+
found = true
|
29
|
+
form.to_params
|
30
|
+
else
|
31
|
+
item
|
32
|
+
end
|
33
|
+
end
|
34
|
+
menu.value << form.to_params unless found
|
35
|
+
menu.save!
|
36
|
+
broadcast(:ok, menu)
|
37
|
+
rescue StandardError => e
|
38
|
+
broadcast(:invalid, e.message)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
attr_reader :form, :menu
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -9,9 +9,10 @@ module Decidim
|
|
9
9
|
# Note that it inherits from `Decidim::Admin::Components::BaseController`, which
|
10
10
|
# override its layout and provide all kinds of useful methods.
|
11
11
|
class ApplicationController < Decidim::Admin::ApplicationController
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
def permission_class_chain
|
13
|
+
[::Decidim::DecidimAwesome::Admin::Permissions] + super
|
14
|
+
end
|
15
|
+
|
15
16
|
before_action do
|
16
17
|
enforce_permission_to :update, :organization, organization: current_organization
|
17
18
|
end
|
@@ -12,6 +12,9 @@ module Decidim
|
|
12
12
|
layout "decidim/admin/decidim_awesome"
|
13
13
|
|
14
14
|
helper_method :constraints_for
|
15
|
+
before_action do
|
16
|
+
enforce_permission_to :edit_config, configs
|
17
|
+
end
|
15
18
|
|
16
19
|
def show
|
17
20
|
@form = form(ConfigForm).from_params(organization_awesome_config)
|
@@ -65,6 +68,12 @@ module Decidim
|
|
65
68
|
def constraints_for(key)
|
66
69
|
awesome_config_instance.setting_for(key)&.constraints
|
67
70
|
end
|
71
|
+
|
72
|
+
def configs
|
73
|
+
return params[:config].keys if params.has_key?(:config)
|
74
|
+
|
75
|
+
DecidimAwesome.config.keys
|
76
|
+
end
|
68
77
|
end
|
69
78
|
end
|
70
79
|
end
|
@@ -9,6 +9,9 @@ module Decidim
|
|
9
9
|
helper ConfigConstraintsHelpers
|
10
10
|
|
11
11
|
layout false
|
12
|
+
before_action do
|
13
|
+
enforce_permission_to :edit_config, constraint_key
|
14
|
+
end
|
12
15
|
|
13
16
|
def new
|
14
17
|
@form = form(ConstraintForm).from_params(filtered_params, setting: current_setting)
|
@@ -118,6 +121,16 @@ module Decidim
|
|
118
121
|
def current_setting
|
119
122
|
awesome_config_instance.setting_for params[:key]
|
120
123
|
end
|
124
|
+
|
125
|
+
def constraint_key
|
126
|
+
key = params[:key] || constraint.awesome_config.var
|
127
|
+
case key
|
128
|
+
when /^scoped_style_/
|
129
|
+
:scoped_styles
|
130
|
+
else
|
131
|
+
key
|
132
|
+
end
|
133
|
+
end
|
121
134
|
end
|
122
135
|
end
|
123
136
|
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module DecidimAwesome
|
5
|
+
module Admin
|
6
|
+
# Editing menu items
|
7
|
+
class MenuHacksController < DecidimAwesome::Admin::ApplicationController
|
8
|
+
include NeedsAwesomeConfig
|
9
|
+
helper ConfigConstraintsHelpers
|
10
|
+
|
11
|
+
layout "decidim/admin/decidim_awesome"
|
12
|
+
|
13
|
+
helper_method :current_items, :md5, :visibility_options, :target_options
|
14
|
+
|
15
|
+
before_action do
|
16
|
+
enforce_permission_to :edit_config, :menu
|
17
|
+
end
|
18
|
+
|
19
|
+
def index; end
|
20
|
+
|
21
|
+
def new
|
22
|
+
@form = form(MenuForm).instance
|
23
|
+
end
|
24
|
+
|
25
|
+
def create
|
26
|
+
@form = form(MenuForm).from_params(params)
|
27
|
+
CreateMenuHack.call(@form, current_menu_name) do
|
28
|
+
on(:ok) do
|
29
|
+
flash[:notice] = I18n.t("menu_hacks.create.success", scope: "decidim.decidim_awesome.admin")
|
30
|
+
redirect_to decidim_admin_decidim_awesome.menu_hacks_path
|
31
|
+
end
|
32
|
+
|
33
|
+
on(:invalid) do |message|
|
34
|
+
flash.now[:alert] = I18n.t("menu_hacks.create.error", error: message, scope: "decidim.decidim_awesome.admin")
|
35
|
+
render :new
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def edit
|
41
|
+
@form = form(MenuForm).from_model(menu_item)
|
42
|
+
end
|
43
|
+
|
44
|
+
def update
|
45
|
+
@form = form(MenuForm).from_params(params)
|
46
|
+
UpdateMenuHack.call(@form, current_menu_name) do
|
47
|
+
on(:ok) do
|
48
|
+
flash[:notice] = I18n.t("menu_hacks.update.success", scope: "decidim.decidim_awesome.admin")
|
49
|
+
redirect_to decidim_admin_decidim_awesome.menu_hacks_path
|
50
|
+
end
|
51
|
+
|
52
|
+
on(:invalid) do |message|
|
53
|
+
flash.now[:alert] = I18n.t("menu_hacks.update.error", error: message, scope: "decidim.decidim_awesome.admin")
|
54
|
+
render :edit
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def destroy
|
60
|
+
DestroyMenuHack.call(menu_item, current_menu_name, current_organization) do
|
61
|
+
on(:ok) do
|
62
|
+
flash[:notice] = I18n.t("menu_hacks.destroy.success", scope: "decidim.decidim_awesome.admin")
|
63
|
+
end
|
64
|
+
on(:invalid) do |error|
|
65
|
+
flash[:alert] = I18n.t("menu_hacks.destroy.error", scope: "decidim.decidim_awesome.admin", error: error)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
redirect_to decidim_admin_decidim_awesome.menu_hacks_path
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def menu_item
|
74
|
+
item = current_items.find { |i| md5(i.url) == params[:id] }
|
75
|
+
raise ActiveRecord::RecordNotFound unless item
|
76
|
+
|
77
|
+
OpenStruct.new(
|
78
|
+
raw_label: item.try(:raw_label) || { current_organization.default_locale => item.label },
|
79
|
+
url: item.url,
|
80
|
+
position: item.position,
|
81
|
+
target: item.try(:target),
|
82
|
+
visibility: item.try(:visibility),
|
83
|
+
native?: !item.respond_to?(:overrided?)
|
84
|
+
)
|
85
|
+
end
|
86
|
+
|
87
|
+
def current_items
|
88
|
+
@current_items ||= current_menu.items(true)
|
89
|
+
end
|
90
|
+
|
91
|
+
def current_menu
|
92
|
+
@current_menu ||= MenuHacker.new(current_menu_name, self)
|
93
|
+
end
|
94
|
+
|
95
|
+
def current_menu_name
|
96
|
+
:menu
|
97
|
+
end
|
98
|
+
|
99
|
+
def md5(text)
|
100
|
+
Digest::MD5.hexdigest(text)
|
101
|
+
end
|
102
|
+
|
103
|
+
def visibility_options
|
104
|
+
MenuForm::VISIBILITY_STATES.map { |key| [I18n.t(".menu_hacks.form.visibility.#{key}", scope: "decidim.decidim_awesome.admin"), key] }.to_h
|
105
|
+
end
|
106
|
+
|
107
|
+
def target_options
|
108
|
+
{
|
109
|
+
I18n.t(".menu_hacks.form.target.self", scope: "decidim.decidim_awesome.admin") => "",
|
110
|
+
I18n.t(".menu_hacks.form.target.blank", scope: "decidim.decidim_awesome.admin") => "_blank"
|
111
|
+
}
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|