decidim-core 0.25.0 → 0.26.0.rc2
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.
- checksums.yaml +4 -4
- data/app/cells/decidim/activity_cell.rb +2 -1
- data/app/cells/decidim/author/flag_user.erb +1 -1
- data/app/cells/decidim/author/profile_inline.erb +1 -1
- data/app/cells/decidim/author/withdraw.erb +2 -2
- data/app/cells/decidim/author_cell.rb +32 -0
- data/app/cells/decidim/card_m_cell.rb +1 -1
- data/app/cells/decidim/content_blocks/cta_cell.rb +1 -1
- data/app/cells/decidim/content_blocks/hero_cell.rb +1 -1
- data/app/cells/decidim/content_blocks/highlighted_content_banner/show.erb +1 -1
- data/app/cells/decidim/content_blocks/how_to_participate/show.erb +1 -1
- data/app/cells/decidim/content_blocks/last_activity_cell.rb +1 -1
- data/app/cells/decidim/content_blocks/stats_cell.rb +12 -0
- data/app/cells/decidim/endorsers_list_cell.rb +3 -1
- data/app/cells/decidim/flag_modal/flag_user.erb +2 -2
- data/app/cells/decidim/flag_modal/show.erb +2 -2
- data/app/cells/decidim/flag_modal_cell.rb +10 -0
- data/app/cells/decidim/following/show.erb +17 -8
- data/app/cells/decidim/following_cell.rb +6 -2
- data/app/cells/decidim/notification/show.erb +31 -0
- data/app/cells/decidim/notification_cell.rb +20 -0
- data/app/cells/decidim/notifications/show.erb +1 -24
- data/app/cells/decidim/notifications_cell.rb +0 -1
- data/app/cells/decidim/user_conversation/conversation_header.erb +1 -1
- data/app/cells/decidim/user_conversation/show.erb +4 -2
- data/app/cells/decidim/user_conversations/conversation_item.erb +1 -1
- data/app/commands/decidim/create_editor_image.rb +41 -0
- data/app/controllers/concerns/decidim/disable_redirection_to_external_host.rb +15 -0
- data/app/controllers/concerns/decidim/safe_redirect.rb +14 -3
- data/app/controllers/decidim/application_controller.rb +1 -0
- data/app/controllers/decidim/cookie_policy_controller.rb +2 -0
- data/app/controllers/decidim/editor_images_controller.rb +47 -0
- data/app/controllers/decidim/user_activities_controller.rb +2 -1
- data/app/forms/decidim/editor_image_form.rb +16 -0
- data/app/helpers/decidim/amendments_helper.rb +1 -1
- data/app/helpers/decidim/application_helper.rb +2 -2
- data/app/helpers/decidim/messaging/conversation_helper.rb +32 -3
- data/app/helpers/decidim/resource_versions_helper.rb +1 -1
- data/app/helpers/decidim/sanitize_helper.rb +65 -0
- data/app/models/decidim/editor_image.rb +14 -0
- data/app/models/decidim/messaging/conversation.rb +9 -0
- data/app/models/decidim/participatory_space_private_user.rb +16 -0
- data/app/models/decidim/user.rb +3 -9
- data/app/models/decidim/user_base_entity.rb +24 -13
- data/app/models/decidim/user_group.rb +40 -0
- data/app/packs/entrypoints/decidim_core.js +1 -0
- data/app/packs/src/decidim/dialog_mode.js +143 -0
- data/app/packs/src/decidim/dialog_mode.test.js +168 -0
- data/app/packs/src/decidim/editor.js +56 -14
- data/app/packs/src/decidim/form_attachments.js +5 -0
- data/app/packs/src/decidim/geocoding/attach_input.js +11 -2
- data/app/packs/src/decidim/index.js +4 -0
- data/app/packs/src/decidim/input_emoji.js +10 -1
- data/app/packs/src/decidim/vendor/image-resize.min.js +3 -0
- data/app/packs/src/decidim/vendor/image-upload.min.js +8 -0
- data/app/packs/stylesheets/decidim/extras/_extras.scss +0 -1
- data/app/packs/stylesheets/decidim/extras/_quill.scss +7 -0
- data/app/packs/stylesheets/decidim/modules/_buttons.scss +11 -4
- data/app/packs/stylesheets/decidim/modules/_cards.scss +4 -0
- data/app/packs/stylesheets/decidim/modules/_layout.scss +1 -1
- data/app/packs/stylesheets/decidim/modules/_timeline.scss +1 -1
- data/app/presenters/decidim/nil_presenter.rb +2 -2
- data/app/presenters/decidim/notification_presenter.rb +25 -0
- data/app/presenters/decidim/official_author_presenter.rb +1 -1
- data/app/presenters/decidim/validation_errors_presenter.rb +27 -0
- data/app/queries/decidim/similar_emendations.rb +1 -1
- data/app/resolvers/decidim/core/metric_resolver.rb +1 -1
- data/app/services/decidim/activity_search.rb +2 -2
- data/app/services/decidim/email_notification_generator.rb +4 -1
- data/app/services/decidim/html_truncation.rb +130 -0
- data/app/services/decidim/open_data_exporter.rb +29 -5
- data/app/services/decidim/resource_search.rb +1 -1
- data/app/uploaders/decidim/editor_image_uploader.rb +6 -0
- data/app/validators/password_validator.rb +123 -0
- data/app/views/decidim/account/_password_fields.html.erb +1 -1
- data/app/views/decidim/devise/passwords/edit.html.erb +1 -1
- data/app/views/decidim/devise/registrations/new.html.erb +1 -1
- data/app/views/decidim/devise/shared/_omniauth_buttons_mini.html.erb +6 -4
- data/app/views/decidim/messaging/conversations/_conversation.html.erb +9 -3
- data/app/views/decidim/messaging/conversations/_messages.html.erb +8 -2
- data/app/views/decidim/messaging/conversations/_show.html.erb +10 -12
- data/app/views/decidim/messaging/conversations/show.html.erb +4 -2
- data/app/views/decidim/newsletters/show.html.erb +1 -1
- data/app/views/decidim/notification_mailer/event_received.html.erb +17 -0
- data/app/views/decidim/pages/_tabbed.html.erb +1 -1
- data/app/views/decidim/searches/_filters_small_view.html.erb +3 -3
- data/app/views/decidim/shared/_login_modal.html.erb +5 -5
- data/app/views/decidim/shared/_orders.html.erb +1 -1
- data/app/views/decidim/shared/_results_per_page.html.erb +1 -1
- data/app/views/decidim/shared/participatory_space_filters/_filters_small_view.html.erb +3 -3
- data/app/views/layouts/decidim/_application.html.erb +1 -12
- data/app/views/layouts/decidim/_head.html.erb +4 -0
- data/app/views/layouts/decidim/_language_chooser.html.erb +1 -1
- data/app/views/layouts/decidim/_meta_tags_config.html.erb +11 -0
- data/app/views/layouts/decidim/_wrapper.html.erb +1 -1
- data/config/brakeman.ignore +149 -0
- data/config/initializers/devise.rb +1 -1
- data/config/initializers/rack_attack.rb +23 -21
- data/config/locales/ar.yml +8 -0
- data/config/locales/ca.yml +43 -0
- data/config/locales/cs.yml +61 -0
- data/config/locales/en.yml +47 -0
- data/config/locales/es-MX.yml +42 -0
- data/config/locales/es-PY.yml +42 -0
- data/config/locales/es.yml +42 -0
- data/config/locales/eu.yml +27 -12
- data/config/locales/fi-plain.yml +42 -0
- data/config/locales/fi.yml +42 -0
- data/config/locales/fr-CA.yml +43 -0
- data/config/locales/fr.yml +75 -28
- data/config/locales/gl.yml +6 -0
- data/config/locales/it.yml +11 -0
- data/config/locales/ja.yml +85 -49
- data/config/locales/lb-LU.yml +1354 -0
- data/config/locales/lb.yml +1 -1
- data/config/locales/nl.yml +51 -0
- data/config/locales/pl.yml +5 -5
- data/config/locales/pt-BR.yml +1 -1
- data/config/locales/ro-RO.yml +275 -252
- data/config/locales/sv.yml +45 -2
- data/config/locales/val-ES.yml +1 -0
- data/config/routes.rb +2 -0
- data/db/migrate/20210730112319_create_decidim_editor_images.rb +12 -0
- data/db/migrate/20211126183540_add_timestamps_to_content_blocks.rb +14 -0
- data/db/seeds.rb +16 -14
- data/lib/decidim/api/functions/user_entity_finder.rb +2 -1
- data/lib/decidim/api/functions/user_entity_list.rb +3 -1
- data/lib/decidim/api/input_sorts/component_input_sort.rb +1 -1
- data/lib/decidim/common_passwords.rb +56 -0
- data/lib/decidim/content_parsers/inline_images_parser.rb +68 -0
- data/lib/decidim/content_parsers.rb +1 -0
- data/lib/decidim/content_renderers/link_renderer.rb +85 -1
- data/lib/decidim/content_renderers/user_group_renderer.rb +1 -1
- data/lib/decidim/content_renderers/user_renderer.rb +1 -1
- data/lib/decidim/core/engine.rb +7 -12
- data/lib/decidim/core/test/factories.rb +7 -1
- data/lib/decidim/core/test/shared_examples/translated_event_examples.rb +131 -0
- data/lib/decidim/core/test.rb +1 -0
- data/lib/decidim/core/version.rb +1 -1
- data/lib/decidim/core.rb +33 -5
- data/lib/decidim/db/common-passwords.txt +128420 -0
- data/lib/decidim/etherpad/pad.rb +48 -0
- data/lib/decidim/etherpad.rb +7 -0
- data/lib/decidim/events/base_event.rb +18 -0
- data/lib/decidim/events/machine_translated_event.rb +36 -0
- data/lib/decidim/events/user_group_event.rb +1 -3
- data/lib/decidim/events.rb +1 -0
- data/lib/decidim/exporters/csv.rb +7 -7
- data/lib/decidim/faker/localized.rb +15 -6
- data/lib/decidim/form_builder.rb +14 -4
- data/lib/decidim/has_attachments.rb +11 -4
- data/lib/decidim/has_component.rb +4 -0
- data/lib/decidim/importers/import_manifest.rb +103 -3
- data/lib/decidim/organization_settings.rb +1 -1
- data/lib/decidim/paddable.rb +1 -9
- data/lib/decidim/participable.rb +5 -0
- data/lib/decidim/resourceable.rb +2 -9
- data/lib/decidim/searchable.rb +2 -2
- data/lib/decidim/settings_manifest.rb +2 -0
- data/lib/decidim/translatable_attributes.rb +6 -6
- data/lib/decidim/view_model.rb +10 -0
- data/lib/tasks/decidim_active_storage_migration_tasks.rake +68 -0
- data/lib/tasks/decidim_webpacker_tasks.rake +4 -10
- metadata +70 -78
- data/app/packs/stylesheets/decidim/extras/_social_icons_mini.scss +0 -11
|
@@ -33,7 +33,6 @@ module Decidim
|
|
|
33
33
|
open_data_component_manifests.each do |manifest|
|
|
34
34
|
add_file_to_output(out, format(FILE_NAME_PATTERN, { host: organization.host, entity: manifest.name }), data_for_component(manifest))
|
|
35
35
|
end
|
|
36
|
-
|
|
37
36
|
open_data_participatory_space_manifests.each do |manifest|
|
|
38
37
|
add_file_to_output(out, format(FILE_NAME_PATTERN, { host: organization.host, entity: manifest.name }), data_for_participatory_space(manifest))
|
|
39
38
|
end
|
|
@@ -42,12 +41,37 @@ module Decidim
|
|
|
42
41
|
buffer.string
|
|
43
42
|
end
|
|
44
43
|
|
|
45
|
-
def data_for_component(export_manifest)
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
def data_for_component(export_manifest, col_sep = Decidim.default_csv_col_sep)
|
|
45
|
+
headers = []
|
|
46
|
+
collection = []
|
|
47
|
+
ActiveRecord::Base.uncached do
|
|
48
|
+
components.where(manifest_name: export_manifest.manifest.name).find_each do |component|
|
|
49
|
+
export_manifest.collection.call(component).find_in_batches(batch_size: 100) do |batch|
|
|
50
|
+
exporter = Decidim::Exporters::CSV.new(batch, export_manifest.serializer)
|
|
51
|
+
headers.push(*exporter.headers)
|
|
52
|
+
exported = exporter.export
|
|
53
|
+
|
|
54
|
+
tmpfile = Tempfile.new("#{export_manifest.name}-#{component.id}-")
|
|
55
|
+
tmpfile.write(exported.read)
|
|
56
|
+
# Do not delete the file when the reference is deleted
|
|
57
|
+
ObjectSpace.undefine_finalizer(tmpfile)
|
|
58
|
+
tmpfile.close
|
|
59
|
+
|
|
60
|
+
collection.push(tmpfile.path)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
48
63
|
end
|
|
49
64
|
|
|
50
|
-
|
|
65
|
+
headers.uniq!
|
|
66
|
+
|
|
67
|
+
data = CSV.generate_line(headers, col_sep: col_sep)
|
|
68
|
+
collection.each do |content|
|
|
69
|
+
CSV.foreach(content, headers: true, col_sep: col_sep) do |row|
|
|
70
|
+
data << CSV.generate_line(row.values_at(*headers), col_sep: col_sep)
|
|
71
|
+
end
|
|
72
|
+
File.unlink(content)
|
|
73
|
+
end
|
|
74
|
+
Decidim::Exporters::ExportData.new(data, "csv")
|
|
51
75
|
end
|
|
52
76
|
|
|
53
77
|
def data_for_participatory_space(export_manifest)
|
|
@@ -75,7 +75,7 @@ module Decidim
|
|
|
75
75
|
conditions << "#{query.model_name.plural}.decidim_scope_id IS NULL" if clean_scope_ids.delete("global")
|
|
76
76
|
conditions.concat(["? = ANY(decidim_scopes.part_of)"] * clean_scope_ids.count) if clean_scope_ids.any?
|
|
77
77
|
|
|
78
|
-
query.includes(:scope).references(:decidim_scopes).where(conditions.join(" OR "), *clean_scope_ids.map(&:to_i))
|
|
78
|
+
query.includes(:scope).references(:decidim_scopes).where(Arel.sql(conditions.join(" OR ")).to_s, *clean_scope_ids.map(&:to_i))
|
|
79
79
|
end
|
|
80
80
|
|
|
81
81
|
# Handle the origin filter.
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Class is used to verify that the user's password is strong enough
|
|
4
|
+
class PasswordValidator < ActiveModel::EachValidator
|
|
5
|
+
MINIMUM_LENGTH = 10
|
|
6
|
+
MAX_LENGTH = 256
|
|
7
|
+
MIN_UNIQUE_CHARACTERS = 5
|
|
8
|
+
IGNORE_SIMILARITY_SHORTER_THAN = 4
|
|
9
|
+
VALIDATION_METHODS = [
|
|
10
|
+
:password_too_short?,
|
|
11
|
+
:password_too_long?,
|
|
12
|
+
:not_enough_unique_characters?,
|
|
13
|
+
:name_included_in_password?,
|
|
14
|
+
:nickname_included_in_password?,
|
|
15
|
+
:email_included_in_password?,
|
|
16
|
+
:domain_included_in_password?,
|
|
17
|
+
:password_too_common?,
|
|
18
|
+
:blacklisted?
|
|
19
|
+
].freeze
|
|
20
|
+
|
|
21
|
+
# Check if user's password is strong enough
|
|
22
|
+
#
|
|
23
|
+
# record - Instance of a form (e.g. Decidim::RegistrationForm) or model
|
|
24
|
+
# attribute - "password"
|
|
25
|
+
# value - Actual password
|
|
26
|
+
# Returns true if password is strong enough
|
|
27
|
+
def validate_each(record, attribute, value)
|
|
28
|
+
return false if value.blank?
|
|
29
|
+
|
|
30
|
+
@record = record
|
|
31
|
+
@attribute = attribute
|
|
32
|
+
@value = value
|
|
33
|
+
@weak_password_reasons = []
|
|
34
|
+
|
|
35
|
+
return true if strong?
|
|
36
|
+
|
|
37
|
+
@weak_password_reasons.each do |reason|
|
|
38
|
+
record.errors[attribute] << get_message(reason)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
false
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
attr_reader :record, :attribute, :value
|
|
47
|
+
|
|
48
|
+
def get_message(reason)
|
|
49
|
+
I18n.t "password_validator.#{reason}"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def strong?
|
|
53
|
+
VALIDATION_METHODS.each do |method|
|
|
54
|
+
@weak_password_reasons << method.to_s.sub(/\?$/, "").to_sym if send(method.to_s)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
@weak_password_reasons.empty?
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def password_too_short?
|
|
61
|
+
value.length < MINIMUM_LENGTH
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def password_too_long?
|
|
65
|
+
value.length > MAX_LENGTH
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def not_enough_unique_characters?
|
|
69
|
+
value.chars.uniq.length < MIN_UNIQUE_CHARACTERS
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def name_included_in_password?
|
|
73
|
+
return false if !record.respond_to?(:name) || record.name.blank?
|
|
74
|
+
return true if value.include?(record.name.delete(" "))
|
|
75
|
+
|
|
76
|
+
record.name.split(" ").each do |part|
|
|
77
|
+
next if part.length < IGNORE_SIMILARITY_SHORTER_THAN
|
|
78
|
+
|
|
79
|
+
return true if value.include?(part)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
false
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def nickname_included_in_password?
|
|
86
|
+
return false if !record.respond_to?(:nickname) || record.nickname.blank?
|
|
87
|
+
|
|
88
|
+
value.include?(record.nickname)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def email_included_in_password?
|
|
92
|
+
return false if !record.respond_to?(:email) || record.email.blank?
|
|
93
|
+
|
|
94
|
+
name, domain, _whatever = record.email.split("@")
|
|
95
|
+
value.include?(name) || (domain && value.include?(domain.split(".").first))
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def domain_included_in_password?
|
|
99
|
+
return false unless record&.current_organization&.host
|
|
100
|
+
return true if value.include?(record.current_organization.host)
|
|
101
|
+
|
|
102
|
+
record.current_organization.host.split(".").each do |part|
|
|
103
|
+
next if part.length < IGNORE_SIMILARITY_SHORTER_THAN
|
|
104
|
+
|
|
105
|
+
return true if value.include?(part)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
false
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def blacklisted?
|
|
112
|
+
Array(Decidim.password_blacklist).each do |expression|
|
|
113
|
+
return true if expression.is_a?(Regexp) && value.match?(expression)
|
|
114
|
+
return true if expression.to_s == value
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
false
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def password_too_common?
|
|
121
|
+
Decidim::CommonPasswords.instance.passwords.include?(value)
|
|
122
|
+
end
|
|
123
|
+
end
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
<%= form.password_field :password, value: form.object.password, autocomplete: "off", help_text: t("devise.passwords.edit.password_help", minimun_characters:
|
|
1
|
+
<%= form.password_field :password, value: form.object.password, autocomplete: "off", help_text: t("devise.passwords.edit.password_help", minimun_characters: ::PasswordValidator::MINIMUM_LENGTH) %>
|
|
2
2
|
<%= form.password_field :password_confirmation, value: form.object.password_confirmation, autocomplete: "off" %>
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
<%= f.hidden_field :reset_password_token %>
|
|
17
17
|
|
|
18
18
|
<div class="field">
|
|
19
|
-
<%= f.password_field :password, autocomplete: "off", help_text: t("devise.passwords.edit.password_help", minimun_characters:
|
|
19
|
+
<%= f.password_field :password, autocomplete: "off", help_text: t("devise.passwords.edit.password_help", minimun_characters: ::PasswordValidator::MINIMUM_LENGTH) %>
|
|
20
20
|
</div>
|
|
21
21
|
|
|
22
22
|
<div class="field">
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
</div>
|
|
50
50
|
|
|
51
51
|
<div class="field">
|
|
52
|
-
<%= f.password_field :password, help_text: t(".password_help", minimun_characters:
|
|
52
|
+
<%= f.password_field :password, help_text: t(".password_help", minimun_characters: ::PasswordValidator::MINIMUM_LENGTH), autocomplete: "off" %>
|
|
53
53
|
</div>
|
|
54
54
|
|
|
55
55
|
<div class="field">
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
<% if Devise.mappings[:user].omniauthable? && current_organization.enabled_omniauth_providers.any? %>
|
|
2
2
|
<div class="row">
|
|
3
3
|
<div class="columns medium-8 medium-centered">
|
|
4
|
-
<span class="register__separator">
|
|
5
|
-
<span class="register__separator__text"><%= t("or", scope: "decidim.devise.shared.omniauth_buttons") %></span>
|
|
6
|
-
</span>
|
|
7
4
|
<div class="text-center">
|
|
8
5
|
<%- current_organization.enabled_omniauth_providers.keys.each do |provider| %>
|
|
6
|
+
<div class="social-register">
|
|
9
7
|
<%= link_to decidim.send("user_#{provider}_omniauth_authorize_path"), class: "button button--social button--#{normalize_provider_name(provider)} button--social--mini", method: :post do %>
|
|
10
8
|
<span class="button--social__icon" aria-hidden="true">
|
|
11
9
|
<%= oauth_icon provider %>
|
|
12
10
|
</span>
|
|
13
|
-
<span class="
|
|
11
|
+
<span class="button--social__text">
|
|
14
12
|
<%= t("devise.shared.links.sign_in_with_provider", provider: normalize_provider_name(provider).titleize) %>
|
|
15
13
|
</span>
|
|
16
14
|
<% end %>
|
|
15
|
+
</div>
|
|
17
16
|
<% end %>
|
|
18
17
|
</div>
|
|
18
|
+
<span class="register__separator">
|
|
19
|
+
<span class="register__separator__text"><%= t("or", scope: "decidim.devise.shared.omniauth_buttons") %></span>
|
|
20
|
+
</span>
|
|
19
21
|
</div>
|
|
20
22
|
</div>
|
|
21
23
|
<% end %>
|
|
@@ -14,10 +14,16 @@
|
|
|
14
14
|
</li>
|
|
15
15
|
<li class="card-data__item card--list__item card-data__item--expand absolutes">
|
|
16
16
|
<div class="mr-s">
|
|
17
|
+
<% if conversation.messages.last.decidim_sender_id == current_user.id %>
|
|
18
|
+
<%= t("to", scope: "decidim.messaging.conversations.index") %>:
|
|
19
|
+
<% else %>
|
|
20
|
+
<%= t("from", scope: "decidim.messaging.conversations.index") %>:
|
|
21
|
+
<% end %>
|
|
22
|
+
|
|
17
23
|
<% if conversation.interlocutors(current_user).count == 1 %>
|
|
18
|
-
<%=
|
|
24
|
+
<%= conversation_name_for(conversation.interlocutors(current_user)) %>
|
|
19
25
|
<% else %>
|
|
20
|
-
|
|
26
|
+
<strong><%= username_list(conversation.interlocutors(current_user), shorten: true).html_safe %></strong>
|
|
21
27
|
<% end %>
|
|
22
28
|
<br>
|
|
23
29
|
<span class="muted">
|
|
@@ -45,7 +51,7 @@
|
|
|
45
51
|
<% if conversation.interlocutors(current_user).count == 1 %>
|
|
46
52
|
<%= icon "chevron-right", class: "card__link icon--big", role: "img", aria_label: t(".show", sender: conversation.interlocutors(current_user).first.name) %>
|
|
47
53
|
<% else %>
|
|
48
|
-
<%= icon "chevron-right", class: "card__link icon--big", role: "img", aria_label: t(".show", sender: username_list(conversation.interlocutors(current_user))) %>
|
|
54
|
+
<%= icon "chevron-right", class: "card__link icon--big", role: "img", aria_label: t(".show", sender: strip_tags(username_list(conversation.interlocutors(current_user)))) %>
|
|
49
55
|
<% end %>
|
|
50
56
|
<% end %>
|
|
51
57
|
</div>
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
<div class="conversation-chat<%= " conversation-chat--offset" if sender_is_user?(sender) %>">
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
<% if sender.deleted? %>
|
|
3
|
+
<span class="label label--small label--basic">
|
|
4
|
+
<%= t("deleted", scope: "decidim.profile") %>
|
|
5
|
+
</span>
|
|
6
|
+
<% else %>
|
|
7
|
+
<%= link_to profile_path(sender.nickname) do %>
|
|
8
|
+
<%= image_tag present(sender).avatar_url, alt: t("decidim.author.avatar", name: decidim_sanitize(sender.name)) %>
|
|
9
|
+
<% end %>
|
|
4
10
|
<% end %>
|
|
5
11
|
<div>
|
|
6
12
|
<% messages.each do |message| %>
|
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
<% if participants.count == 1 %>
|
|
2
|
-
<% conversation_label = t(".chat_with") + " #{participants.first.name} (@#{participants.first.nickname})" %>
|
|
3
|
-
<% else %>
|
|
4
|
-
<% conversation_label = t(".title", usernames: username_list(participants)) %>
|
|
5
|
-
<% end %>
|
|
6
|
-
|
|
7
1
|
<div class="wrapper">
|
|
8
2
|
<div class="row">
|
|
9
|
-
<div class="columns medium-9 medium-centered tabs-panel is-active" id="conversations" role="tabpanel" aria-label="<%=
|
|
3
|
+
<div class="columns medium-9 medium-centered tabs-panel is-active" id="conversations" role="tabpanel" aria-label="<%= strip_tags(conversation_label_for(participants)) %>">
|
|
10
4
|
<div class="conversation">
|
|
11
5
|
|
|
12
6
|
<div class="conversation-header flex--cc absolutes">
|
|
@@ -15,20 +9,24 @@
|
|
|
15
9
|
<%= icon "chevron-left", role: "img", aria_label: t(".back") %>
|
|
16
10
|
<% end %>
|
|
17
11
|
</div>
|
|
12
|
+
|
|
18
13
|
<% if participants.count == 1 %>
|
|
19
|
-
|
|
20
|
-
<%= image_tag present(participants.first).avatar_url, alt: t("decidim.author.avatar", name:
|
|
14
|
+
<% if participants.first.deleted? %>
|
|
15
|
+
<%= image_tag present(participants.first).avatar_url, alt: t("decidim.author.avatar", name: t("decidim.profile.deleted")) %>
|
|
16
|
+
<% else %>
|
|
17
|
+
<%= link_to profile_path(participants.first.nickname) do %>
|
|
18
|
+
<%= image_tag present(participants.first).avatar_url, alt: t("decidim.author.avatar", name: decidim_sanitize(participants.first.name)) %>
|
|
19
|
+
<% end %>
|
|
21
20
|
<% end %>
|
|
22
21
|
<% else %>
|
|
23
22
|
<%= image_tag present(current_user).avatar.default_multiuser_url, alt: t("decidim.author.avatar_multiuser") %>
|
|
24
23
|
<% end %>
|
|
25
|
-
|
|
26
24
|
<div class="ml-s">
|
|
27
25
|
<h1>
|
|
28
26
|
<% if participants.count == 1 %>
|
|
29
|
-
<%= t(".chat_with") %>
|
|
27
|
+
<%= t(".chat_with") %> <%= conversation_name_for(participants) %>
|
|
30
28
|
<% else %>
|
|
31
|
-
<%= t(".title", usernames: username_list(participants)) %>
|
|
29
|
+
<%= t(".title", usernames: username_list(participants)).html_safe %>
|
|
32
30
|
<% end %>
|
|
33
31
|
</h1>
|
|
34
32
|
</div>
|
|
@@ -5,9 +5,11 @@
|
|
|
5
5
|
<% end %>
|
|
6
6
|
</div>
|
|
7
7
|
|
|
8
|
-
<% if conversation.
|
|
8
|
+
<% if conversation.with_deleted_users?(current_user) %>
|
|
9
|
+
<div class="callout warning margin-top-2"><%= t ".deleted_accounts" %></div>
|
|
10
|
+
<% elsif conversation.accept_user?(current_user) %>
|
|
9
11
|
<%= render "reply", form: @form, conversation: conversation %>
|
|
10
12
|
<% else %>
|
|
11
|
-
<
|
|
13
|
+
<div class="callout warning margin-top-2"><%= t ".not_allowed" %></div>
|
|
12
14
|
<% end %>
|
|
13
15
|
<% end %>
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
newsletter: newsletter,
|
|
6
6
|
recipient_user: @user
|
|
7
7
|
) %>
|
|
8
|
-
<%=
|
|
8
|
+
<%= decidim_sanitize_editor @cell.to_s %>
|
|
9
9
|
|
|
10
10
|
<% content_for :note do %>
|
|
11
11
|
<%== t "note", scope: "decidim.newsletter_mailer.newsletter", organization_name: h(@organization.name), link: decidim.notifications_settings_url(host: @organization.host) %>
|
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
<% end %>
|
|
10
10
|
|
|
11
11
|
<% if @event_instance.try(:safe_resource_text).present? %>
|
|
12
|
+
<% if @event_instance.perform_translation? %>
|
|
13
|
+
<p style="font-weight: bold"><%= t(".original_text") %></p>
|
|
14
|
+
<% end %>
|
|
15
|
+
|
|
12
16
|
<blockquote>
|
|
13
17
|
<p>
|
|
14
18
|
<%= @event_instance.safe_resource_text %>
|
|
@@ -16,6 +20,19 @@
|
|
|
16
20
|
</blockquote>
|
|
17
21
|
<% end %>
|
|
18
22
|
|
|
23
|
+
<% if @event_instance.content_in_same_language? %>
|
|
24
|
+
<p><%= t(".same_language", language: I18n.locale.to_s ) %></p>
|
|
25
|
+
<% elsif @event_instance.translation_missing? %>
|
|
26
|
+
<p><%= t(".no_translation_available", link: @event_instance.resource_url ) %></p>
|
|
27
|
+
<% elsif @event_instance.perform_translation? %>
|
|
28
|
+
<p style="font-weight: bold"><%= t(".translated_text") %></p>
|
|
29
|
+
<blockquote>
|
|
30
|
+
<p>
|
|
31
|
+
<%= @event_instance.safe_resource_translated_text %>
|
|
32
|
+
</p>
|
|
33
|
+
</blockquote>
|
|
34
|
+
<% end %>
|
|
35
|
+
|
|
19
36
|
<% if @event_instance.has_button? %>
|
|
20
37
|
<table class="button expanded radius">
|
|
21
38
|
<tr>
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<div class="filters-controls hide-for-mediumlarge">
|
|
2
|
-
<button data-open="filter-box" class="filters-controls__trigger">
|
|
2
|
+
<button data-open="filter-box" class="filters-controls__trigger" aria-controls="filter-box" aria-haspopup="dialog">
|
|
3
3
|
<%= t ".filter" %>
|
|
4
4
|
<%= icon "caret-bottom", class: "icon--small float-right", aria_label: t(".unfold"), role: "img" %>
|
|
5
5
|
</button>
|
|
6
6
|
</div>
|
|
7
7
|
|
|
8
|
-
<div class="reveal" id="filter-box" data-reveal>
|
|
8
|
+
<div class="reveal" id="filter-box" data-reveal role="dialog" aria-modal="true" aria-labelledby="filter-box-label">
|
|
9
9
|
<div class="reveal__header">
|
|
10
|
-
<h3 class="reveal__title"><%= t ".filter_by" %>:</h3>
|
|
10
|
+
<h3 id="filter-box-label" class="reveal__title"><%= t ".filter_by" %>:</h3>
|
|
11
11
|
<button class="close-button" data-close aria-label="<%= t(".close_modal") %>" type="button">
|
|
12
12
|
<span aria-hidden="true">×</span>
|
|
13
13
|
</button>
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
<div class="reveal" id="loginModal" data-reveal>
|
|
1
|
+
<div class="reveal" id="loginModal" data-reveal role="dialog" aria-modal="true" aria-labelledby="loginModal-label">
|
|
2
2
|
<div class="reveal__header">
|
|
3
|
-
<h2 class="reveal__title"><%= t(".please_sign_in") %></h2>
|
|
3
|
+
<h2 id="loginModal-label" class="reveal__title"><%= t(".please_sign_in") %></h2>
|
|
4
4
|
<button class="close-button" data-close aria-label="<%= t(".close_modal") %>"
|
|
5
5
|
type="button">
|
|
6
6
|
<span aria-hidden="true">×</span>
|
|
7
7
|
</button>
|
|
8
8
|
</div>
|
|
9
9
|
<% if current_organization.sign_in_enabled? %>
|
|
10
|
+
<% cache current_organization do %>
|
|
11
|
+
<%= render "decidim/devise/shared/omniauth_buttons_mini" %>
|
|
12
|
+
<% end %>
|
|
10
13
|
<div class="row">
|
|
11
14
|
<div class="columns medium-8 medium-centered">
|
|
12
15
|
<%
|
|
@@ -39,9 +42,6 @@
|
|
|
39
42
|
</p>
|
|
40
43
|
</div>
|
|
41
44
|
</div>
|
|
42
|
-
<% cache current_organization do %>
|
|
43
|
-
<%= render "decidim/devise/shared/omniauth_buttons_mini" %>
|
|
44
|
-
<% end %>
|
|
45
45
|
<% else %>
|
|
46
46
|
<div class="row">
|
|
47
47
|
<div class="columns medium-8 medium-centered">
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
data-close-on-click="true"
|
|
10
10
|
role="menubar">
|
|
11
11
|
<li class="is-dropdown-submenu-parent" role="presentation">
|
|
12
|
-
<a href="#" id="<%= menu_id %>-control" aria-controls="<%= menu_id %>" aria-haspopup="
|
|
12
|
+
<a href="#" id="<%= menu_id %>-control" aria-controls="<%= menu_id %>" aria-haspopup="menu" title="<%= t("#{i18n_scope}.label") %>" role="menuitem"><%= t("#{i18n_scope}.#{order}") %></a>
|
|
13
13
|
|
|
14
14
|
<ul id="<%= menu_id %>" class="menu" role="menu" aria-labelledby="<%= menu_id %>-control">
|
|
15
15
|
<% orders.each do |order_name| %>
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
data-close-on-click="true"
|
|
10
10
|
role="menubar">
|
|
11
11
|
<li class="is-dropdown-submenu-parent" role="presentation">
|
|
12
|
-
<a href="#" id="<%= menu_id %>-control" aria-controls="<%= menu_id %>" aria-haspopup="
|
|
12
|
+
<a href="#" id="<%= menu_id %>-control" aria-controls="<%= menu_id %>" aria-haspopup="menu" title="<%= t("decidim.shared.results_per_page.title") %>" role="menuitem"><%= per_page %></a>
|
|
13
13
|
<ul id="<%= menu_id %>" class="menu" role="menu" aria-labelledby="<%= menu_id %>-control">
|
|
14
14
|
<% Decidim::Paginable::OPTIONS.each do |per_page_option| %>
|
|
15
15
|
<li role="presentation">
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<div class="filters-controls hide-for-mediumlarge">
|
|
2
|
-
<button data-open="filter-box" class="filters-controls__trigger">
|
|
2
|
+
<button data-open="filter-box" class="filters-controls__trigger" aria-controls="filter-box" aria-haspopup="dialog">
|
|
3
3
|
<%= t("filter", scope: "decidim.searches.filters_small_view") %>
|
|
4
4
|
<%= icon "caret-bottom", class: "icon--small float-right", aria_label: t("unfold", scope: "decidim.searches.filters_small_view"), role: "img" %>
|
|
5
5
|
</button>
|
|
6
6
|
</div>
|
|
7
7
|
|
|
8
|
-
<div class="reveal" id="filter-box" data-reveal>
|
|
8
|
+
<div class="reveal" id="filter-box" data-reveal role="dialog" aria-modal="true" aria-labelledby="filter-box-label">
|
|
9
9
|
<div class="reveal__header">
|
|
10
|
-
<h3 class="reveal__title"><%= t("filter_by", scope: "decidim.searches.filters_small_view") %>:</h3>
|
|
10
|
+
<h3 id="filter-box-label" class="reveal__title"><%= t("filter_by", scope: "decidim.searches.filters_small_view") %>:</h3>
|
|
11
11
|
<button class="close-button" data-close aria-label="<%= 't("close_modal", scope: "decidim.searches.filters_small_view")' %>" type="button">
|
|
12
12
|
<span aria-hidden="true">×</span>
|
|
13
13
|
</button>
|
|
@@ -1,15 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
description: strip_tags(translated_attribute(current_organization.description)),
|
|
3
|
-
title: current_organization.name,
|
|
4
|
-
url: request.original_url,
|
|
5
|
-
twitter_handler: current_organization.twitter_handler,
|
|
6
|
-
image_url: Decidim::ContentBlock.published.find_by(
|
|
7
|
-
organization: current_organization,
|
|
8
|
-
scope_name: :homepage,
|
|
9
|
-
manifest_name: :hero
|
|
10
|
-
).try(:images_container).try(:attached_uploader, :background_image).try(:path)
|
|
11
|
-
}) %>
|
|
12
|
-
|
|
1
|
+
<%= render partial: "layouts/decidim/meta_tags_config" %>
|
|
13
2
|
<!DOCTYPE html>
|
|
14
3
|
<html lang="<%= I18n.locale %>" class="no-js">
|
|
15
4
|
<head>
|
|
@@ -17,6 +17,10 @@
|
|
|
17
17
|
<meta property="og:description" content="<%= decidim_meta_description %>">
|
|
18
18
|
<meta property="og:image" content="<%= decidim_meta_image_url %>">
|
|
19
19
|
|
|
20
|
+
<% if current_organization.colors["theme"] %>
|
|
21
|
+
<meta name="theme-color" content="<%= current_organization.colors["theme"] %>">
|
|
22
|
+
<% end %>
|
|
23
|
+
|
|
20
24
|
<%= favicon %>
|
|
21
25
|
<%= stylesheet_pack_tag "decidim_core", media: "all" %>
|
|
22
26
|
<%= invisible_captcha_styles %>
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
data-close-on-click="true"
|
|
8
8
|
role="menubar">
|
|
9
9
|
<li class="is-dropdown-submenu-parent" role="presentation">
|
|
10
|
-
<%= link_to t("name", scope: "locale"), "#language-chooser-menu", id: "language-chooser-control", "aria-label": t("layouts.decidim.language_chooser.choose_language"), "aria-controls": "language-chooser-menu", "aria-haspopup": "
|
|
10
|
+
<%= link_to t("name", scope: "locale"), "#language-chooser-menu", id: "language-chooser-control", "aria-label": t("layouts.decidim.language_chooser.choose_language"), "aria-controls": "language-chooser-menu", "aria-haspopup": "menu", role: "menuitem" %>
|
|
11
11
|
<ul class="menu is-dropdown-submenu" id="language-chooser-menu" role="menu" aria-labelledby="language-chooser-control">
|
|
12
12
|
<% (available_locales - [I18n.locale.to_s]).each do |locale| %>
|
|
13
13
|
<li lang="<%= locale %>" role="presentation"><%= link_to locale_name(locale), decidim.locale_path(locale: locale), method: :post, role: "menuitem" %></li>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<% add_decidim_meta_tags({
|
|
2
|
+
description: strip_tags(translated_attribute(current_organization.description)),
|
|
3
|
+
title: current_organization.name,
|
|
4
|
+
url: request.original_url,
|
|
5
|
+
twitter_handler: current_organization.twitter_handler,
|
|
6
|
+
image_url: Decidim::ContentBlock.published.find_by(
|
|
7
|
+
organization: current_organization,
|
|
8
|
+
scope_name: :homepage,
|
|
9
|
+
manifest_name: :hero
|
|
10
|
+
).try(:images_container).try(:attached_uploader, :background_image).try(:path)
|
|
11
|
+
}) %>
|
|
@@ -66,7 +66,7 @@ end
|
|
|
66
66
|
data-close-on-click="true"
|
|
67
67
|
role="menubar">
|
|
68
68
|
<li class="is-dropdown-submenu-parent show-for-medium" role="presentation">
|
|
69
|
-
<%= link_to current_user.name, decidim.account_path, id: "user-menu-control", "aria-controls": "user-menu", "aria-haspopup": "
|
|
69
|
+
<%= link_to current_user.name, decidim.account_path, id: "user-menu-control", "aria-controls": "user-menu", "aria-haspopup": "menu", "aria-label": t("layouts.decidim.user_menu.account", name: current_user.name), "role": "menuitem" %>
|
|
70
70
|
<ul class="menu is-dropdown-submenu" id="user-menu" role="menu" aria-labelledby="user-menu-control">
|
|
71
71
|
<%= render partial: "layouts/decidim/user_menu" %>
|
|
72
72
|
</ul>
|