decidim-core 0.29.0 → 0.29.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/activity_cell.rb +0 -3
  3. data/app/cells/decidim/author/show.erb +5 -4
  4. data/app/cells/decidim/author_cell.rb +26 -0
  5. data/app/cells/decidim/card_s/show.erb +5 -3
  6. data/app/cells/decidim/content_blocks/stats_cell.rb +1 -1
  7. data/app/cells/decidim/diff_cell.rb +4 -0
  8. data/app/cells/decidim/endorsement_buttons_cell.rb +1 -1
  9. data/app/cells/decidim/newsletter_templates/image_text_cta_cell.rb +1 -1
  10. data/app/cells/decidim/translation_bar/show.erb +2 -2
  11. data/app/cells/decidim/translation_bar_cell.rb +1 -1
  12. data/app/commands/decidim/amendable/create_draft.rb +1 -0
  13. data/app/commands/decidim/destroy_account.rb +3 -0
  14. data/app/controllers/concerns/decidim/devise_authentication_methods.rb +1 -1
  15. data/app/controllers/concerns/decidim/direct_upload.rb +82 -0
  16. data/app/controllers/decidim/doorkeeper/credentials_controller.rb +1 -1
  17. data/app/controllers/decidim/links_controller.rb +1 -1
  18. data/app/controllers/decidim/profiles_controller.rb +4 -0
  19. data/app/forms/decidim/upload_validation_form.rb +1 -1
  20. data/app/helpers/concerns/decidim/user_role_checker.rb +46 -0
  21. data/app/helpers/decidim/cta_button_helper.rb +1 -1
  22. data/app/helpers/decidim/layout_helper.rb +28 -0
  23. data/app/helpers/decidim/map_helper.rb +6 -1
  24. data/app/helpers/decidim/sanitize_helper.rb +11 -2
  25. data/app/helpers/decidim/scopes_helper.rb +3 -2
  26. data/app/models/decidim/action_log.rb +11 -1
  27. data/app/models/decidim/attachment.rb +1 -1
  28. data/app/packs/src/decidim/append_redirect_url_to_modals.js +24 -14
  29. data/app/packs/src/decidim/direct_uploads/upload_field.js +21 -8
  30. data/app/packs/src/decidim/direct_uploads/upload_modal.js +3 -0
  31. data/app/packs/src/decidim/index.js +3 -0
  32. data/app/packs/src/decidim/remote_tooltips.js +38 -0
  33. data/app/packs/src/decidim/toggle.js +1 -1
  34. data/app/packs/src/decidim/tooltips.js +42 -22
  35. data/app/packs/stylesheets/decidim/_buttons.scss +1 -1
  36. data/app/packs/stylesheets/decidim/_labels.scss +1 -1
  37. data/app/packs/stylesheets/decidim/_modal_update.scss +4 -0
  38. data/app/packs/stylesheets/decidim/_profile.scss +1 -1
  39. data/app/packs/stylesheets/decidim/_progress-bar.scss +1 -1
  40. data/app/packs/stylesheets/decidim/legacy/conference-diploma.scss +2 -1
  41. data/app/presenters/decidim/attachment_presenter.rb +1 -1
  42. data/app/queries/decidim/last_activity.rb +16 -5
  43. data/app/services/decidim/base_diff_renderer.rb +26 -2
  44. data/app/services/decidim/email_notification_generator.rb +14 -5
  45. data/app/views/decidim/devise/omniauth_registrations/new.html.erb +1 -1
  46. data/app/views/decidim/offline/show.html.erb +1 -1
  47. data/app/views/decidim/pages/_tabbed.html.erb +2 -2
  48. data/app/views/layouts/decidim/_head.html.erb +1 -1
  49. data/app/views/layouts/decidim/header/_menu_breadcrumb_mobile_tablet.html.erb +1 -1
  50. data/config/locales/ar.yml +16 -1
  51. data/config/locales/bg.yml +0 -1
  52. data/config/locales/bn-BD.yml +1 -0
  53. data/config/locales/bs-BA.yml +98 -0
  54. data/config/locales/ca.yml +14 -10
  55. data/config/locales/cs.yml +7 -1
  56. data/config/locales/de.yml +20 -16
  57. data/config/locales/el.yml +7 -1
  58. data/config/locales/en.yml +5 -1
  59. data/config/locales/es-MX.yml +6 -2
  60. data/config/locales/es-PY.yml +6 -2
  61. data/config/locales/es.yml +12 -8
  62. data/config/locales/eu.yml +202 -185
  63. data/config/locales/fi-plain.yml +5 -1
  64. data/config/locales/fi.yml +40 -36
  65. data/config/locales/fr-CA.yml +7 -3
  66. data/config/locales/fr.yml +6 -2
  67. data/config/locales/ga-IE.yml +9 -0
  68. data/config/locales/gl.yml +8 -1
  69. data/config/locales/hu.yml +3 -4
  70. data/config/locales/id-ID.yml +8 -0
  71. data/config/locales/is-IS.yml +8 -1
  72. data/config/locales/it.yml +19 -0
  73. data/config/locales/ja.yml +18 -16
  74. data/config/locales/lb.yml +9 -0
  75. data/config/locales/lt.yml +5 -2
  76. data/config/locales/lv.yml +8 -0
  77. data/config/locales/nl.yml +10 -1
  78. data/config/locales/no.yml +9 -0
  79. data/config/locales/pl.yml +1 -2
  80. data/config/locales/pt-BR.yml +244 -1
  81. data/config/locales/pt.yml +14 -0
  82. data/config/locales/ro-RO.yml +319 -180
  83. data/config/locales/ru.yml +8 -0
  84. data/config/locales/sk.yml +9 -1
  85. data/config/locales/sv.yml +541 -96
  86. data/config/locales/tr-TR.yml +10 -1
  87. data/config/locales/uk.yml +8 -1
  88. data/config/locales/zh-CN.yml +9 -0
  89. data/config/locales/zh-TW.yml +8 -1
  90. data/config/routes.rb +1 -0
  91. data/decidim-core.gemspec +4 -1
  92. data/lib/decidim/api/functions/component_list.rb +1 -1
  93. data/lib/decidim/api/functions/participatory_space_finder_base.rb +11 -1
  94. data/lib/decidim/api/interfaces/participatory_space_interface.rb +1 -1
  95. data/lib/decidim/api/types/component_type.rb +7 -0
  96. data/lib/decidim/api/types/user_group_type.rb +4 -0
  97. data/lib/decidim/api/types/user_type.rb +4 -0
  98. data/lib/decidim/attributes/rich_text.rb +38 -0
  99. data/lib/decidim/attributes/time_with_zone.rb +11 -1
  100. data/lib/decidim/attributes.rb +2 -0
  101. data/lib/decidim/content_parsers/blob_parser.rb +93 -0
  102. data/lib/decidim/content_parsers.rb +1 -0
  103. data/lib/decidim/content_renderers/blob_renderer.rb +90 -0
  104. data/lib/decidim/content_renderers.rb +1 -0
  105. data/lib/decidim/core/engine.rb +35 -1
  106. data/lib/decidim/core/test/factories.rb +28 -0
  107. data/lib/decidim/core/test/shared_examples/authorable_interface_examples.rb +1 -1
  108. data/lib/decidim/core/test/shared_examples/comments_examples.rb +25 -2
  109. data/lib/decidim/core/test/shared_examples/system_endorse_resource_examples.rb +107 -9
  110. data/lib/decidim/core/version.rb +1 -1
  111. data/lib/decidim/core.rb +11 -0
  112. data/lib/decidim/diffy_extension.rb +18 -0
  113. data/lib/decidim/form_builder.rb +1 -1
  114. data/lib/decidim/map/autocomplete.rb +1 -0
  115. data/lib/decidim/organization_settings.rb +4 -1
  116. data/lib/decidim/participatory_space_user.rb +4 -0
  117. data/lib/decidim/query_extensions.rb +0 -26
  118. data/lib/decidim/settings_manifest.rb +2 -0
  119. data/lib/decidim/translatable_attributes.rb +6 -1
  120. data/lib/decidim/view_model.rb +1 -1
  121. data/lib/tasks/upgrade/decidim_attachments.rake +14 -0
  122. data/lib/tasks/upgrade/decidim_fix_categorization.rake +34 -8
  123. metadata +30 -7
@@ -0,0 +1,38 @@
1
+ import createTooltip from "src/decidim/tooltips"
2
+
3
+ /**
4
+ * Given the following HTML structure,
5
+ * <span data-remote-tooltip="true" tooltip-url="some url" data-author="true">
6
+ * <span></span>
7
+ * </span>
8
+ *
9
+ * This function will check if the HTMLElement where is attached to has a child, and will add a data tooltip attribute
10
+ * to the respective child in order to attach the fetched HTML content fetched under a json key as the content of the
11
+ * HTML tooltip. The DOM structure is expected to be like follows:
12
+ *
13
+ * <span data-remote-tooltip="true" tooltip-url="some url" data-author="true">
14
+ * <span data-tooltip="HTML content from json data field"></span>
15
+ * </span>
16
+ *
17
+ * @param {HTMLElement} node The element holding the initialization data
18
+ * @returns {void}
19
+ */
20
+ export default async function(node) {
21
+ const container = node.firstElementChild;
22
+
23
+ if (container) {
24
+ const response = await fetch(node.dataset.tooltipUrl, {
25
+ headers: {
26
+ "Content-Type": "application/json"
27
+ }
28
+ });
29
+ if (response.ok) {
30
+ const json = await response.json();
31
+
32
+ container.dataset.tooltip = json.data;
33
+ createTooltip(container);
34
+ } else {
35
+ console.error(response.status, response.statusText);
36
+ }
37
+ }
38
+ }
@@ -9,7 +9,7 @@ export default function createToggle(component) {
9
9
  const { toggle } = component.dataset
10
10
 
11
11
  if (!component.id) {
12
- // when component has no id, we enforce to have it one
12
+ // when component has no id, we enforce it to have one
13
13
  component.id = `toggle-${Math.random().toString(36).substring(7)}`
14
14
  }
15
15
 
@@ -63,9 +63,32 @@ export default function(node) {
63
63
  // append to dom hidden, to apply css transitions
64
64
  tooltip.setAttribute("aria-hidden", true)
65
65
 
66
- const append = () => {
67
- // do nothing if the tooltip is already present at the DOM
66
+ // used to detect if the user is on a mobile device by checking the user agent
67
+ const useMobile = (/Mobi|Android/i).test(navigator.userAgent);
68
+
69
+ // used not to collapse tooltip
70
+ let removeTooltip = () => {
71
+ tooltip.setAttribute("aria-hidden", "true");
72
+ }
73
+
74
+ // used to allow clicks outside the tooltip to take place on the page or device
75
+ const OutsideClick = (event) => {
76
+ if (!tooltip.contains(event.target) && event.target !== node) {
77
+ removeTooltip();
78
+ }
79
+ }
80
+
81
+ // function called again to allow clicks outside the tooltip to collapse the tooltip
82
+ removeTooltip = () => {
83
+ tooltip.setAttribute("aria-hidden", "true");
84
+ document.removeEventListener("click", OutsideClick)
85
+ }
86
+
87
+ const toggleTooltip = (event) => {
88
+ event.preventDefault();
89
+ // if the tooltip is visible in the DOM, hide it otherwise display
68
90
  if (tooltip.getAttribute("aria-hidden") === "false") {
91
+ tooltip.setAttribute("aria-hidden", "true");
69
92
  return
70
93
  }
71
94
 
@@ -106,27 +129,24 @@ export default function(node) {
106
129
  tooltip.style.left = `${positionX}px`
107
130
 
108
131
  tooltip.setAttribute("aria-hidden", false)
109
- }
110
-
111
- // in order to revoke the remove event when the mouse is over the trigger/tooltip
112
- let cancelRemove = false
113
132
 
114
- const remove = () => {
115
- cancelRemove = false
116
- // give some sleep time before hiding the element from the DOM
117
- setTimeout(() => !cancelRemove && tooltip.setAttribute("aria-hidden", true), 500);
133
+ // sleep time before hiding the element from the DOM
134
+ setTimeout(() => document.addEventListener("click", OutsideClick))
118
135
  }
119
136
 
120
- // keyboard listener is at root-level
121
- window.addEventListener("keydown", (event) => event.key === "Escape" && remove())
122
-
123
- node.addEventListener("mouseenter", append)
124
- node.addEventListener("mouseleave", remove)
125
- node.addEventListener("focus", append)
126
- node.addEventListener("blur", remove)
127
- tooltip.addEventListener("mouseenter", () => tooltip.setAttribute("aria-hidden", false))
128
- tooltip.addEventListener("mouseleave", remove)
129
-
130
- node.addEventListener("mouseover", () => (cancelRemove = true))
131
- tooltip.addEventListener("mouseover", () => (cancelRemove = true))
137
+ if (useMobile) {
138
+ // mobile use to click and toggle the tooltip
139
+ node.addEventListener("click", toggleTooltip);
140
+ window.addEventListener("keydown", (event) => event.key === "Escape" && removeTooltip())
141
+ } else {
142
+ // desktop use for hover and blur over tooltip
143
+ node.addEventListener("mouseenter", toggleTooltip)
144
+ node.addEventListener("mouseleave", removeTooltip)
145
+ node.addEventListener("focus", toggleTooltip)
146
+ node.addEventListener("blur", removeTooltip)
147
+
148
+ // tooltip hover listeners to prevent hiding when hovered
149
+ tooltip.addEventListener("mouseenter", () => tooltip.setAttribute("aria-hidden", false))
150
+ tooltip.addEventListener("mouseleave", removeTooltip)
151
+ }
132
152
  }
@@ -67,7 +67,7 @@
67
67
  }
68
68
 
69
69
  &.is-hover,
70
- &:not([disabled]):not([class*="button__text"]):hover {
70
+ &:not([disabled]):not([class*="button__text"]):not(label):hover {
71
71
  @apply text-white;
72
72
 
73
73
  background: linear-gradient(0deg, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3)),
@@ -6,7 +6,7 @@
6
6
  --warning: #ad4910;
7
7
  --bg-warning: #ffeebd;
8
8
 
9
- @apply bg-background text-gray-2 rounded inline-flex items-center gap-1 px-2 font-semibold text-sm;
9
+ @apply bg-background text-gray-2 rounded inline-flex items-center gap-1 px-2 py-1 h-min font-semibold text-sm;
10
10
 
11
11
  &.success {
12
12
  @apply bg-[var(--bg-success)] text-[var(--success)];
@@ -6,6 +6,10 @@
6
6
  @apply py-14;
7
7
  }
8
8
 
9
+ &.is-disabled label.button__secondary {
10
+ @apply text-gray-2 bg-background-3 border border-gray-2 cursor-not-allowed;
11
+ }
12
+
9
13
  &-container {
10
14
  @apply space-y-4;
11
15
  }
@@ -45,7 +45,7 @@
45
45
 
46
46
  &__actions {
47
47
  &-main {
48
- @apply w-fit grid grid-cols-2 md:grid-cols-1 mx-auto gap-x-4 gap-y-6 md:gap-4;
48
+ @apply w-fit mx-auto gap-x-4 gap-y-6 md:gap-4;
49
49
 
50
50
  &__dropdown {
51
51
  @apply divide-y divide-gray-3 z-20 w-64;
@@ -29,7 +29,7 @@
29
29
  }
30
30
 
31
31
  &__sm {
32
- @apply w-16;
32
+ @apply w-16 pt-2;
33
33
  }
34
34
 
35
35
  &__sm &__number {
@@ -37,7 +37,6 @@
37
37
  }
38
38
 
39
39
  .conference-diploma .diploma__logo {
40
- border: 1px solid #333;
41
40
  padding: 2rem;
42
41
  }
43
42
 
@@ -47,10 +46,12 @@
47
46
  max-height: 100%;
48
47
  max-width: 100%;
49
48
  margin: 0;
49
+ padding-top: 10%;
50
50
  }
51
51
 
52
52
  .conference-diploma .diploma__border {
53
53
  margin: 0;
54
+ margin-top: 15%;
54
55
  -moz-border-image: url("../images/decidim/pattern.png") 20 repeat;
55
56
  -webkit-border-image: url("../images/decidim/pattern.png") 20 repeat;
56
57
  -o-border-image: url("../images/decidim/pattern.png") 20 repeat;
@@ -6,7 +6,7 @@ module Decidim
6
6
  #
7
7
  class AttachmentPresenter < SimpleDelegator
8
8
  def attachment_file_url
9
- attachment.attached_uploader(:file).url(host: attached_to.organization.host)
9
+ attachment.attached_uploader(:file).url
10
10
  end
11
11
 
12
12
  def attachment
@@ -56,13 +56,24 @@ module Decidim
56
56
 
57
57
  condition = if klass.include?(Decidim::HasPrivateUsers)
58
58
  Arel.sql(
59
- [
60
- "decidim_action_logs.participatory_space_type = '#{manifest.model_class_name}'",
61
- "decidim_action_logs.participatory_space_id IN (#{Arel.sql(klass.visible_for(current_user).select(:id).to_sql)})"
62
- ].join(" AND ")
59
+ <<~SQL.squish
60
+ (
61
+ decidim_action_logs.participatory_space_type = '#{manifest.model_class_name}' AND#{" "}
62
+ decidim_action_logs.participatory_space_id IN (#{Arel.sql(klass.visible_for(current_user).select(:id).to_sql)})
63
+ ) OR#{" "}
64
+ (
65
+ decidim_action_logs.resource_type = '#{manifest.model_class_name}' AND#{" "}
66
+ decidim_action_logs.resource_id IN (#{Arel.sql(klass.visible_for(current_user).select(:id).to_sql)})
67
+ )
68
+ SQL
63
69
  ).to_s
64
70
  else
65
- Arel.sql("decidim_action_logs.participatory_space_type = '#{manifest.model_class_name}'").to_s
71
+ Arel.sql(
72
+ [
73
+ "decidim_action_logs.resource_type = '#{manifest.model_class_name}'",
74
+ "decidim_action_logs.participatory_space_type = '#{manifest.model_class_name}'"
75
+ ].join(" OR ")
76
+ ).to_s
66
77
  end
67
78
 
68
79
  conditions << "(#{condition})"
@@ -41,7 +41,7 @@ module Decidim
41
41
  end
42
42
 
43
43
  def parse_i18n_changeset(attribute, values, type, diff)
44
- values.last.keys.each do |locale, _value|
44
+ (values.last.keys - ["machine_translations"]).each do |locale, _value|
45
45
  first_value = values.first.try(:[], locale)
46
46
  last_value = values.last.try(:[], locale)
47
47
  next if first_value == last_value
@@ -56,6 +56,27 @@ module Decidim
56
56
  }
57
57
  )
58
58
  end
59
+
60
+ return diff unless values.last.has_key?("machine_translations")
61
+
62
+ values.last.fetch("machine_translations").each_key do |locale, _value|
63
+ next unless I18n.available_locales.include?(locale.to_sym)
64
+
65
+ first_value = values.first.try(:[], "machine_translations").try(:[], locale)
66
+ last_value = values.last.try(:[], "machine_translations").try(:[], locale)
67
+
68
+ attribute_locale = :"#{attribute}_machine_translations_#{locale}"
69
+
70
+ diff.update(
71
+ attribute_locale => {
72
+ type:,
73
+ label: generate_i18n_label(attribute, locale, "decidim.machine_translations.automatic"),
74
+ old_value: first_value,
75
+ new_value: last_value
76
+ }
77
+ )
78
+ end
79
+
59
80
  diff
60
81
  end
61
82
 
@@ -108,7 +129,8 @@ module Decidim
108
129
  end
109
130
 
110
131
  # Returns a String.
111
- def generate_i18n_label(attribute, locale)
132
+ # i18n-tasks-use t("decidim.machine_translations.automatic")
133
+ def generate_i18n_label(attribute, locale, postfix = "")
112
134
  label = I18n.t(attribute, scope: i18n_scope)
113
135
  locale_name = if I18n.available_locales.include?(locale.to_sym)
114
136
  I18n.t("locale.name", locale:)
@@ -116,6 +138,8 @@ module Decidim
116
138
  locale
117
139
  end
118
140
 
141
+ locale_name = I18n.t(postfix, locale_name:, locale:) if postfix.present?
142
+
119
143
  "#{label} (#{locale_name})"
120
144
  end
121
145
 
@@ -36,20 +36,29 @@ module Decidim
36
36
  return unless resource
37
37
  return unless event_class.types.include?(:email)
38
38
 
39
- followers.each do |recipient|
40
- next unless ["all", "followed-only"].include?(recipient.notification_types)
39
+ send_to_followers
40
+ send_to_affected_users
41
+ end
41
42
 
42
- send_email_to(recipient, user_role: :follower)
43
- end
43
+ private
44
44
 
45
+ def send_to_affected_users
45
46
  affected_users.each do |recipient|
46
47
  next unless ["all", "own-only"].include?(recipient.notification_types)
48
+ next if recipient.deleted? || recipient.blocked?
47
49
 
48
50
  send_email_to(recipient, user_role: :affected_user)
49
51
  end
50
52
  end
51
53
 
52
- private
54
+ def send_to_followers
55
+ followers.each do |recipient|
56
+ next unless ["all", "followed-only"].include?(recipient.notification_types)
57
+ next if recipient.deleted? || recipient.blocked?
58
+
59
+ send_email_to(recipient, user_role: :follower)
60
+ end
61
+ end
53
62
 
54
63
  attr_reader :event, :event_class, :resource, :followers, :affected_users, :extra
55
64
 
@@ -13,7 +13,7 @@
13
13
  <%= form_required_explanation %>
14
14
  </div>
15
15
 
16
- <%= decidim_form_for(@form, namespace: "registration", as: resource_name, url: omniauth_registrations_path(resource_name)) do |f| %>
16
+ <%= decidim_form_for(@form, namespace: "registration", as: resource_name, url: decidim.omniauth_registrations_path(resource_name)) do |f| %>
17
17
 
18
18
  <div class="form__wrapper">
19
19
  <%= f.text_field :name, help_text: t("decidim.devise.omniauth_registrations.new.username_help"), autocomplete: "name", placeholder: "John Doe" %>
@@ -1,6 +1,6 @@
1
1
  <% add_decidim_page_title(t("decidim.offline.name")) %>
2
2
 
3
- <main id="offline-fallback-html" class="text-center mt-8">
3
+ <main id="offline-fallback-html" class="text-center my-8">
4
4
  <div class="flex justify-center">
5
5
  <svg xmlns="http://www.w3.org/2000/svg" width="5rem" height="r5em" viewBox="0 0 25 25">
6
6
  <path
@@ -10,7 +10,7 @@
10
10
  </header>
11
11
 
12
12
  <div class="vertical-tabs">
13
- <nav>
13
+ <nav role="navigation" aria-label="<%= I18n.t("layouts.decidim.navigation.aria_label", title: translated_attribute(page.title)) %>">
14
14
  <button id="dropdown-trigger-pages" data-component="dropdown" data-target="dropdown-menu-pages" data-open-md="true" data-auto-close="true">
15
15
  <span>
16
16
  <%= translated_attribute(page.title) %>
@@ -21,7 +21,7 @@
21
21
  <ul id="dropdown-menu-pages" class="vertical-tabs__list" role="menu">
22
22
  <% pages.each do |sibling| %>
23
23
  <li class="<%= "is-active" if page == sibling %>" role="menuitem">
24
- <%= link_to translated_attribute(sibling.title), page_path(sibling.slug) %>
24
+ <%= link_to translated_attribute(sibling.title), page_path(sibling.slug), "aria-current": (page == sibling).to_s %>
25
25
  </li>
26
26
  <% end %>
27
27
  </ul>
@@ -2,7 +2,7 @@
2
2
 
3
3
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
4
4
  <% available_locales.each do |locale| %>
5
- <link rel="alternate" href="<%= url_for(request.parameters.merge(locale:)) %>" hreflang="<%= locale %>">
5
+ <link rel="alternate" href="<%= current_url(request.parameters.merge(locale:)) %>" hreflang="<%= locale %>">
6
6
  <% end %>
7
7
 
8
8
  <meta name="twitter:card" content="summary_large_image">
@@ -2,7 +2,7 @@
2
2
  <div class="menu-bar__breadcrumb-mobile__dropdown-trigger">
3
3
  <span>
4
4
  <% breadcrumb_items.last(2).each_with_index do |item, i| %>
5
- <% item_label = decidim_escape_translated(item[:label]) %>
5
+ <% item_label = decidim_escape_translated(item[:label]).html_safe %>
6
6
  <% if i.positive? %>
7
7
  <span>/</span>
8
8
  <% end %>
@@ -91,6 +91,8 @@ ar:
91
91
  'false': 'لا'
92
92
  'true': 'نعم'
93
93
  date:
94
+ buttons:
95
+ select: تحديد
94
96
  formats:
95
97
  decidim_short: "%d/%m/%Y"
96
98
  decidim_short_with_month_name_short: "%d %b %Y"
@@ -282,6 +284,7 @@ ar:
282
284
  withdrawn: |-
283
285
  تم سحب هذا التعديل على %{amendable_type} %{amendable_link}
284
286
  من قبل المؤلف.
287
+ name: تعديل
285
288
  new:
286
289
  amendment_author: مؤلف التعديل
287
290
  send: إنشاء
@@ -454,6 +457,8 @@ ar:
454
457
  description: الوصف
455
458
  footer_sub_hero:
456
459
  name: تذييل البطل الفرعي راية
460
+ global_menu:
461
+ name: القائمة العامة
457
462
  hero_settings_form:
458
463
  background_image: الصورة الخلفية
459
464
  welcome_text: نص الترحيب
@@ -473,8 +478,12 @@ ar:
473
478
  name: النشاط الاخير
474
479
  title: النشاط الاخير
475
480
  view_all: عرض الكل
481
+ metadata:
482
+ name: البيانات الوصفية
476
483
  metrics:
477
484
  name: مقاييس المنظمة
485
+ participatory_space_metrics:
486
+ name: المقاييس
478
487
  participatory_space_stats:
479
488
  name: الإحصائيات
480
489
  social_networks_metadata:
@@ -493,6 +502,10 @@ ar:
493
502
  name: احصائيات المنظمة
494
503
  sub_hero:
495
504
  name: البطل الفرعي راية
505
+ core:
506
+ application_helper:
507
+ filter_category_values:
508
+ all: الكل
496
509
  devise:
497
510
  omniauth_registrations:
498
511
  new:
@@ -796,7 +809,6 @@ ar:
796
809
  title_required: العنوان مطلوب!
797
810
  uploaded: تم التحميل
798
811
  validating: جارية المصادقة...
799
- validation_error: خطأ في المصادقة!
800
812
  select_file: اختيار ملف
801
813
  upload_help:
802
814
  dropzone: قم بإسقاط الملفات هنا أو انقر للتحميل
@@ -1253,6 +1265,7 @@ ar:
1253
1265
  participatory_space_filters:
1254
1266
  filters:
1255
1267
  areas: المناطق
1268
+ scope: نطاق
1256
1269
  select_an_area: اختر المنطقة
1257
1270
  public_participation:
1258
1271
  public_participation: إبراز حضوري علنا
@@ -1665,6 +1678,8 @@ ar:
1665
1678
  whatsapp_web: واتساب
1666
1679
  xing: شينغ
1667
1680
  time:
1681
+ buttons:
1682
+ select: تحديد
1668
1683
  formats:
1669
1684
  day_of_month: "%b %d"
1670
1685
  day_of_week: "%a"
@@ -926,7 +926,6 @@ bg:
926
926
  title_required: Заглавието е задължително!
927
927
  uploaded: Качено
928
928
  validating: Валидиране...
929
- validation_error: Грешка при валидирането!
930
929
  select_file: Избор на файл
931
930
  upload_help:
932
931
  dropzone: Пуснете файлове тук или щракнете върху бутона за качване
@@ -0,0 +1 @@
1
+ bn:
@@ -0,0 +1,98 @@
1
+ ---
2
+ bs:
3
+ activerecord:
4
+ models:
5
+ decidim/endorsement:
6
+ one: Podržavanje
7
+ few: Podržavanja
8
+ other: Podržavanja
9
+ decidim:
10
+ accessibility:
11
+ logo: "Zvanični logo %{organization}"
12
+ skip_button: Preskoči na glavni sadržaj
13
+ admin_log:
14
+ user:
15
+ show_email: "%{user_name} je pribavio e-mail adresu učesnika %{resource_name}"
16
+ application:
17
+ document:
18
+ download: Preuzmi datoteku
19
+ author:
20
+ endorsements:
21
+ one: podržavanje
22
+ few: podržavanja
23
+ other: podržavanja
24
+ content_blocks:
25
+ hero_settings_form:
26
+ background_image: Pozadinska slika
27
+ welcome_text: Tekst dobrodošlice
28
+ stats:
29
+ name: Statistika organizacije
30
+ endorsements:
31
+ identities:
32
+ done: Gotovo
33
+ select_identity: Izaberite identitet
34
+ events:
35
+ resource_endorsed:
36
+ email_intro: '%{endorser_name}%{endorser_nickname}, koga pratite, je podržao %{resource_title} i mislimo da bi vas to možda interesovalo. Pogledajte i doprinesite:'
37
+ email_outro: Dobili ste ovo obaveštenje jer pratite %{endorser_nickname}. Možete da prestanete da dobijate obaveštenja, ukoliko pratite prethodni link.
38
+ email_subject: "%{endorser_nickname} je podržao nešto"
39
+ messaging:
40
+ conversations:
41
+ add_conversation_users:
42
+ add_max_users: 'Dodajte korisnike u razgovor: najviše 9 korisnika'
43
+ add_users_placeholder: Pretraži...
44
+ modal_title: Novi razgovor
45
+ no_results: Nema rezultata
46
+ index:
47
+ new_conversation: Novi razgovor
48
+ next: Sledeće
49
+ newsletter_templates:
50
+ basic_only_text:
51
+ body_preview: 'Probni tekst za pasus: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque fringilla nisl tellus. Donec sed mi dui. Sed efficitur libero a felis tempor sollicitudin. Nullam vestibulum fringilla felis, id efficitur lorem sagittis et. Vivamus aliquam maximus velit vel dapibus. Mauris pellentesque, enim eu varius lacinia, risus ante rutrum ipsum, non lobortis augue lorem quis urna. Aenean et malesuada arcu.'
52
+ name: Osnovno (samo tekst)
53
+ basic_only_text_settings_form:
54
+ body: Glavni deo teksta
55
+ interpolations_hint: 'Mala pomoć: Možeš da napišeš "%{name}" bilo gde u tekstu ili naslovu i automatski će se zameniti sa imenom primaoca.'
56
+ image_text_cta:
57
+ body_preview: 'Probni tekst za pasus: Maecenas ac nisl vitae lectus pretium facilisis. Etiam facilisis sem nibh, sit amet rutrum mi aliquam nec. Sed id urna at nisl pretium mollis eu vel velit. Proin vitae suscipit urna, sed faucibus urna. Pellentesque id libero vulputate ipsum scelerisque suscipit. Nam aliquam sodales mi sit amet cursus. Donec mattis faucibus purus. Aenean tincidunt porta lorem ac commodo. Vestibulum in mollis mi. Morbi eros erat, cursus ut tortor sit amet, imperdiet dapibus arcu. Suspendisse id egestas enim. In eget magna sed enim efficitur elementum sit amet aliquam quam. Donec fermentum metus eget urna luctus pulvinar.'
58
+ cta_text_preview: Tekst Poziva na akciju
59
+ introduction_preview: 'Probni tekst za uvod: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque fringilla nisl tellus. Donec sed mi dui. Sed efficitur libero a felis tempor sollicitudin. Nullam vestibulum fringilla felis, id efficitur lorem sagittis et. Vivamus aliquam maximus velit vel dapibus. Mauris pellentesque, enim eu varius lacinia, risus ante rutrum ipsum, non lobortis augue lorem quis urna. Aenean et malesuada arcu.'
60
+ name: Dugme za sliku, tekst i Poziv na akciju
61
+ image_text_cta_settings_form:
62
+ body: Glavni deo teksta
63
+ cta_text: Tekst dugmeta poziva na akciju
64
+ cta_url: Link dugmeta poziva na akciju
65
+ interpolations_hint: 'Mala pomoć: Možeš da napišeš "%{name}" bilo gde u uvodu, glavnom delu teksta, pozivu na akciju ili naslovu i automatski će se zameniti sa imenom primaoca.'
66
+ introduction: Uvod
67
+ main_image: Glavna slika
68
+ notifications_settings:
69
+ show:
70
+ direct_messages: Primaj direktne poruke od svih bez ograničenja
71
+ pages:
72
+ participatory_space:
73
+ metrics:
74
+ headline: Metrika
75
+ link: Prikaži svu metriku
76
+ resource_endorsements:
77
+ create:
78
+ error: Nastao je problem pri podržavanju.
79
+ shared:
80
+ results_per_page:
81
+ title: Izaberite broj rezultata po stranici
82
+ user_contact_disabled: Ovaj učesnik ne prihvata direktne poruke.
83
+ errors:
84
+ messages:
85
+ invalid_time_zone: nije validna vremenska zona
86
+ locale:
87
+ name: Bosanski
88
+ time:
89
+ formats:
90
+ long_dashed: "%d-%m-%Y %H:%M:%S"
91
+ versions:
92
+ dropdown:
93
+ choose_diff_view_html: 'HTML režim gledanja:'
94
+ views:
95
+ pagination:
96
+ next_title: Veza ka sledećoj stranici
97
+ previous_title: Veza ka prethodnoj stranici
98
+ title: 'Redni broj stranice:'