decidim-core 0.31.0.rc2 → 0.31.0

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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/activity_cell.rb +6 -0
  3. data/app/controllers/decidim/download_your_data_controller.rb +5 -2
  4. data/app/models/decidim/private_export.rb +4 -0
  5. data/app/packs/src/decidim/controllers/dropdown/controller.js +2 -2
  6. data/app/packs/src/decidim/datepicker/generate_datepicker.js +6 -0
  7. data/app/packs/src/decidim/datepicker/generate_timepicker.js +9 -0
  8. data/app/packs/src/decidim/index.js +10 -5
  9. data/app/packs/src/decidim/map/controller/markers.js +3 -1
  10. data/app/packs/stylesheets/decidim/_dropdown.scss +22 -5
  11. data/app/packs/stylesheets/decidim/_filters.scss +1 -1
  12. data/app/packs/stylesheets/decidim/_footer.scss +5 -0
  13. data/app/services/decidim/download_your_data_exporter.rb +15 -4
  14. data/app/services/decidim/open_data_exporter.rb +2 -1
  15. data/app/views/decidim/download_your_data/_export.html.erb +1 -1
  16. data/app/views/decidim/export_mailer/download_your_data_export.html.erb +1 -1
  17. data/app/views/decidim/export_mailer/export.html.erb +1 -1
  18. data/config/locales/ca-IT.yml +4 -2
  19. data/config/locales/ca.yml +2 -0
  20. data/config/locales/de.yml +1 -1
  21. data/config/locales/en.yml +2 -0
  22. data/config/locales/es-MX.yml +2 -0
  23. data/config/locales/es-PY.yml +2 -0
  24. data/config/locales/es.yml +2 -0
  25. data/config/locales/eu.yml +26 -15
  26. data/config/locales/fi-plain.yml +11 -0
  27. data/config/locales/fi.yml +11 -0
  28. data/config/locales/fr-CA.yml +13 -1
  29. data/config/locales/fr.yml +13 -1
  30. data/config/locales/it.yml +2 -0
  31. data/config/locales/ja.yml +22 -0
  32. data/config/locales/ru.yml +0 -1
  33. data/config/locales/sl.yml +0 -1
  34. data/db/data/20251108232118_add_dummy_migration.rb +11 -0
  35. data/db/migrate/20250819110800_convert_private_exports_id_to_uuid.rb +55 -0
  36. data/decidim-core.gemspec +1 -0
  37. data/lib/decidim/core/engine.rb +9 -0
  38. data/lib/decidim/core/test/factories.rb +7 -2
  39. data/lib/decidim/core/test/shared_examples/comments_examples.rb +24 -0
  40. data/lib/decidim/core/version.rb +1 -1
  41. data/lib/decidim/shakapacker/configuration.rb +5 -1
  42. data/lib/tasks/upgrade/clean.rake +11 -0
  43. data/lib/tasks/upgrade/decidim_fix_action_log.rake +28 -0
  44. metadata +23 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 20b25b4c72d8bdd6dc49a4de6ef5c9668d93ee906c40e9ca1147883682b22a32
4
- data.tar.gz: aa75ba1beac71b39a10ac9dc539be1c8390aaa6ac61d253f16b02889a58933a9
3
+ metadata.gz: 644720c93a8b08cdb4aa839557a74298774aef2719321671ca3bee677d8e93a6
4
+ data.tar.gz: e603634ef33432a213f5122b5e00c11614085d95fcc35e4a3c1b180d582427d8
5
5
  SHA512:
6
- metadata.gz: 108a66dff2b65eb213285e9335ae7c4e365f541fb49460973c07e4a372ebbf5673514113cfc5e3fb451ee867ad6a0de40a520f7953da10d95c5ad05ed97e98cb
7
- data.tar.gz: fd774c108044e92d3181a8d3fb57d5b2c6cfa42bd411485765bb53e302dc3bf480022f9bda4fa4bbec7050c8a898db5ba7c267a68ec58ecccd1324c8d7554a07
6
+ metadata.gz: a98933696db00e724d2b7ae56c14e3cc718be1026234a9a36679ef3678395a3fe4308be1ff8d9fd59aa233f7c056459e2466089a2f9e21368c9df6b37c722505
7
+ data.tar.gz: 2dc98284fe86eb99c409a4f418b00ec6baba661476bfa2114b518a63dfba5313b33e268099a1e90703d98ec4ec438c8e1e4a30e51717ca63c2fb2f57b20e4664
@@ -12,6 +12,12 @@ module Decidim
12
12
  return unless renderable?
13
13
 
14
14
  render
15
+ rescue NoMethodError => e
16
+ # Soft-deleted components or participatory spaces could cause errors
17
+ # when rendering activities. We log them for further inspection but
18
+ # avoid breaking the entire activity feed.
19
+ Rails.logger.error("Error rendering activity cell for #{model.id}: #{e.message}")
20
+ nil
15
21
  end
16
22
 
17
23
  # Since activity logs could be linked to resource no longer available
@@ -43,7 +43,10 @@ module Decidim
43
43
  def download_file
44
44
  enforce_permission_to(:download, :user, current_user:)
45
45
 
46
- if private_export.expired?
46
+ if private_export.blank?
47
+ flash[:error] = t("decidim.account.download_your_data_export.export_not_found")
48
+ redirect_to download_your_data_path
49
+ elsif private_export.expired?
47
50
  flash[:error] = t("decidim.account.download_your_data_export.export_expired")
48
51
  redirect_to download_your_data_path
49
52
  elsif private_export.file.attached?
@@ -57,7 +60,7 @@ module Decidim
57
60
  private
58
61
 
59
62
  def private_export
60
- @private_export ||= current_user.private_exports.find(params[:uuid])
63
+ @private_export ||= current_user.private_exports.where(uuid: params[:uuid]).first
61
64
  end
62
65
 
63
66
  def help_definitions
@@ -12,6 +12,10 @@ module Decidim
12
12
 
13
13
  default_scope { order(created_at: :desc) }
14
14
 
15
+ before_create do |record|
16
+ record.uuid = SecureRandom.uuid
17
+ end
18
+
15
19
  def expired?
16
20
  expires_at < Time.zone.now
17
21
  end
@@ -116,10 +116,10 @@ export default class extends Controller {
116
116
  changeStyleOfSelectedElement() {
117
117
  this.element.addEventListener("click", function(event) {
118
118
  event.target.parentNode.parentNode.querySelectorAll("a").forEach((link) => {
119
- link.parentNode.classList.remove("dropdown__item-hovered")
119
+ link.parentNode.classList.remove("dropdown__item-opened");
120
120
  })
121
121
 
122
- event.target.parentNode.classList.add("dropdown__item-hovered")
122
+ event.target.parentNode.classList.add("dropdown__item-opened")
123
123
  })
124
124
  }
125
125
  }
@@ -14,12 +14,18 @@ export default function generateDatePicker(input, row, formats) {
14
14
  date.setAttribute("id", `${input.id}_date`);
15
15
  date.setAttribute("type", "text");
16
16
  date.setAttribute("aria-label", input.dataset.dateLabel);
17
+ if (input.attributes.disabled) {
18
+ date.setAttribute("disabled", input.attributes.disabled);
19
+ };
17
20
 
18
21
  const calendar = document.createElement("button");
19
22
  calendar.innerHTML = icon("calendar-line");
20
23
  calendar.setAttribute("class", "datepicker__calendar-button");
21
24
  calendar.setAttribute("type", "button");
22
25
  calendar.setAttribute("aria-label", input.dataset.buttonDateLabel);
26
+ if (input.attributes.disabled) {
27
+ calendar.setAttribute("disabled", input.attributes.disabled);
28
+ };
23
29
 
24
30
  dateColumn.appendChild(date);
25
31
  dateColumn.appendChild(calendar);
@@ -1,4 +1,6 @@
1
1
  /* eslint-disable require-jsdoc */
2
+ /* eslint max-lines: ["error", 310] */
3
+
2
4
  import icon from "src/decidim/refactor/moved/icon"
3
5
  import { changeHourDisplay, changeMinuteDisplay, formatDate, hourDisplay, minuteDisplay, formatTime, setHour, setMinute, updateTimeValue, updateInputValue } from "src/decidim/datepicker/datepicker_functions"
4
6
  import { timeKeyDownListener, timeBeforeInputListener } from "src/decidim/datepicker/datepicker_listeners";
@@ -14,12 +16,19 @@ export default function generateTimePicker(input, row, formats) {
14
16
  time.setAttribute("id", `${input.id}_time`);
15
17
  time.setAttribute("type", "text");
16
18
  time.setAttribute("aria-label", input.dataset.timeLabel);
19
+ if (input.attributes.disabled) {
20
+ time.setAttribute("disabled", input.attributes.disabled);
21
+ };
17
22
 
18
23
  const clock = document.createElement("button");
19
24
  clock.innerHTML = icon("time-line")
20
25
  clock.setAttribute("class", "datepicker__clock-button");
21
26
  clock.setAttribute("type", "button");
22
27
  clock.setAttribute("aria-label", input.dataset.buttonTimeLabel);
28
+ if (input.attributes.disabled) {
29
+ clock.setAttribute("disabled", input.attributes.disabled);
30
+ };
31
+
23
32
 
24
33
  timeColumn.appendChild(time);
25
34
  timeColumn.appendChild(clock);
@@ -70,16 +70,21 @@ const deprecate = (element, targetController, oldSyntax) => {
70
70
  return;
71
71
  }
72
72
 
73
- console.warn(element)
74
73
  console.warn(`[Decidim] ${oldSyntax} is deprecated. Please use the new version of this component - data-controller="${targetController}" - ${window.location.href}`)
75
- // eslint-disable-next-line no-alert
76
- alert(`[Decidim] ${oldSyntax} is deprecated. Please use the new version of this component - data-controller="${targetController}"`)
74
+
75
+ if (typeof window.Decidim.dev !== "undefined" && window.Decidim.dev === true) {
76
+ // eslint-disable-next-line no-alert
77
+ alert(`[Decidim] ${oldSyntax} is deprecated. Please use the new version of this component - data-controller="${targetController}"`)
78
+ }
77
79
  }
78
80
 
79
81
  const deprecationMessage = (element, oldSyntax, newSyntax) => {
80
82
  console.warn(`[Decidim] ${oldSyntax} is deprecated. Please use the new version of this component - ${newSyntax}`)
81
- // eslint-disable-next-line no-alert
82
- alert(`[Decidim] ${oldSyntax} is deprecated. Please use the new version of this component - ${newSyntax}`)
83
+
84
+ if (typeof window.Decidim.dev !== "undefined" && window.Decidim.dev === true) {
85
+ // eslint-disable-next-line no-alert
86
+ alert(`[Decidim] ${oldSyntax} is deprecated. Please use the new version of this component - ${newSyntax}`)
87
+ }
83
88
  }
84
89
 
85
90
  window.deprecate = deprecate;
@@ -67,7 +67,9 @@ export default class MapMarkersController extends MapController {
67
67
  }
68
68
 
69
69
  clearMarkers() {
70
- this.map.removeLayer(this.markerClusters);
70
+ if (this.markerClusters !== null) {
71
+ this.map.removeLayer(this.markerClusters);
72
+ }
71
73
  this.markerClusters = new L.MarkerClusterGroup();
72
74
  this.map.addLayer(this.markerClusters);
73
75
  }
@@ -106,12 +106,9 @@
106
106
  @apply text-gray-2 mr-1;
107
107
  }
108
108
  }
109
- }
110
109
 
111
- &:hover,
112
- &-hovered {
113
- > .dropdown__button {
114
- @apply text-white no-underline;
110
+ &:hover {
111
+ @apply text-white no-underline !bg-secondary;
115
112
 
116
113
  span {
117
114
  @apply text-white;
@@ -122,6 +119,26 @@
122
119
  }
123
120
  }
124
121
  }
122
+
123
+ &-opened {
124
+ > .dropdown__button {
125
+ @apply text-secondary no-underline;
126
+
127
+ span {
128
+ @apply text-secondary;
129
+ }
130
+
131
+ svg {
132
+ fill: rgb(var(--secondary-rgb) / var(--tw-bg-opacity)) !important;
133
+ }
134
+
135
+ &:hover {
136
+ svg {
137
+ fill: white !important;
138
+ }
139
+ }
140
+ }
141
+ }
125
142
  }
126
143
 
127
144
  &__bottom {
@@ -129,7 +129,7 @@
129
129
 
130
130
  /* overwrite default dropdowns */
131
131
  [data-target="dropdown-menu-filters"] {
132
- @apply px-0 justify-start [&>span]:text-gray-2;
132
+ @apply px-0 justify-start [&>span]:text-gray-2 md:hidden;
133
133
 
134
134
  > svg {
135
135
  @apply h-4 w-4 text-gray;
@@ -4,6 +4,11 @@ footer {
4
4
 
5
5
  &__top {
6
6
  @apply hidden lg:flex flex-row gap-8 container py-10;
7
+
8
+ .prose a,
9
+ .prose strong {
10
+ @apply text-white;
11
+ }
7
12
  }
8
13
 
9
14
  &__down {
@@ -22,14 +22,21 @@ module Decidim
22
22
  end
23
23
 
24
24
  # i18n-tasks-use t("decidim.download_your_data.show.download_your_data")
25
- def export
26
- user_export = user.private_exports.build
25
+ def export(retries: 0)
26
+ data.rewind
27
+ user_export = user.private_exports.build(file_size: data.length)
27
28
  user_export.export_type = name
28
- user_export.file.attach(io: data, filename: "#{name}.zip", content_type: "application/zip")
29
+ user_export.content_type = "application/zip"
29
30
  user_export.expires_at = Decidim.download_your_data_expiry_time.from_now
30
31
  user_export.metadata = {}
31
32
  user_export.save!
32
- user_export
33
+ user_export.file.attach(io: data, filename: "#{name}.zip", content_type: "application/zip")
34
+
35
+ return user_export.reload if user_export.reload.file.attached?
36
+ return user_export.reload if retries >= 3
37
+
38
+ user_export.destroy!
39
+ export(retries: retries + 1)
33
40
  end
34
41
 
35
42
  private
@@ -37,6 +44,10 @@ module Decidim
37
44
  attr_reader :user, :export_format, :name
38
45
 
39
46
  def data
47
+ @data ||= load_data!
48
+ end
49
+
50
+ def load_data!
40
51
  user_data, user_attachments = data_and_attachments_for_user
41
52
  buffer = Zip::OutputStream.write_buffer do |out|
42
53
  save_user_data(out, user_data)
@@ -117,9 +117,10 @@ module Decidim
117
117
  end
118
118
 
119
119
  def data_for_participatory_space(export_manifest)
120
- collection = participatory_spaces.flat_map do |participatory_space|
120
+ collection = participatory_spaces.filter { |space| space.manifest.name == export_manifest.manifest.name }.flat_map do |participatory_space|
121
121
  export_manifest.collection.call(participatory_space)
122
122
  end
123
+
123
124
  serializer = export_manifest.open_data_serializer.nil? ? export_manifest.serializer : export_manifest.open_data_serializer
124
125
  exporter = Decidim::Exporters::CSV.new(collection, serializer)
125
126
  get_help_definition(:spaces, exporter, export_manifest, collection.count) unless collection.empty?
@@ -2,7 +2,7 @@
2
2
  <td class="text-left p-4"><%= t(export.export_type, scope:"decidim.download_your_data.show") %></td>
3
3
  <td class="text-center"><%= export.expired? ? t("expired", scope:"decidim.download_your_data.show") : l(export.expires_at, format: :decidim_short) %></td>
4
4
  <td class="py-4">
5
- <%= button_to download_download_your_data_path(export),
5
+ <%= button_to download_download_your_data_path(uuid: export.uuid),
6
6
  class: "button button__sm button__transparent-secondary m-auto block",
7
7
  disabled: export.expired?,
8
8
  aria: { label: t("download", scope:"decidim.download_your_data.show") },
@@ -3,5 +3,5 @@
3
3
  </p>
4
4
 
5
5
  <p class="email-button email-button__cta">
6
- <%= link_to t(".download"), download_download_your_data_url(@private_export, host: @organization.host), class: "button expanded hollow button--sc" %>
6
+ <%= link_to t(".download"), download_download_your_data_url(uuid: @private_export.uuid, host: @organization.host), class: "button expanded hollow button--sc" %>
7
7
  </p>
@@ -3,5 +3,5 @@
3
3
  </p>
4
4
 
5
5
  <p class="email-button email-button__cta">
6
- <%= link_to t(".download"), download_download_your_data_url(@private_export, host: @organization.host), class: "button expanded hollow button--sc" %>
6
+ <%= link_to t(".download"), download_download_your_data_url(uuid: @private_export.uuid, host: @organization.host), class: "button expanded hollow button--sc" %>
7
7
  </p>
@@ -199,6 +199,7 @@ ca-IT:
199
199
  success: El teu compte s'ha eliminat correctament.
200
200
  download_your_data_export:
201
201
  export_expired: L'exportació ha caducat. Intenta generar una nova exportació.
202
+ export_not_found: L'exportació a la qual has accedit no existeix o no tens accés o permisos per descarregar-la
202
203
  file_no_exists: L'arxiu no existeix
203
204
  notice: La descàrrega de les teves dades està en curs. Rebràs un correu electrònic quan estigui completa.
204
205
  email_change:
@@ -1149,6 +1150,7 @@ ca-IT:
1149
1150
  create_with_space: "%{user_name} ha creat %{resource_name} a %{space_name}"
1150
1151
  delete: "%{user_name} ha eliminat %{resource_name}"
1151
1152
  delete_with_space: "%{user_name} ha eliminat %{resource_name} en %{space_name}"
1153
+ publish: "%{user_name} ha publicat %{resource_name}"
1152
1154
  publish_with_space: "%{user_name} ha publicat %{resource_name} en %{space_name}"
1153
1155
  unknown_action: "%{user_name} ha realitzat una acció a %{resource_name}"
1154
1156
  unknown_action_with_space: "%{user_name} ha realitzat una acció a %{resource_name} en %{space_name}"
@@ -2170,8 +2172,8 @@ ca-IT:
2170
2172
  profile: Perfil
2171
2173
  title: Configuració de la participant
2172
2174
  locale:
2173
- name: Català
2174
- name_with_error: Català (error!)
2175
+ name: Alguerés
2176
+ name_with_error: Alguerés (error!)
2175
2177
  number:
2176
2178
  currency:
2177
2179
  format:
@@ -199,6 +199,7 @@ ca:
199
199
  success: El teu compte s'ha eliminat correctament.
200
200
  download_your_data_export:
201
201
  export_expired: L'exportació ha caducat. Intenta generar una nova exportació.
202
+ export_not_found: L'exportació a la qual has accedit no existeix o no tens accés o permisos per descarregar-la
202
203
  file_no_exists: L'arxiu no existeix
203
204
  notice: La descàrrega de les teves dades està en curs. Rebràs un correu electrònic quan estigui completa.
204
205
  email_change:
@@ -1149,6 +1150,7 @@ ca:
1149
1150
  create_with_space: "%{user_name} ha creat %{resource_name} a %{space_name}"
1150
1151
  delete: "%{user_name} ha eliminat %{resource_name}"
1151
1152
  delete_with_space: "%{user_name} ha eliminat %{resource_name} en %{space_name}"
1153
+ publish: "%{user_name} ha publicat %{resource_name}"
1152
1154
  publish_with_space: "%{user_name} ha publicat %{resource_name} en %{space_name}"
1153
1155
  unknown_action: "%{user_name} ha realitzat una acció a %{resource_name}"
1154
1156
  unknown_action_with_space: "%{user_name} ha realitzat una acció a %{resource_name} en %{space_name}"
@@ -686,7 +686,7 @@ de:
686
686
  newsletter_title: Kontakterlaubnis
687
687
  sign_up: Konto erstellen
688
688
  subtitle: Erstellen Sie ein Konto, um auf der Plattform teilzunehmen.
689
- terms: die Nutzungsbedingungen
689
+ terms: den Nutzungsbedingungen
690
690
  tos_agreement: Mit der Anmeldung stimmen Sie %{link} zu.
691
691
  tos_title: Nutzungsbedingungen
692
692
  username_help: Öffentlich sichtbarer Name, der in Ihren Beiträgen angezeigt wird. Um Anonymität zu gewährleisten, kann es sich um einen beliebigen Namen handeln.
@@ -199,6 +199,7 @@ en:
199
199
  success: Your account was successfully deleted.
200
200
  download_your_data_export:
201
201
  export_expired: The export has expired. Try to generate a new export.
202
+ export_not_found: The export you have accessed does not exist, or you do not have access to download it
202
203
  file_no_exists: File does not exist
203
204
  notice: The download of your data is currently in progress. You will receive an email when it is complete.
204
205
  email_change:
@@ -1156,6 +1157,7 @@ en:
1156
1157
  create_with_space: "%{user_name} created %{resource_name} in %{space_name}"
1157
1158
  delete: "%{user_name} deleted %{resource_name}"
1158
1159
  delete_with_space: "%{user_name} deleted %{resource_name} in %{space_name}"
1160
+ publish: "%{user_name} published %{resource_name}"
1159
1161
  publish_with_space: "%{user_name} published %{resource_name} in %{space_name}"
1160
1162
  unknown_action: "%{user_name} performed some action on %{resource_name}"
1161
1163
  unknown_action_with_space: "%{user_name} performed some action on %{resource_name} in %{space_name}"
@@ -199,6 +199,7 @@ es-MX:
199
199
  success: Tu cuenta se ha eliminado correctamente.
200
200
  download_your_data_export:
201
201
  export_expired: La exportación ha caducado. Intenta generar una nueva exportación.
202
+ export_not_found: La exportación a la que has accedido no existe o no tienes acceso o permisos para descargarla
202
203
  file_no_exists: El archivo no existe
203
204
  notice: La descarga de tus datos está en curso. Recibirás un correo electrónico cuando se complete.
204
205
  email_change:
@@ -1152,6 +1153,7 @@ es-MX:
1152
1153
  create_with_space: "%{user_name} creó %{resource_name} en %{space_name}"
1153
1154
  delete: "%{user_name} eliminó %{resource_name}"
1154
1155
  delete_with_space: "%{user_name} eliminó %{resource_name} en %{space_name}"
1156
+ publish: "%{user_name} publicó %{resource_name}"
1155
1157
  publish_with_space: "%{user_name} ha publicado %{resource_name} en %{space_name}"
1156
1158
  unknown_action: "%{user_name} realizó una acción en %{resource_name}"
1157
1159
  unknown_action_with_space: "%{user_name} realizó una acción en %{resource_name} en %{space_name}"
@@ -199,6 +199,7 @@ es-PY:
199
199
  success: Tu cuenta se ha eliminado correctamente.
200
200
  download_your_data_export:
201
201
  export_expired: La exportación ha caducado. Intenta generar una nueva exportación.
202
+ export_not_found: La exportación a la que has accedido no existe o no tienes acceso o permisos para descargarla
202
203
  file_no_exists: El archivo no existe
203
204
  notice: La descarga de tus datos está en curso. Recibirás un correo electrónico cuando se complete.
204
205
  email_change:
@@ -1152,6 +1153,7 @@ es-PY:
1152
1153
  create_with_space: "%{user_name} creó %{resource_name} en %{space_name}"
1153
1154
  delete: "%{user_name} eliminó %{resource_name}"
1154
1155
  delete_with_space: "%{user_name} eliminó %{resource_name} en %{space_name}"
1156
+ publish: "%{user_name} publicó %{resource_name}"
1155
1157
  publish_with_space: "%{user_name} ha publicado %{resource_name} en %{space_name}"
1156
1158
  unknown_action: "%{user_name} realizó una acción en %{resource_name}"
1157
1159
  unknown_action_with_space: "%{user_name} realizó una acción en %{resource_name} en %{space_name}"
@@ -199,6 +199,7 @@ es:
199
199
  success: Tu cuenta se ha eliminado correctamente.
200
200
  download_your_data_export:
201
201
  export_expired: La exportación ha caducado. Intenta generar una nueva exportación.
202
+ export_not_found: La exportación a la que has accedido no existe o no tienes acceso o permisos para descargarla
202
203
  file_no_exists: El archivo no existe
203
204
  notice: La descarga de tus datos está en curso. Recibirás un correo electrónico cuando se complete.
204
205
  email_change:
@@ -1149,6 +1150,7 @@ es:
1149
1150
  create_with_space: "%{user_name} creó %{resource_name} en %{space_name}"
1150
1151
  delete: "%{user_name} eliminó %{resource_name}"
1151
1152
  delete_with_space: "%{user_name} eliminó %{resource_name} en %{space_name}"
1153
+ publish: "%{user_name} publicó %{resource_name}"
1152
1154
  publish_with_space: "%{user_name} ha publicado %{resource_name} en %{space_name}"
1153
1155
  unknown_action: "%{user_name} realizó una acción en %{resource_name}"
1154
1156
  unknown_action_with_space: "%{user_name} realizó una acción en %{resource_name} en %{space_name}"
@@ -199,6 +199,7 @@ eu:
199
199
  success: Zure kontua ezabatu egin da.
200
200
  download_your_data_export:
201
201
  export_expired: Esportazioa amaitu da. Saiatu beste esportazio bat sortzen.
202
+ export_not_found: Sartu zaren esportazioa ez da existitzen, edo ez duzu deskargatzeko aukerarik
202
203
  file_no_exists: Fitxategia ez dago
203
204
  notice: Une honetan zure datuak deskargatzen ari dira. Mezu elektroniko bat jasoko duzu amaitutakoan.
204
205
  email_change:
@@ -414,7 +415,7 @@ eu:
414
415
  heading: Aldaketa berrikustea
415
416
  send: Onartu aldaketa
416
417
  update_draft:
417
- error: Arazoa egon da zuzenketa-zirriborroa eguneratzean.
418
+ error: Arazo bat egon da zuzenketa-zirriborroa eguneratzean.
418
419
  success: Zuzenketa-zirriborroa zuzen eguneratu da.
419
420
  withdraw:
420
421
  error: Arazo bat izan da zuzenketa kentzean.
@@ -671,7 +672,7 @@ eu:
671
672
  nickname_help: Zure ezizena %{organization}-an. Letrak, zenbakiak, '-' eta '_' soilik eduki ditzake.
672
673
  sign_up: Mesedez, osatu zure profila
673
674
  subtitle: Mesedez, bete hurrengo formularioa kontua sortzen amaitzeko
674
- username_help: Zure mezuetan agertuko den izen publikoa. Anonimatua bermatze aldera, edozein izen izan daiteke.
675
+ username_help: Zure mezuetan agertzen den izen publikoa. Anonimotasuna bermatzeko helburuarekin, edozein izen izan daiteke.
675
676
  new_tos_fields:
676
677
  sign_up: Sortu kontu bat
677
678
  sign_up_title: Zure kontua sortzen amaitu
@@ -688,7 +689,7 @@ eu:
688
689
  terms: zerbitzuaren baldintzak
689
690
  tos_agreement: 'Erregistratzean, hau onartzen duzu: %{link}.'
690
691
  tos_title: Zerbitzuaren baldintzak
691
- username_help: Zure mezuetan agertuko den izen publikoa. Anonimatua bermatze aldera, edozein izen izan daiteke.
692
+ username_help: Zure mezuetan agertzen den izen publikoa. Anonimotasuna bermatzeko helburuarekin, edozein izen izan daiteke.
692
693
  sessions:
693
694
  new:
694
695
  are_you_new?: Oraindik erregistratu gabe?
@@ -725,7 +726,7 @@ eu:
725
726
  doorkeeper:
726
727
  authorizations:
727
728
  new:
728
- api_read: Irakurri edukia APIren bitartez
729
+ api_read: APIren bitartez edukia irakurri
729
730
  authorize: Aplikazioa baimentzen du
730
731
  by_organization_link_html: '%{link} bidez'
731
732
  cancel: Ezeztatu
@@ -823,7 +824,7 @@ eu:
823
824
  reset_password_sent_at: Zein datatan eta zein ordutan bidali zen pasahitza berriro
824
825
  roles: Parte-hartzaile honek duen rola, baldin badute
825
826
  sign_in_count: Zenbat aldiz hasi duen saioa parte-hartzaile honek
826
- type: Parte-hartzaile honek zer mota duen
827
+ type: Erabiltzaile honek dituen aukerak
827
828
  unconfirmed_email: Parte-hartzaile honek oraindik baieztatu ez duen helbide elektronikoa
828
829
  updated_at: Zein datatan eta zein ordutan eguneratu zen parte-hartzaile hau azken aldiz
829
830
  show:
@@ -908,12 +909,12 @@ eu:
908
909
  affected_user:
909
910
  email_intro: '%{amendable_title} k zuzenketa ukatu egin du. Orrialde honetan ikus dezakezu:'
910
911
  email_outro: 'Jakinarazpen hau jaso duzu honen egilea zarelako: %{amendable_title}.'
911
- email_subject: Aldaketa %{amendable_title} %{emendation_author_nickname} k ukatua
912
+ email_subject: Aldaketa %{amendable_title} %{emendation_author_nickname} egileak ukatua
912
913
  notification_title: <a href="%{emendation_author_path}">%{emendation_author_nickname}</a> k egindako <a href="%{emendation_path}">zuzenketa <a href="%{amendable_path}">%{amendable_title}</a> k ukatu du.
913
914
  follower:
914
915
  email_intro: 'Aldaketa ukatu egin da %{amendable_title}. Orrialde honetatik ikus dezakezu:'
915
916
  email_outro: Jakinarazpen hau jaso duzu %{amendable_title} jarraitzen duzulako. Aurreko estekan jakinarazpenak jasotzeari utzi ahal diozu.
916
- email_subject: '%{emendation_author_nickname} k baztertu du %{amendable_title} aldaketa'
917
+ email_subject: '%{emendation_author_nickname} egileak baztertu du %{amendable_title} aldaketa'
917
918
  notification_title: <a href="%{emendation_author_path}">%{emendation_author_nickname}</a> k sortutako <a href="%{emendation_path}">zuzenketa </a> <a href="%{amendable_path}">%{amendable_title}</a> k ukatu du.
918
919
  emendation_promoted:
919
920
  follower:
@@ -970,9 +971,9 @@ eu:
970
971
  notification_title: |-
971
972
  Administratzaile batek zure %{resource_type} ezabatu du salatua izan delako arrazoi honengatik %{report_reasons}.</br><i>%{resource_content}</i>
972
973
  resource_liked:
973
- email_intro: '%{liker_name} %{liker_nickname} -k, zu jarraitzen ari zarenak, "%{resource_title}" atsegin du eta uste dugu interesatu ahal zaizula. Egiaztatu eta lagundu:'
974
+ email_intro: '%{liker_name} %{liker_nickname}, jarraitzen ari zaren horri "%{resource_title}" gustatu zaio, eta zuretzat interesgarria izan daitekeela uste dugu. Kontsultatu eta ekarri:'
974
975
  email_outro: Jakinarazpen hau jaso duzu %{liker_nickname} jarraitzen duzulako. Ondorengo estekan sartu jakinarazpenak jasotzeari uzteko.
975
- email_subject: "%{liker_nickname} -k beste bat atsegin du"
976
+ email_subject: "%{liker_nickname}(e) k like berri bat egin du"
976
977
  notification_title: <a href="%{liker_path}">%{liker_name} %{liker_nickname}</a> -k <a href="%{resource_path}">%{resource_title}</a> %{resource_type} ategin du.
977
978
  resources:
978
979
  soft_deleted:
@@ -1085,7 +1086,7 @@ eu:
1085
1086
  dropzone: Bota fitxategiak hona edo egin klik igotzeko
1086
1087
  explanation: Gida honetarako %{attribute}
1087
1088
  gamification:
1088
- all_badges_link: Ikusi eskuragarri dauden txapak.
1089
+ all_badges_link: Ikusi eskuragarri dauden bereizgarri guztiak.
1089
1090
  badges:
1090
1091
  followers:
1091
1092
  conditions:
@@ -1150,6 +1151,7 @@ eu:
1150
1151
  create_with_space: "%{user_name} sortu %{resource_name} en %{space_name}"
1151
1152
  delete: "%{user_name} parte-hartzaileak %{resource_name} ezabatu du"
1152
1153
  delete_with_space: "%{user_name} parte-hartzaileak %{resource_name} ezabatu du %{space_name} espazioan"
1154
+ publish: "%{user_name} parte-hartzaileak %{resource_name} argitaratu du"
1153
1155
  publish_with_space: "%{user_name} parte-hartzaileak %{resource_name} argitaratu du %{space_name} espazioan"
1154
1156
  unknown_action: "%{user_name} parte-hartzaileak ekintza batzuk egin ditu %{resource_name} ean"
1155
1157
  unknown_action_with_space: "%{user_name} parte-hartzaileak ekintza batzuk egin ditu %{resource_name} ean %{space_name} espazioan"
@@ -1392,7 +1394,7 @@ eu:
1392
1394
  name: Taxonomia honen izena
1393
1395
  parent_id: Taxonomia nagusi honen identifikatzaile bakarrak (baldin badago)
1394
1396
  part_of: Taxonomia hau beste taxonomia baten parte den jakiteko erabiltzen da
1395
- taxonomizations_count: Taxonomia hau erabiltzen duten baliabideen zenbaketa
1397
+ taxonomizations_count: Taxonomia hori erabiltzen duten baliabideen zenbaketa
1396
1398
  updated_at: Zein datatan eguneratu zen taxonomia hau azkenekoz
1397
1399
  weight: Zein ordenatan erakusten den taxonomia hau
1398
1400
  users:
@@ -1726,18 +1728,27 @@ eu:
1726
1728
  greeting: "%{name}, agurgarria:\n"
1727
1729
  instructions_1: Sarbidea baduzu posta elektronikoko kontu horretarako, mesedez, kontsultatu zure sarrera-erretilua argibideetarako.
1728
1730
  instructions_2: Horrela ez bada, zure lankideetako batek, pasahitza duenak, jarri beharko du eta kredentzialak zurekin partekatu.
1731
+ instructions_intro: Taldeko kideek profil horretarako sarbidea partekatuko dute orain, saio-hasierako egiaztagiri partekatuak erabiliz (posta elektronikoa eta pasahitza). %{email}(e) ra jarraibideak bidali ditugu profilaren pasahitz berria ezartzeko.
1732
+ instructions_title: "<strong>Zer esan nahi du horrek zuretzat</strong>"
1733
+ subject: Taldearen profilari dagokionez, eguneraketa garrantzitsua
1729
1734
  notify_deprecation_to_owner:
1730
1735
  body_1: '%{organization_name} (e) n duzun taldearen profilari buruzko eguneraketa garrantzitsu baten berri ematera gatozkizu.'
1731
1736
  body_2: 'Zurea bezalako erakundeen esperientzia sinplifikatzeko gure ahaleginen zati gisa, orain arte ezagutzen dugun "Erabiltzaile Taldeak" funtzioa zaharkituta geratuko da. Taldearen profila: <strong>%{name}</strong>, ohiko parte-hartzailearen profil bihurtu da.'
1737
+ body_3: Zure kontuan sartzen jarraitzeko eta sarbidea partekatzeko, pasahitz bat ezartzea behar dugu. Behin ezarrita, saioa hasteko kredentzialak (posta elektronikoa eta pasahitza) edozeinekin parteka ditzakezu.
1732
1738
  greeting: '%{name}, agurgarria:'
1739
+ instructions_1: 'Egin klik beheko estekan zure pasahitza ezartzeko:'
1740
+ instructions_2: 'Partekatu saioa hasteko kredentzialak (posta elektronikoa: %{email} eta pasahitz berria) zure lankideekin.'
1741
+ instructions_title: "<strong>Egin beharrekoa</strong>"
1742
+ set_password: Idatzi zure pasahitza
1743
+ subject: Zure taldearen profilari buruzko eguneratze garrantzitsua
1733
1744
  notify_user_group_patched:
1734
1745
  body_1_html: 'Zure taldearen profilari buruzko eguneratze garrantzitsu baten berri emango dizugu hemen: %{organization_name}.'
1735
1746
  body_2_html: 'Zurea bezalako erakundeen esperientzia sinplifikatzeko gure ahaleginen zati gisa, orain arte ezagutzen dugun "Erabiltzaile Taldeak" funtzioa zaharkituta geratuko da. Taldearen profila: <strong>%{name}</strong>, ohiko parte-hartzailearen profil bihurtu da.'
1736
1747
  body_3_html: Zure kontuan sartzen jarraitzeko eta sarbidea partekatzeko, mezu elektroniko eta pasahitz berri bat ezar ditzazun behar dugu. Mesedez, kontuan izan zure taldeko kide bakoitzak mezu hau jasoko duela. Sarbide jarraitua bermatzeko, denek erabiliko dituzten kredentzial partekatuak (posta elektronikoa eta pasahitza) adostu beharko dituzu.
1737
1748
  greeting: '%{name}, agurgarria:'
1738
1749
  instructions_1_html: 'Erabili behin-behineko kredentzial hauek saioa hasteko: <br><br> Erabiltzailea: <strong>% {email}</strong> <br> Pasahitza: <strong>% {password}</strong> <br><br>'
1739
- instructions_2_html: Jarri helbide elektroniko berria eta pasahitza.
1740
- instructions_3_html: Partekatu zure lankideekin aukeratutako sarrera-kredentzialak, talde osoak kontura sartzen jarraitu ahal izateko.
1750
+ instructions_2_html: Helbide elektroniko berria eta pasahitza jarri.
1751
+ instructions_3_html: Zure lankideekin aukeratutako sarrera-kredentzialak partekatu, talde osoak kontura sartzen jarraitu ahal izateko.
1741
1752
  instructions_title_html: "<strong>Zer egin behar duzu?</strong>"
1742
1753
  subject: Zure taldearen profilari buruzko eguneratze garrantzitsua
1743
1754
  user_report_mailer:
@@ -1850,7 +1861,7 @@ eu:
1850
1861
  reset_password_instructions:
1851
1862
  action: Nire pasahitza aldatu
1852
1863
  greeting: Kaixo %{recipient}!
1853
- instruction: Norbaitek zure pasahitza aldatzeko esteka eskatu du, eta beheko estekan egin dezakezu.
1864
+ instruction: Norbaitek esteka bat eskatu du zure pasahitza aldatzeko, eta beheko estekaren bidez egin dezakezu.
1854
1865
  instruction_2: Ez baduzu hori eskatu, ez egin kasurik mezu honi.
1855
1866
  instruction_3: Zure pasahitza ez da aldatuko aurreko estekara sartu eta beste bat sortu arte.
1856
1867
  subject: Berrezarri pasahitzaren argibideak
@@ -2019,7 +2030,7 @@ eu:
2019
2030
  long_words: luzeegiak diren hitzak ditu (35 karaktere baino gehiago)
2020
2031
  must_start_with_caps: letra larriz hasi behartu
2021
2032
  nesting_too_deep: ezin da egon azpikategoria batean
2022
- not_found: ezin izan da aurkitu. Lehenago konturik sortu duzu?
2033
+ not_found: ezin izan da aurkitu. Aurretik kontu bat sortu duzu?
2023
2034
  not_locked: ez dago itxita
2024
2035
  not_saved:
2025
2036
  one: 'Errore bat izan da zure eskaera prozesatzean:'
@@ -1151,6 +1151,7 @@ fi-pl:
1151
1151
  create_with_space: "%{user_name} loi %{resource_name} tilassa %{space_name}"
1152
1152
  delete: "%{user_name} poisti %{resource_name}"
1153
1153
  delete_with_space: "%{user_name} poisti %{resource_name} tilassa %{space_name}"
1154
+ publish: "%{user_name} julkaisi kohteen %{resource_name}"
1154
1155
  publish_with_space: "%{user_name} julkaisi %{resource_name} osallistumistilassa %{space_name}"
1155
1156
  unknown_action: "%{user_name} suoritti toimenpiteen koskien kohdetta %{resource_name}"
1156
1157
  unknown_action_with_space: "%{user_name} suoritti toimenpiteen koskien kohdetta %{resource_name} tilassa %{space_name}"
@@ -1740,6 +1741,16 @@ fi-pl:
1740
1741
  instructions_title: "<strong>Mitä sinun tulee tehdä</strong>"
1741
1742
  set_password: Määritä salasana
1742
1743
  subject: Tärkeä ryhmäprofiilia koskeva päivitys
1744
+ notify_user_group_patched:
1745
+ body_1_html: Tämä viesti koskee tärkeää päivitystä käyttäjäryhmät-toiminnossa palvelussa %{organization_name}.
1746
+ body_2_html: Yksinkertaistaaksemme organisaatioiden kokemusta tällä alustalla, käyttäjäryhmät poistetaan alustalta. Käyttäjäryhmäsi <strong>%{name}</strong> profiili on nyt muutettu tavalliseksi osallistujaprofiiliksi.
1747
+ body_3_html: Jatkaaksesi ryhmätilisi käyttöä, sinun tulee asettaa sille sähköpostiosoite ja salasana. Huomioithan, että jokainen ryhmäsi jäsen saa tämän sähköpostiviestin. Mikäli haluat jatkaa tilin käyttöä, yhden ryhmän jäsenen tulee jatkossa hallinnoida tiliä ryhmän sähköpostiosoitteella ja hänen asettamallaan salasanalla.
1748
+ greeting: Hei %{name},
1749
+ instructions_1_html: 'Käytä seuraavia väliaikaisia tunnuksia kirjautuaksesi sisään: <br><br> Sähköpostiosoite: <strong>%{email}</strong> <br> Salasana <strong>%{password}</strong><br><br>'
1750
+ instructions_2_html: Aseta uusi sähköpostiosoite ja salasana.
1751
+ instructions_3_html: Älä jaa näitä tunnuksia kenenkään kanssa. Ainoastaan ryhmän hallinnoija voi jatkossa kirjautua palveluun tällä tilillä.
1752
+ instructions_title_html: "<strong>Mitä sinun täytyy tehdä?</strong>"
1753
+ subject: Tärkeä ryhmäprofiilia koskeva päivitys
1743
1754
  user_report_mailer:
1744
1755
  notify:
1745
1756
  body_1: Käyttäjä %{user} on ilmoitettu käyttäjän %{token} toimesta
@@ -1151,6 +1151,7 @@ fi:
1151
1151
  create_with_space: "%{user_name} loi %{resource_name} osallistumistilassa %{space_name}"
1152
1152
  delete: "%{user_name} poisti %{resource_name}"
1153
1153
  delete_with_space: "%{user_name} poisti %{resource_name} osallistumistilassa %{space_name}"
1154
+ publish: "%{user_name} julkaisi kohteen %{resource_name}"
1154
1155
  publish_with_space: "%{user_name} julkaisi %{resource_name} osallistumistilassa %{space_name}"
1155
1156
  unknown_action: "%{user_name} suoritti toimenpiteen koskien kohdetta %{resource_name}"
1156
1157
  unknown_action_with_space: "%{user_name} suoritti toimenpiteen koskien kohdetta %{resource_name} osallistumistilassa %{space_name}"
@@ -1740,6 +1741,16 @@ fi:
1740
1741
  instructions_title: "<strong>Mitä sinun tulee tehdä</strong>"
1741
1742
  set_password: Määritä salasana
1742
1743
  subject: Tärkeä ryhmäprofiilia koskeva päivitys
1744
+ notify_user_group_patched:
1745
+ body_1_html: Tämä viesti koskee tärkeää päivitystä käyttäjäryhmät-toiminnossa palvelussa %{organization_name}.
1746
+ body_2_html: Yksinkertaistaaksemme organisaatioiden kokemusta tällä alustalla, käyttäjäryhmät poistetaan alustalta. Käyttäjäryhmäsi <strong>%{name}</strong> profiili on nyt muutettu tavalliseksi osallistujaprofiiliksi.
1747
+ body_3_html: Jatkaaksesi ryhmätilisi käyttöä, sinun tulee asettaa sille sähköpostiosoite ja salasana. Huomioithan, että jokainen ryhmäsi jäsen saa tämän sähköpostiviestin. Mikäli haluat jatkaa tilin käyttöä, yhden ryhmän jäsenen tulee jatkossa hallinnoida tiliä ryhmän sähköpostiosoitteella ja hänen asettamallaan salasanalla.
1748
+ greeting: Hei %{name},
1749
+ instructions_1_html: 'Käytä seuraavia väliaikaisia tunnuksia kirjautuaksesi sisään: <br><br> Sähköpostiosoite: <strong>%{email}</strong> <br> Salasana <strong>%{password}</strong><br><br>'
1750
+ instructions_2_html: Aseta uusi sähköpostiosoite ja salasana.
1751
+ instructions_3_html: Älä jaa näitä tunnuksia kenenkään kanssa. Ainoastaan ryhmän hallinnoija voi jatkossa kirjautua palveluun tällä tilillä.
1752
+ instructions_title_html: "<strong>Mitä sinun täytyy tehdä?</strong>"
1753
+ subject: Tärkeä ryhmäprofiilia koskeva päivitys
1743
1754
  user_report_mailer:
1744
1755
  notify:
1745
1756
  body_1: Käyttäjä %{user} on ilmoitettu käyttäjän %{token} toimesta
@@ -184,6 +184,7 @@ fr-CA:
184
184
  success: Votre compte a été supprimé avec succès.
185
185
  download_your_data_export:
186
186
  export_expired: L'export a expiré. Essayez de générer un nouvel export.
187
+ export_not_found: L'export auquel vous avez tenté d'accéder n'existe pas, ou vous n'avez pas l'accès pour le télécharger
187
188
  file_no_exists: Le fichier n'existe pas
188
189
  notice: Le téléchargement de vos données est en cours. Vous recevrez un email lorsque celui-ci sera terminé.
189
190
  email_change:
@@ -1024,6 +1025,7 @@ fr-CA:
1024
1025
  create_with_space: "%{user_name} a créé %{resource_name} dans %{space_name}"
1025
1026
  delete: "%{user_name} a supprimé %{resource_name}"
1026
1027
  delete_with_space: "%{user_name} a supprimé %{resource_name} dans %{space_name}"
1028
+ publish: "%{user_name} a publié %{resource_name}"
1027
1029
  publish_with_space: "%{user_name} a publié %{resource_name} dans %{space_name}"
1028
1030
  unknown_action: "%{user_name} a effectué une action sur %{resource_name}"
1029
1031
  unknown_action_with_space: "%{user_name} a effectué une action sur %{resource_name} dans %{space_name}"
@@ -1054,7 +1056,7 @@ fr-CA:
1054
1056
  latlng_text: 'latitude : %{latitude}, longitude : %{longitude}'
1055
1057
  map_service_brand: OpenStreetMap
1056
1058
  menu:
1057
- help: Aide
1059
+ help: Aidez-moi
1058
1060
  home: Accueil
1059
1061
  messaging:
1060
1062
  conversation_mailer:
@@ -1576,6 +1578,16 @@ fr-CA:
1576
1578
  instructions_title: "<strong>Ce que vous devez faire</strong>"
1577
1579
  set_password: Définissez votre mot de passe
1578
1580
  subject: Mise à jour importante concernant votre profil de groupe
1581
+ notify_user_group_patched:
1582
+ body_1_html: Nous vous contactons pour vous informer d’une mise à jour importante concernant votre profil de groupe sur %{organization_name}.
1583
+ body_2_html: Dans le cadre de nos efforts pour simplifier et améliorer l'expérience des organisations comme la vôtre, nous déprécions la fonctionnalité "Groupes d'utilisateurs". Votre groupe, <strong>%{name}</strong>a été converti en simple compte.
1584
+ body_3_html: Pour continuer à accéder à votre compte et partager votre accès, nous avons besoin que vous définissiez une nouvelle adresse e-mail et un nouveau mot de passe. Veuillez noter que chaque membre de votre groupe recevra ce courriel. Pour assurer la continuité de l'accès, vous devrez convenir en interne des identifiants partagés (adresse e-mail et mot de passe) que tout le monde utilisera.
1585
+ greeting: Cher(ère) %{name},
1586
+ instructions_1_html: 'Utilisez les identifiants temporaires suivants pour vous connecter : <br><br> Nom d''utilisateur : <strong>%{email}</strong> <br> Mot de passe : <strong>%{password}</strong><br><br>'
1587
+ instructions_2_html: Définir une nouvelle adresse e-mail et un nouveau mot de passe.
1588
+ instructions_3_html: Partagez les identifiants de connexion choisis avec vos collègues pour que l'ensemble du groupe puisse continuer à accéder au compte.
1589
+ instructions_title_html: "<strong>Ce que vous devez faire</strong>"
1590
+ subject: Mise à jour importante concernant votre profil de groupe
1579
1591
  user_report_mailer:
1580
1592
  notify:
1581
1593
  body_1: L'utilisateur %{user} a été signalé par %{token}
@@ -184,6 +184,7 @@ fr:
184
184
  success: Votre compte a été supprimé avec succès.
185
185
  download_your_data_export:
186
186
  export_expired: L'export a expiré. Essayez de générer un nouvel export.
187
+ export_not_found: L'export auquel vous avez tenté d'accéder n'existe pas, ou vous n'avez pas l'accès pour le télécharger
187
188
  file_no_exists: Le fichier n'existe pas
188
189
  notice: Le téléchargement de vos données est en cours. Vous recevrez un email lorsque celui-ci sera terminé.
189
190
  email_change:
@@ -1024,6 +1025,7 @@ fr:
1024
1025
  create_with_space: "%{user_name} a créé %{resource_name} dans %{space_name}"
1025
1026
  delete: "%{user_name} a supprimé %{resource_name}"
1026
1027
  delete_with_space: "%{user_name} a supprimé %{resource_name} dans %{space_name}"
1028
+ publish: "%{user_name} a publié %{resource_name}"
1027
1029
  publish_with_space: "%{user_name} a publié %{resource_name} dans %{space_name}"
1028
1030
  unknown_action: "%{user_name} a effectué une action sur %{resource_name}"
1029
1031
  unknown_action_with_space: "%{user_name} a effectué une action sur %{resource_name} dans %{space_name}"
@@ -1054,7 +1056,7 @@ fr:
1054
1056
  latlng_text: 'latitude : %{latitude}, longitude : %{longitude}'
1055
1057
  map_service_brand: OpenStreetMap
1056
1058
  menu:
1057
- help: Aide
1059
+ help: Aidez-moi
1058
1060
  home: Accueil
1059
1061
  messaging:
1060
1062
  conversation_mailer:
@@ -1576,6 +1578,16 @@ fr:
1576
1578
  instructions_title: "<strong>Ce que vous devez faire</strong>"
1577
1579
  set_password: Définissez votre mot de passe
1578
1580
  subject: Mise à jour importante concernant votre profil de groupe
1581
+ notify_user_group_patched:
1582
+ body_1_html: Nous vous contactons pour vous informer d’une mise à jour importante concernant votre profil de groupe sur %{organization_name}.
1583
+ body_2_html: Dans le cadre de nos efforts pour simplifier et améliorer l'expérience des organisations comme la vôtre, nous déprécions la fonctionnalité "Groupes d'utilisateurs". Votre groupe, <strong>%{name}</strong>a été converti en simple compte.
1584
+ body_3_html: Pour continuer à accéder à votre compte et partager votre accès, nous avons besoin que vous définissiez une nouvelle adresse e-mail et un nouveau mot de passe. Veuillez noter que chaque membre de votre groupe recevra ce courriel. Pour assurer la continuité de l'accès, vous devrez convenir en interne des identifiants partagés (adresse e-mail et mot de passe) que tout le monde utilisera.
1585
+ greeting: Cher(ère) %{name},
1586
+ instructions_1_html: 'Utilisez les identifiants temporaires suivants pour vous connecter : <br><br> Nom d''utilisateur : <strong>%{email}</strong> <br> Mot de passe : <strong>%{password}</strong><br><br>'
1587
+ instructions_2_html: Définir une nouvelle adresse e-mail et un nouveau mot de passe.
1588
+ instructions_3_html: Partagez les identifiants de connexion choisis avec vos collègues pour que l'ensemble du groupe puisse continuer à accéder au compte.
1589
+ instructions_title_html: "<strong>Ce que vous devez faire</strong>"
1590
+ subject: Mise à jour importante concernant votre profil de groupe
1579
1591
  user_report_mailer:
1580
1592
  notify:
1581
1593
  body_1: L'utilisateur %{user} a été signalé par %{token}
@@ -454,6 +454,8 @@ it:
454
454
  description: Descrisione
455
455
  footer_sub_hero:
456
456
  name: Banner di sub eroe di piè di pagina
457
+ global_menu:
458
+ name: Menu globale
457
459
  hero_settings_form:
458
460
  background_image: Immagine di sfondo
459
461
  welcome_text: Testo di benvenuto
@@ -186,6 +186,7 @@ ja:
186
186
  success: アカウントが正常に削除されました。
187
187
  download_your_data_export:
188
188
  export_expired: エクスポートの有効期限が切れています。新しいエクスポートを生成してください。
189
+ export_not_found: アクセスしたエクスポートが存在しないか、ダウンロードする権限がありません
189
190
  file_no_exists: ファイルが存在しません
190
191
  notice: データのダウンロードは現在進行中です。完了した際にはメールでお知らせします。
191
192
  email_change:
@@ -1133,6 +1134,7 @@ ja:
1133
1134
  create_with_space: "%{user_name} が %{resource_name} に %{space_name} を作成しました"
1134
1135
  delete: "%{user_name} が %{resource_name} を削除しました"
1135
1136
  delete_with_space: "%{user_name} が %{resource_name} で %{space_name} を削除しました"
1137
+ publish: "%{user_name} が %{resource_name}を公開しました"
1136
1138
  publish_with_space: "%{user_name} が %{space_name} の %{resource_name} を公開しました"
1137
1139
  unknown_action: "%{user_name} が %{resource_name} にいくつかのアクションを実行しました"
1138
1140
  unknown_action_with_space: "%{user_name} が %{resource_name} で %{space_name} にアクションを実行しました"
@@ -1706,10 +1708,30 @@ ja:
1706
1708
  body_2: 組織向けの利用体験を簡素化する取り組みの一環として、「ユーザーグループ」機能は廃止される予定です。あなたのユーザーグループのプロフィールは通常の参加者プロフィールに変更されました。
1707
1709
  greeting: こんにちは %{name} さん、
1708
1710
  instructions_1: そのメールアカウントにアクセスできる場合は、受信トレイに届いている案内をご確認ください。
1711
+ instructions_2: そうでない場合は、アクセス権を持つ同僚の一人がパスワードを設定し、ログイン情報をあなたと共有する必要があります。
1712
+ instructions_intro: グループメンバーは、共有ログインクレデンシャル(メールアドレスとパスワード)を使用して、このプロファイルへのアクセスを共有するようになりました。 プロファイルの新しいパスワードを設定するための指示を %{email} に送信しました。
1713
+ instructions_title: "<strong>あなたへの影響</strong>"
1714
+ subject: グループプロフィールに関する重要な更新情報
1709
1715
  notify_deprecation_to_owner:
1710
1716
  body_1: '%{organization_name}でのグループプロフィールに関する重要なアップデートについてお知らせするためにご連絡しています。'
1711
1717
  body_2: あなたのような組織向けの利用体験を簡素化・改善する取り組みの一環として、「ユーザーグループ」機能は廃止されます。あなたのグループ<strong>%{name}</strong>は通常のアカウントに変更されました。
1718
+ body_3: 引き続きアカウントへアクセスしてアクセス権限を共有するためには、パスワードを設定する必要があります。設定後、ログイン認証情報(メールアドレスとパスワード)を任意の相手と共有することが可能になります。
1712
1719
  greeting: こんにちは %{name} さん、
1720
+ instructions_1: '以下のリンクをクリックしてパスワードを設定してください:'
1721
+ instructions_2: 'ログイン認証情報(メールアドレス:%{email}、新規パスワード)を同僚と共有してください。'
1722
+ instructions_title: "<strong>実施すべきこと</strong>"
1723
+ set_password: パスワードの設定
1724
+ subject: グループプロフィールに関する重要な更新事項
1725
+ notify_user_group_patched:
1726
+ body_1_html: '%{organization_name}におけるグループプロフィールに関する重要な更新についてお知らせします。'
1727
+ body_2_html: 組織の利便性向上とシステムの簡素化を図るため、「ユーザーグループ」機能の廃止を決定いたしました。あなたのグループ <strong>%{name}</strong> は、通常のアカウント形式に変更されています。
1728
+ body_3_html: 引き続きアカウントにアクセスしてアクセス権限を共有するためには、新しいメールアドレスとパスワードの設定が必要です。なお、グループの各メンバーにはこのメールが送信されます。継続的なアクセスを保証するため、共有する認証情報(メールアドレスとパスワード)について、グループ内で事前に合意していただく必要があります。
1729
+ greeting: こんにちは %{name} さん、
1730
+ instructions_1_html: '以下の仮認証情報を使用してログインしてください:<br><br> ユーザー名: <strong>%{email}</strong> <br> パスワード: <strong>%{password}</strong><br><br>'
1731
+ instructions_2_html: 新しいメールアドレスとパスワードを設定します。
1732
+ instructions_3_html: 選択したログイン認証情報を同僚の方々と共有し、グループ全体で引き続きアカウントにアクセスできるようにしてください。
1733
+ instructions_title_html: "<strong>実施が必要な事項</strong>"
1734
+ subject: グループプロフィールに関する重要なお知らせ
1713
1735
  user_report_mailer:
1714
1736
  notify:
1715
1737
  body_1: ユーザー %{user} が %{token} によって報告されました
@@ -378,7 +378,6 @@ ru:
378
378
  managed_users:
379
379
  expired_session: Текущий сеанс выступления в роли участника истек.
380
380
  menu:
381
- help: Справка
382
381
  home: Главная
383
382
  messaging:
384
383
  conversation_mailer:
@@ -16,7 +16,6 @@ sl:
16
16
  linked_classes:
17
17
  meeting: Sestanki
18
18
  menu:
19
- help: Pomoč
20
19
  home: Domov
21
20
  messaging:
22
21
  conversations:
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddDummyMigration < ActiveRecord::Migration[7.2]
4
+ def up
5
+ # This migration is not doing anything. It is just here as a mere placeholder.
6
+ end
7
+
8
+ def down
9
+ raise ActiveRecord::IrreversibleMigration
10
+ end
11
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This migration comes from decidim (originally 20250819110800)
4
+ class ConvertPrivateExportsIdToUuid < ActiveRecord::Migration[7.0]
5
+ def up
6
+ create_table :decidim_private_exports_new, force: :cascade do |t|
7
+ t.uuid :uuid, null: false
8
+ t.string :export_type, null: false
9
+ t.string :attached_to_type
10
+ t.integer :attached_to_id
11
+ t.string :file
12
+ t.string :content_type, null: false
13
+ t.string :file_size, null: false
14
+ t.datetime :expires_at
15
+ t.jsonb :metadata, default: {}
16
+ t.timestamps
17
+
18
+ t.index [:uuid], name: "index_decidim_private_exports_on_uuid", unique: true
19
+ end
20
+ # Copy data from old table to new table
21
+ execute <<-SQL.squish
22
+ INSERT INTO decidim_private_exports_new (uuid, export_type, attached_to_type, attached_to_id, file, content_type, file_size, expires_at, metadata, created_at, updated_at)
23
+ SELECT id, export_type, attached_to_type, attached_to_id, file, content_type, file_size, NOW(), metadata, created_at, updated_at
24
+ FROM decidim_private_exports
25
+ SQL
26
+
27
+ # Drop old table and rename new table
28
+ drop_table :decidim_private_exports
29
+ rename_table :decidim_private_exports_new, :decidim_private_exports
30
+ end
31
+
32
+ def down
33
+ # Similar approach for rollback
34
+ create_table :decidim_private_exports_new, id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
35
+ t.string :export_type, null: false
36
+ t.string :attached_to_type
37
+ t.integer :attached_to_id
38
+ t.string :file
39
+ t.string :content_type, null: false
40
+ t.string :file_size, null: false
41
+ t.datetime :expires_at
42
+ t.jsonb :metadata, default: {}
43
+ t.timestamps
44
+ end
45
+
46
+ execute <<-SQL.squish
47
+ INSERT INTO decidim_private_exports_new (id, export_type, attached_to_type, attached_to_id, file, content_type, file_size, expires_at, metadata, created_at, updated_at)
48
+ SELECT uuid, export_type, attached_to_type, attached_to_id, file, content_type, file_size, expires_at, metadata, created_at, updated_at
49
+ FROM decidim_private_exports
50
+ SQL
51
+
52
+ drop_table :decidim_private_exports
53
+ rename_table :decidim_private_exports_new, :decidim_private_exports
54
+ end
55
+ end
data/decidim-core.gemspec CHANGED
@@ -41,6 +41,7 @@ Gem::Specification.new do |s|
41
41
  s.add_dependency "cells-rails", "~> 0.1.3"
42
42
  s.add_dependency "charlock_holmes", "~> 0.7"
43
43
  s.add_dependency "chartkick", "~> 5.1.2"
44
+ s.add_dependency "data_migrate", "~> 11.3"
44
45
  s.add_dependency "date_validator", "~> 0.12.0"
45
46
  s.add_dependency "devise", "~> 4.7"
46
47
  s.add_dependency "devise-i18n", "~> 1.2"
@@ -38,6 +38,7 @@ require "ransack"
38
38
  require "wisper"
39
39
  require "chartkick"
40
40
  require "shakapacker"
41
+ require "data_migrate"
41
42
 
42
43
  require "decidim/api"
43
44
  require "decidim/core/content_blocks/registry_manager"
@@ -229,6 +230,13 @@ module Decidim
229
230
  Decidim.icons.register(name: "facebook-circle-line", icon: "facebook-circle-line", category: "social icon", description: "", engine: :core)
230
231
  end
231
232
 
233
+ initializer "decidim_core.data_migrate" do |app|
234
+ DataMigrate.configure do |config|
235
+ config.data_migrations_path = [app.root.join("db/data").to_s]
236
+ config.data_migrations_path << root.join("db/data").to_s
237
+ end
238
+ end
239
+
232
240
  initializer "decidim_core.patch_shakapacker", before: "shakapacker.version_checker" do
233
241
  ENV["SHAKAPACKER_CONFIG"] = Decidim::Shakapacker.configuration.configuration_file
234
242
  end
@@ -488,6 +496,7 @@ module Decidim
488
496
  end
489
497
 
490
498
  initializer "decidim_core.add_cells_view_paths" do
499
+ Cell::ViewModel.view_paths << Rails.root.join("app/views") # for partials
491
500
  Cell::ViewModel.view_paths << File.expand_path("#{Decidim::Core::Engine.root}/app/cells")
492
501
  Cell::ViewModel.view_paths << File.expand_path("#{Decidim::Core::Engine.root}/app/cells/amendable")
493
502
  Cell::ViewModel.view_paths << File.expand_path("#{Decidim::Core::Engine.root}/app/views") # for partials
@@ -871,9 +871,14 @@ FactoryBot.define do
871
871
  end
872
872
  expires_at { 1.week.from_now }
873
873
  attached_to { create(:user, organization:, skip_injection:) }
874
- export_type { "dummy" }
874
+ export_type { "download_your_data" }
875
875
  content_type { "application/zip" }
876
- file_size { 10.kilobytes }
876
+ file_size { 208.bytes }
877
+ file { Decidim::Dev.test_file("dummy-export.zip", "application/zip") }
878
+
879
+ trait :expired do
880
+ expires_at { 1.week.ago }
881
+ end
877
882
  end
878
883
 
879
884
  factory :searchable_resource, class: "Decidim::SearchableResource" do
@@ -873,6 +873,30 @@ shared_examples "comments" do
873
873
  expect(page.find("#comment-#{parent.id}-replies").text).to be_blank
874
874
  end
875
875
  end
876
+
877
+ context "when admin moderates the comment" do
878
+ let!(:user) { create(:user, :admin, :confirmed, organization:) }
879
+
880
+ before do
881
+ switch_to_host(organization.host)
882
+ login_as user, scope: :user
883
+ visit resource_path
884
+ end
885
+
886
+ it "hides the comment" do
887
+ within "#comment_#{comments.first.id}" do
888
+ page.find("[id^='dropdown-trigger']").click
889
+ click_on "Report"
890
+ end
891
+
892
+ within "#flagModalComment#{comments.first.id}" do
893
+ check "Hide this content"
894
+ click_on "Hide"
895
+ end
896
+
897
+ expect(page).to have_content("This resource has been hidden.")
898
+ end
899
+ end
876
900
  end
877
901
 
878
902
  describe "arguable option" do
@@ -4,7 +4,7 @@ module Decidim
4
4
  # This holds the decidim-core version.
5
5
  module Core
6
6
  def self.version
7
- "0.31.0.rc2"
7
+ "0.31.0"
8
8
  end
9
9
  end
10
10
  end
@@ -64,7 +64,11 @@ module Decidim
64
64
  end
65
65
 
66
66
  def configuration_file_path
67
- @configuration_file_path ||= File.join(app_path, "tmp/shakapacker_runtime.yml")
67
+ @configuration_file_path ||= if defined?(Rails) && Rails.env.test?
68
+ File.join(app_path, "tmp/shakapacker_runtime#{ENV.fetch("TEST_ENV_NUMBER", "")}.yml")
69
+ else
70
+ File.join(app_path, "tmp/shakapacker_runtime.yml")
71
+ end
68
72
  end
69
73
 
70
74
  def original_configuration_file_path
@@ -148,6 +148,17 @@ namespace :decidim do
148
148
  invalid_private_exports.delete_all
149
149
  end
150
150
 
151
+ desc "Remove invalid exports from ActiveStorage"
152
+ task remove_private_exports_attachments: :environment do
153
+ invalid = ActiveStorage::Attachment.where(record_type: "Decidim::PrivateExport", record_id: 0)
154
+ logger.info("=== Removing #{invalid.length} invalid PrivateExports attachments")
155
+ invalid.each(&:purge_later)
156
+
157
+ expired = Decidim::PrivateExport.where(expires_at: ..Time.zone.now).collect(&:file).compact_blank
158
+ logger.info("=== Removing #{expired.length} expired attachments from PrivateExports")
159
+ expired.each(&:purge_later) if expired.any?
160
+ end
161
+
151
162
  def logger
152
163
  @logger ||= Logger.new($stdout)
153
164
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :decidim do
4
+ namespace :upgrade do
5
+ desc "Fixes the visibility of menu_hidden action logs"
6
+ task :fix_action_log => :environment do
7
+ logger.info("Fixing action log menu_hidden actions...")
8
+
9
+ count = Decidim::ActionLog.where(action: "menu_hidden").where.not(visibility: "admin-only").count
10
+ logger.info "Found #{count} action logs to update."
11
+ if count.positive?
12
+ # ActionLog is a read-only model, so we need to use raw SQL to update the records
13
+ ActiveRecord::Base.connection.execute("UPDATE decidim_action_logs SET visibility = 'admin-only' WHERE action = 'menu_hidden'")
14
+ if Decidim::ActionLog.where(action: "menu_hidden").where.not(visibility: "admin-only").count.zero?
15
+ logger.info("Successfully updated #{count} action logs.")
16
+ else
17
+ logger.error("Failed to update all action logs. Please check the database.")
18
+ end
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def logger
25
+ @logger ||= Logger.new($stdout)
26
+ end
27
+ end
28
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: decidim-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.31.0.rc2
4
+ version: 0.31.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josep Jaume Rey Peroy
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2025-10-28 00:00:00.000000000 Z
13
+ date: 2025-11-20 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: concurrent-ruby
@@ -138,6 +138,20 @@ dependencies:
138
138
  - - "~>"
139
139
  - !ruby/object:Gem::Version
140
140
  version: 5.1.2
141
+ - !ruby/object:Gem::Dependency
142
+ name: data_migrate
143
+ requirement: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - "~>"
146
+ - !ruby/object:Gem::Version
147
+ version: '11.3'
148
+ type: :runtime
149
+ prerelease: false
150
+ version_requirements: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - "~>"
153
+ - !ruby/object:Gem::Version
154
+ version: '11.3'
141
155
  - !ruby/object:Gem::Dependency
142
156
  name: date_validator
143
157
  requirement: !ruby/object:Gem::Requirement
@@ -800,28 +814,28 @@ dependencies:
800
814
  requirements:
801
815
  - - '='
802
816
  - !ruby/object:Gem::Version
803
- version: 0.31.0.rc2
817
+ version: 0.31.0
804
818
  type: :development
805
819
  prerelease: false
806
820
  version_requirements: !ruby/object:Gem::Requirement
807
821
  requirements:
808
822
  - - '='
809
823
  - !ruby/object:Gem::Version
810
- version: 0.31.0.rc2
824
+ version: 0.31.0
811
825
  - !ruby/object:Gem::Dependency
812
826
  name: decidim-dev
813
827
  requirement: !ruby/object:Gem::Requirement
814
828
  requirements:
815
829
  - - '='
816
830
  - !ruby/object:Gem::Version
817
- version: 0.31.0.rc2
831
+ version: 0.31.0
818
832
  type: :development
819
833
  prerelease: false
820
834
  version_requirements: !ruby/object:Gem::Requirement
821
835
  requirements:
822
836
  - - '='
823
837
  - !ruby/object:Gem::Version
824
- version: 0.31.0.rc2
838
+ version: 0.31.0
825
839
  description: Adds core features so other engines can hook into the framework.
826
840
  email:
827
841
  - josepjaume@gmail.com
@@ -2227,6 +2241,7 @@ files:
2227
2241
  - config/locales/zh-CN.yml
2228
2242
  - config/locales/zh-TW.yml
2229
2243
  - config/routes.rb
2244
+ - db/data/20251108232118_add_dummy_migration.rb
2230
2245
  - db/migrate/20160817115213_devise_create_decidim_users.rb
2231
2246
  - db/migrate/20160919104837_create_decidim_organizations.rb
2232
2247
  - db/migrate/20160920140207_devise_invitable_add_to_decidim_users.rb
@@ -2472,6 +2487,7 @@ files:
2472
2487
  - db/migrate/20250603103953_add_refresh_tokens_enabled_to_doorkeeper_applications.rb
2473
2488
  - db/migrate/20250609073104_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb
2474
2489
  - db/migrate/20250613122148_remove_hashtag_table_from_core.rb
2490
+ - db/migrate/20250819110800_convert_private_exports_id_to_uuid.rb
2475
2491
  - db/seeds.rb
2476
2492
  - db/seeds/Exampledocument.pdf
2477
2493
  - db/seeds/avatars/001.jpg
@@ -3034,6 +3050,7 @@ files:
3034
3050
  - lib/tasks/upgrade/decidim_change_valuator_tasks.rake
3035
3051
  - lib/tasks/upgrade/decidim_content_blocks_tasks.rake
3036
3052
  - lib/tasks/upgrade/decidim_deduplicate_likes.rake
3053
+ - lib/tasks/upgrade/decidim_fix_action_log.rake
3037
3054
  - lib/tasks/upgrade/decidim_fix_nickname_uniqueness.rake
3038
3055
  - lib/tasks/upgrade/decidim_fix_short_url_resolver.rake
3039
3056
  - lib/tasks/upgrade/decidim_migrate_wysiwyg_content.rake