decidim-assemblies 0.26.2 → 0.27.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/assemblies/content_blocks/highlighted_assemblies/show.erb +2 -2
  3. data/app/cells/decidim/assemblies/content_blocks/highlighted_assemblies_cell.rb +2 -4
  4. data/app/commands/decidim/assemblies/admin/copy_assembly.rb +10 -7
  5. data/app/commands/decidim/assemblies/admin/create_assemblies_type.rb +1 -1
  6. data/app/commands/decidim/assemblies/admin/create_assembly.rb +1 -1
  7. data/app/commands/decidim/assemblies/admin/create_assembly_member.rb +12 -12
  8. data/app/commands/decidim/assemblies/admin/destroy_assemblies_type.rb +1 -1
  9. data/app/commands/decidim/assemblies/admin/destroy_assembly_admin.rb +1 -1
  10. data/app/commands/decidim/assemblies/admin/destroy_assembly_member.rb +1 -1
  11. data/app/commands/decidim/assemblies/admin/import_assembly.rb +11 -7
  12. data/app/commands/decidim/assemblies/admin/notify_role_assigned_to_assembly.rb +1 -1
  13. data/app/commands/decidim/assemblies/admin/publish_assembly.rb +1 -1
  14. data/app/commands/decidim/assemblies/admin/unpublish_assembly.rb +1 -1
  15. data/app/commands/decidim/assemblies/admin/update_assemblies_setting.rb +1 -1
  16. data/app/commands/decidim/assemblies/admin/update_assemblies_type.rb +1 -1
  17. data/app/commands/decidim/assemblies/admin/update_assembly.rb +1 -1
  18. data/app/commands/decidim/assemblies/admin/update_assembly_member.rb +11 -11
  19. data/app/controllers/decidim/assemblies/admin/assembly_copies_controller.rb +1 -1
  20. data/app/controllers/decidim/assemblies/admin/assembly_imports_controller.rb +1 -1
  21. data/app/controllers/decidim/assemblies/admin/reminders_controller.rb +14 -0
  22. data/app/controllers/decidim/assemblies/assemblies_controller.rb +6 -6
  23. data/app/events/decidim/role_assigned_to_assembly_event.rb +1 -1
  24. data/app/forms/decidim/assemblies/admin/assembly_import_form.rb +5 -6
  25. data/app/helpers/decidim/assemblies/filter_assemblies_helper.rb +10 -6
  26. data/app/models/decidim/assembly.rb +10 -4
  27. data/app/packs/src/decidim/assemblies/orgchart.js +52 -46
  28. data/app/permissions/decidim/assemblies/permissions.rb +45 -11
  29. data/app/presenters/decidim/assemblies/admin_log/assembly_presenter.rb +1 -1
  30. data/app/presenters/decidim/assemblies/assembly_stats_presenter.rb +4 -1
  31. data/app/presenters/decidim/assembly_member_presenter.rb +3 -5
  32. data/app/queries/decidim/assemblies/admin/admin_users.rb +1 -1
  33. data/app/queries/decidim/assemblies/admin/assembly_members.rb +1 -1
  34. data/app/queries/decidim/assemblies/assemblies_with_user_role.rb +1 -1
  35. data/app/queries/decidim/assemblies/filtered_assemblies.rb +1 -1
  36. data/app/queries/decidim/assemblies/organization_assemblies.rb +1 -1
  37. data/app/queries/decidim/assemblies/organization_prioritized_assemblies.rb +2 -2
  38. data/app/queries/decidim/assemblies/organization_published_assemblies.rb +2 -2
  39. data/app/queries/decidim/assemblies/parent_assemblies.rb +1 -1
  40. data/app/queries/decidim/assemblies/parent_assemblies_for_select.rb +1 -1
  41. data/app/queries/decidim/assemblies/prioritized_assemblies.rb +1 -1
  42. data/app/queries/decidim/assemblies/promoted_assemblies.rb +1 -1
  43. data/app/queries/decidim/assemblies/published_assemblies.rb +1 -1
  44. data/app/queries/decidim/assemblies/visible_assemblies.rb +1 -1
  45. data/app/serializers/decidim/assemblies/assembly_importer.rb +4 -3
  46. data/app/views/decidim/assemblies/_filter_by_type.html.erb +1 -1
  47. data/app/views/decidim/assemblies/admin/assemblies/index.html.erb +2 -2
  48. data/app/views/decidim/assemblies/assemblies/_promoted_assembly.html.erb +1 -1
  49. data/app/views/decidim/assemblies/assemblies/index.html.erb +3 -1
  50. data/app/views/decidim/assemblies/assemblies/show.html.erb +3 -1
  51. data/app/views/layouts/decidim/_assembly_header.html.erb +1 -1
  52. data/config/locales/ar.yml +1 -1
  53. data/config/locales/bg.yml +1 -0
  54. data/config/locales/ca.yml +6 -2
  55. data/config/locales/cs.yml +6 -2
  56. data/config/locales/de.yml +6 -2
  57. data/config/locales/el.yml +1 -7
  58. data/config/locales/en.yml +5 -2
  59. data/config/locales/es-MX.yml +6 -2
  60. data/config/locales/es-PY.yml +6 -2
  61. data/config/locales/es.yml +6 -2
  62. data/config/locales/eu.yml +1 -7
  63. data/config/locales/fi-plain.yml +6 -2
  64. data/config/locales/fi.yml +6 -2
  65. data/config/locales/fr-CA.yml +6 -2
  66. data/config/locales/fr.yml +11 -7
  67. data/config/locales/ga-IE.yml +1 -0
  68. data/config/locales/gl.yml +2 -7
  69. data/config/locales/hu.yml +43 -3
  70. data/config/locales/id-ID.yml +1 -1
  71. data/config/locales/is-IS.yml +4 -1
  72. data/config/locales/it.yml +1 -7
  73. data/config/locales/ja.yml +6 -2
  74. data/config/locales/lb.yml +1 -6
  75. data/config/locales/lt.yml +473 -0
  76. data/config/locales/lv.yml +1 -1
  77. data/config/locales/nl.yml +27 -18
  78. data/config/locales/no.yml +1 -7
  79. data/config/locales/pl.yml +3 -2
  80. data/config/locales/pt-BR.yml +1 -7
  81. data/config/locales/pt.yml +1 -7
  82. data/config/locales/ro-RO.yml +1 -7
  83. data/config/locales/ru.yml +3 -1
  84. data/config/locales/sk.yml +3 -0
  85. data/config/locales/sl.yml +3 -6
  86. data/config/locales/sr-CS.yml +1 -0
  87. data/config/locales/sv.yml +2 -7
  88. data/config/locales/tr-TR.yml +1 -7
  89. data/config/locales/uk.yml +3 -1
  90. data/config/locales/zh-CN.yml +1 -7
  91. data/lib/decidim/assemblies/admin_engine.rb +4 -1
  92. data/lib/decidim/assemblies/participatory_space.rb +9 -9
  93. data/lib/decidim/assemblies/version.rb +1 -1
  94. metadata +13 -13
  95. data/app/services/decidim/assemblies/assembly_search.rb +0 -18
@@ -2,10 +2,13 @@
2
2
  /* eslint dot-location: ["error", "property"], no-negated-condition: "error" */
3
3
  /* eslint no-unused-expressions: ["error", { "allowTernary": true }] */
4
4
  /* eslint no-unused-vars: 0 */
5
- /* global d3 */
6
5
 
7
- import * as d3 from "d3"
8
- import renderChart from "src/decidim/vizzs/renders"
6
+ import { select, selectAll, event } from "d3-selection";
7
+ import { max } from "d3-array";
8
+ import { hierarchy } from "d3-hierarchy";
9
+ import { forceManyBody, forceCollide, forceCenter, forceX, forceY, forceSimulation, forceLink } from "d3-force";
10
+ import { drag } from "d3-drag";
11
+ import { json } from "d3-fetch";
9
12
 
10
13
  // lib
11
14
  const renderOrgCharts = () => {
@@ -54,11 +57,11 @@ const renderOrgCharts = () => {
54
57
  let updateData
55
58
  let collapse, expand
56
59
  let filter
57
- let hierarchy = {}
60
+ let _hierarchy = {}
58
61
 
59
62
  // main chart object
60
- let main = function (selection) {
61
- selection.each(function scope() {
63
+ let main = function (_selection) {
64
+ _selection.each(function scope() {
62
65
 
63
66
  // calculated properties
64
67
  let calc = {}
@@ -68,12 +71,12 @@ const renderOrgCharts = () => {
68
71
  calc.chartHeight = attrs.svgHeight - attrs.marginBottom - calc.chartTopMargin
69
72
 
70
73
  // ########################## HIERARCHY STUFF #########################
71
- hierarchy.root = d3.hierarchy(attrs.data.root)
74
+ _hierarchy.root = hierarchy(attrs.data.root)
72
75
 
73
76
  // ########################### BEHAVIORS #########################
74
77
  let behaviors = {}
75
- // behaviors.zoom = d3.zoom().scaleExtent([0.75, 100, 8]).on("zoom", zoomed)
76
- behaviors.drag = d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended)
78
+ // behaviors.zoom = zoom().scaleExtent([0.75, 100, 8]).on("zoom", zoomed)
79
+ behaviors.drag = drag().on("start", dragstarted).on("drag", dragged).on("end", dragended)
77
80
 
78
81
  // ########################### LAYOUTS #########################
79
82
  let layouts = {}
@@ -83,24 +86,24 @@ const renderOrgCharts = () => {
83
86
 
84
87
  // ########################### FORCE STUFF #########################
85
88
  let force = {}
86
- force.link = d3.forceLink().id((d) => d.id)
87
- force.charge = d3.forceManyBody().strength(-240)
88
- force.center = d3.forceCenter(calc.chartWidth / 2, calc.chartHeight / 2)
89
+ force.link = forceLink().id((d) => d.id)
90
+ force.charge = forceManyBody().strength(-240)
91
+ force.center = forceCenter(calc.chartWidth / 2, calc.chartHeight / 2)
89
92
 
90
93
  // prevent collide
91
- force.collide = d3.forceCollide().radius((d) => {
94
+ force.collide = forceCollide().radius((d) => {
92
95
  // Creates an invented radius based on element measures: diagonal = 2 * radius = sqrt(width^2, height^2)
93
96
  let base = (d.bbox || {}).width + (attrs.nodeGutter.x * 2)
94
97
  let height = (d.bbox || {}).height + (attrs.nodeGutter.y * 2)
95
98
  let diagonal = Math.sqrt(Math.pow(base, 2) + Math.pow(height, 2))
96
99
  let fakeRadius = (diagonal / 2)
97
100
 
98
- // return d3.max([attrs.nodeDistance * 3, fakeRadius])
101
+ // return max([attrs.nodeDistance * 3, fakeRadius])
99
102
  return fakeRadius * 1.5
100
103
  })
101
104
 
102
105
  // manually set x positions (which is calculated using custom radial layout)
103
- force.x = d3.forceX()
106
+ force.x = forceX()
104
107
  .strength(0.5)
105
108
  .x(function (d) {
106
109
 
@@ -115,8 +118,8 @@ const renderOrgCharts = () => {
115
118
  return projectCircle(d.proportion, (d.depth - 1) * attrs.distance)[0]
116
119
  })
117
120
 
118
- // manually set y positions (which is calculated using d3.cluster)
119
- force.y = d3.forceY()
121
+ // manually set y positions (which is calculated using cluster)
122
+ force.y = forceY()
120
123
  .strength(0.5)
121
124
  .y(function (d) {
122
125
 
@@ -134,7 +137,7 @@ const renderOrgCharts = () => {
134
137
  // --------------------------------- INITIALISE FORCE SIMULATION ----------------------------
135
138
 
136
139
  // get based on top parameter simulation
137
- force.simulation = d3.forceSimulation()
140
+ force.simulation = forceSimulation()
138
141
  .force("link", force.link)
139
142
  .force("charge", force.charge)
140
143
  .force("center", force.center)
@@ -145,7 +148,7 @@ const renderOrgCharts = () => {
145
148
  // ########################### HIERARCHY STUFF #########################
146
149
 
147
150
  // flatten root
148
- let arr = flatten(hierarchy.root)
151
+ let arr = flatten(_hierarchy.root)
149
152
 
150
153
  // hide members based on their depth
151
154
  arr.forEach((d) => {
@@ -163,25 +166,25 @@ const renderOrgCharts = () => {
163
166
  // #################################### DRAWINGS #######################
164
167
 
165
168
  // drawing containers
166
- let container = d3.select(this)
169
+ let container = select(this)
167
170
 
168
171
  // add svg
169
- let svg = container.patternify({ tag: "svg", selector: "svg-chart-container" })
172
+ let svg = patternify(container, { tag: "svg", selector: "svg-chart-container" })
170
173
  .attr("width", attrs.svgWidth)
171
174
  .attr("height", attrs.svgHeight)
172
175
  // .call(behaviors.zoom)
173
176
 
174
177
  // add container g element
175
- let chart = svg.patternify({ tag: "g", selector: "chart" })
178
+ let chart = patternify(svg, { tag: "g", selector: "chart" })
176
179
  .attr("transform", `translate(${calc.chartLeftMargin},${calc.chartTopMargin})`)
177
180
 
178
181
  // ################################ Chart Content Drawing ##################################
179
182
 
180
183
  // link wrapper
181
- let linksWrapper = chart.patternify({ tag: "g", selector: "links-wrapper" })
184
+ let linksWrapper = patternify(chart, { tag: "g", selector: "links-wrapper" })
182
185
 
183
186
  // node wrapper
184
- let nodesWrapper = chart.patternify({ tag: "g", selector: "nodes-wrapper" })
187
+ let nodesWrapper = patternify(chart, { tag: "g", selector: "nodes-wrapper" })
185
188
  let links, nodes
186
189
 
187
190
  // reusable function which updates visual based on data change
@@ -194,14 +197,14 @@ const renderOrgCharts = () => {
194
197
  (clickedNode) ? $btnReset.removeClass("invisible") : $btnReset.addClass("invisible")
195
198
 
196
199
  // set xy and proportion properties with custom radial layout
197
- layouts.radial(hierarchy.root)
200
+ layouts.radial(_hierarchy.root)
198
201
 
199
202
  // nodes and links array
200
- let nodesArr = flatten(hierarchy.root, true)
203
+ let nodesArr = flatten(_hierarchy.root, true)
201
204
  .orderBy((d) => d.depth)
202
205
  .filter((d) => !d.hidden)
203
206
 
204
- let linksArr = hierarchy.root.links()
207
+ let linksArr = _hierarchy.root.links()
205
208
  .filter((d) => !d.source.hidden)
206
209
  .filter((d) => !d.target.hidden)
207
210
 
@@ -274,7 +277,7 @@ const renderOrgCharts = () => {
274
277
  .attr("class", "as-text")
275
278
  .attr("dx", (d) => d.bbox.x + d.bbox.width + attrs.nodeGutter.x)
276
279
  .attr("dy", attrs.childrenIndicatorRadius + 3)
277
- .text((d) => d3.max([(d.children || {}).length, (d._children || {}).length]))
280
+ .text((d) => max([(d.children || {}).length, (d._children || {}).length]))
278
281
 
279
282
  // merge node groups and style it
280
283
  nodes = enteredNodes.merge(nodes)
@@ -291,7 +294,7 @@ const renderOrgCharts = () => {
291
294
  // zoom handler
292
295
  // function zoomed() {
293
296
  // // get transform event
294
- // let transform = d3.event.transform
297
+ // let transform = event.transform
295
298
  // attrs.lastTransform = transform
296
299
  //
297
300
  // // apply transform event props to the wrapper
@@ -330,8 +333,8 @@ const renderOrgCharts = () => {
330
333
  // handle dragging event
331
334
  function dragged(d) {
332
335
  // make dragged node fixed
333
- d.fx = d3.event.x
334
- d.fy = d3.event.y
336
+ d.fx = event.x
337
+ d.fy = event.y
335
338
  }
336
339
 
337
340
  // -------------------- handle drag end event ---------------
@@ -342,7 +345,7 @@ const renderOrgCharts = () => {
342
345
  // -------------------------- node mouse hover handler ---------------
343
346
  function nodeMouseEnter(d) {
344
347
  // get links
345
- let _links = hierarchy.root.links()
348
+ let _links = _hierarchy.root.links()
346
349
 
347
350
  // get hovered node connected links
348
351
  let connectedLinks = _links.filter((l) => l.source.id === d.id || l.target.id === d.id)
@@ -438,7 +441,7 @@ const renderOrgCharts = () => {
438
441
  // }
439
442
 
440
443
  function freeNodes() {
441
- d3.selectAll(".node").each((n) => {
444
+ selectAll(".node").each((n) => {
442
445
  n.fx = null
443
446
  n.fy = null
444
447
  })
@@ -507,18 +510,18 @@ const renderOrgCharts = () => {
507
510
  }
508
511
 
509
512
  // ----------- PROTOTYEPE FUNCTIONS ----------------------
510
- d3.selection.prototype.patternify = function (_params) {
513
+ function patternify(node, _params) {
511
514
  let selector = _params.selector
512
515
  let elementTag = _params.tag
513
516
  let _data = _params.data || [selector]
514
517
 
515
518
  // pattern in action
516
- let selection = this.selectAll(`.${selector}`).data(_data)
517
- selection.exit().remove()
518
- selection = selection.enter().append(elementTag).merge(selection)
519
- selection.attr("class", selector)
519
+ let _selection = node.selectAll(`.${selector}`).data(_data)
520
+ _selection.exit().remove()
521
+ _selection = _selection.enter().append(elementTag).merge(_selection)
522
+ _selection.attr("class", selector)
520
523
 
521
- return selection
524
+ return _selection
522
525
  }
523
526
 
524
527
  // custom radial layout
@@ -527,8 +530,8 @@ const renderOrgCharts = () => {
527
530
 
528
531
  recurse(root, 0, 1)
529
532
 
530
- function recurse(node, min, max) {
531
- node.proportion = (max + min) / 2
533
+ function recurse(node, min, _max) {
534
+ node.proportion = (_max + min) / 2
532
535
  if (!node.x) {
533
536
 
534
537
  // if node has parent, match entered node positions to it's parent
@@ -550,7 +553,7 @@ const renderOrgCharts = () => {
550
553
 
551
554
  // recursively do the same for children
552
555
  if (node.children) {
553
- let offset = (max - min) / node.children.length
556
+ let offset = (_max - min) / node.children.length
554
557
  node.children.forEach(function (child, i) {
555
558
  let newMin = min + (offset * i)
556
559
  let newMax = newMin + offset
@@ -624,7 +627,7 @@ const renderOrgCharts = () => {
624
627
 
625
628
  // run visual
626
629
  main.run = function () {
627
- d3.selectAll(attrs.container)
630
+ selectAll(attrs.container)
628
631
  .call(main)
629
632
  return main
630
633
  }
@@ -643,7 +646,7 @@ const renderOrgCharts = () => {
643
646
 
644
647
  main.reset = function () {
645
648
 
646
- hierarchy.root.children.forEach((e) => collapse(e, true))
649
+ _hierarchy.root.children.forEach((e) => collapse(e, true))
647
650
  main.run()
648
651
 
649
652
  return main
@@ -659,7 +662,7 @@ const renderOrgCharts = () => {
659
662
  let width = $container.width()
660
663
  let height = width / (16 / 9)
661
664
 
662
- d3.json($container.data("url")).then((data) => {
665
+ json($container.data("url")).then((data) => {
663
666
  // Make a fake previous node if the data entry is not hierarchical
664
667
  if (data instanceof Array) {
665
668
  fake = true
@@ -691,5 +694,8 @@ const renderOrgCharts = () => {
691
694
  }
692
695
 
693
696
  $(() => {
694
- renderChart(renderOrgCharts);
697
+ renderOrgCharts()
698
+ $(document).on("change.zf.tabs", () => {
699
+ renderOrgCharts()
700
+ });
695
701
  })
@@ -32,6 +32,8 @@ module Decidim
32
32
  user_can_list_assembly_list?
33
33
  user_can_read_current_assembly?
34
34
  user_can_create_assembly?
35
+ user_can_export_assembly?
36
+ user_can_copy_assembly?
35
37
  user_can_read_assemblies_setting?
36
38
 
37
39
  # org admins and space admins can do everything in the admin section
@@ -71,6 +73,12 @@ module Decidim
71
73
  user.admin? || (assembly ? can_manage_assembly?(role: :admin) : has_manageable_assemblies?)
72
74
  end
73
75
 
76
+ # It's an admin assembly when assembly exists and the user is allowed to
77
+ # manage the current assembly.
78
+ def admin_assembly?
79
+ assembly.present? && assembly_admin_allowed_assemblies.include?(assembly)
80
+ end
81
+
74
82
  # Checks if it has any manageable assembly, with any possible role.
75
83
  def has_manageable_assemblies?(role: :any)
76
84
  return unless user
@@ -88,7 +96,11 @@ module Decidim
88
96
  # Returns a collection of assemblies where the given user has the
89
97
  # specific role privilege.
90
98
  def assemblies_with_role_privileges(role)
91
- Decidim::Assemblies::AssembliesWithUserRole.for(user, role)
99
+ if role == :admin
100
+ assembly_admin_allowed_assemblies
101
+ else
102
+ Decidim::Assemblies::AssembliesWithUserRole.for(user, role)
103
+ end
92
104
  end
93
105
 
94
106
  def public_list_assemblies_action?
@@ -151,12 +163,26 @@ module Decidim
151
163
  allow! if user.admin? || has_manageable_assemblies?
152
164
  end
153
165
 
154
- # Only organization admins can create a assembly
166
+ # Only organization admins and assemblies admins can create a assembly
155
167
  def user_can_create_assembly?
156
168
  return unless permission_action.action == :create &&
157
169
  permission_action.subject == :assembly
158
170
 
159
- toggle_allow(user.admin?)
171
+ toggle_allow(user.admin? || admin_assembly? || user_role == "admin")
172
+ end
173
+
174
+ def user_can_export_assembly?
175
+ return unless permission_action.action == :export &&
176
+ permission_action.subject == :assembly
177
+
178
+ toggle_allow(user.admin? || admin_assembly?)
179
+ end
180
+
181
+ def user_can_copy_assembly?
182
+ return unless permission_action.action == :copy &&
183
+ permission_action.subject == :assembly
184
+
185
+ toggle_allow(user.admin? || admin_assembly?)
160
186
  end
161
187
 
162
188
  def user_can_read_assemblies_setting?
@@ -185,10 +211,9 @@ module Decidim
185
211
  end
186
212
 
187
213
  def allowed_list_of_assemblies?
188
- assemblies = AssembliesWithUserRole.for(user)
189
- parent_assemblies = assemblies.flat_map { |assembly| [assembly.id] + assembly.ancestors.pluck(:id) }
214
+ parent_assemblies = assembly_admin_allowed_assemblies.flat_map { |assembly| [assembly.id] + assembly.ancestors.pluck(:id) }
190
215
 
191
- allowed_list_of_assemblies = Decidim::Assembly.where(id: assemblies + parent_assemblies)
216
+ allowed_list_of_assemblies = Decidim::Assembly.where(id: assembly_admin_allowed_assemblies + parent_assemblies)
192
217
  allowed_list_of_assemblies.uniq.member?(assembly)
193
218
  end
194
219
 
@@ -196,7 +221,7 @@ module Decidim
196
221
  return unless read_assembly_list_permission_action?
197
222
  return if permission_action.subject == :assembly_list
198
223
 
199
- toggle_allow(user.admin? || can_manage_assembly?)
224
+ toggle_allow(user.admin? || can_manage_assembly? || admin_assembly?)
200
225
  end
201
226
 
202
227
  # A moderator needs to be able to read the assembly they are assigned to,
@@ -223,13 +248,10 @@ module Decidim
223
248
  end
224
249
 
225
250
  # Process admins can perform everything *inside* that assembly. They cannot
226
- # create a assembly or perform actions on assembly groups or other
227
- # assemblies.
251
+ # perform actions on assembly groups or other assemblies.
228
252
  def assembly_admin_action?
229
253
  return unless can_manage_assembly?(role: :admin)
230
254
  return if user.admin?
231
- return disallow! if permission_action.action == :create &&
232
- permission_action.subject == :assembly
233
255
 
234
256
  is_allowed = [
235
257
  :attachment,
@@ -279,6 +301,18 @@ module Decidim
279
301
  def assembly
280
302
  @assembly ||= context.fetch(:current_participatory_space, nil) || context.fetch(:assembly, nil)
281
303
  end
304
+
305
+ def user_role
306
+ assembly_user_role = Decidim::AssemblyUserRole.find_by(decidim_user_id: user.id)
307
+ assembly_user_role.present? ? assembly_user_role.role : :any
308
+ end
309
+
310
+ def assembly_admin_allowed_assemblies
311
+ assemblies = AssembliesWithUserRole.for(user, :admin)
312
+ child_assemblies = assemblies.flat_map { |assembly| [assembly.id] + assembly.children.pluck(:id) }
313
+
314
+ Decidim::Assembly.where(id: assemblies + child_assemblies)
315
+ end
282
316
  end
283
317
  end
284
318
  end
@@ -63,7 +63,7 @@ module Decidim
63
63
 
64
64
  def action_string
65
65
  case action
66
- when "create", "publish", "unpublish", "update"
66
+ when "create", "publish", "unpublish", "update", "duplicate", "export", "import"
67
67
  "decidim.admin_log.assembly.#{action}"
68
68
  else
69
69
  super
@@ -4,9 +4,12 @@ module Decidim
4
4
  module Assemblies
5
5
  # A presenter to render statistics in an Assembly.
6
6
  class AssemblyStatsPresenter < Decidim::StatsPresenter
7
- attribute :assembly, Decidim::Assembly
8
7
  include Decidim::IconHelper
9
8
 
9
+ def assembly
10
+ __getobj__.fetch(:assembly)
11
+ end
12
+
10
13
  # Public: returns a collection of stats (Hash) for the Assembly Home.
11
14
  def collection
12
15
  highlighted_stats = assembly_participants_stats
@@ -46,11 +46,9 @@ module Decidim
46
46
  private
47
47
 
48
48
  def user
49
- @user ||= begin
50
- if (user = __getobj__.user.presence)
51
- Decidim::UserPresenter.new(user)
52
- end
53
- end
49
+ @user ||= if (user = __getobj__.user.presence)
50
+ Decidim::UserPresenter.new(user)
51
+ end
54
52
  end
55
53
  end
56
54
  end
@@ -4,7 +4,7 @@ module Decidim
4
4
  module Assemblies
5
5
  module Admin
6
6
  # A class used to find the admins for an assembly or an organization assemblies.
7
- class AdminUsers < Rectify::Query
7
+ class AdminUsers < Decidim::Query
8
8
  # Syntactic sugar to initialize the class and return the queried objects.
9
9
  #
10
10
  # assembly - an assembly that needs to find its assembly admins
@@ -4,7 +4,7 @@ module Decidim
4
4
  module Assemblies
5
5
  module Admin
6
6
  # A class used to find the AssemblyMembers's by their status status.
7
- class AssemblyMembers < Rectify::Query
7
+ class AssemblyMembers < Decidim::Query
8
8
  # Syntactic sugar to initialize the class and return the queried objects.
9
9
  #
10
10
  # assembly_members - the initial AssemblyMember relation that needs to be filtered.
@@ -4,7 +4,7 @@ module Decidim
4
4
  module Assemblies
5
5
  # A class used to find the Assemblies that the given user has
6
6
  # the specific role privilege.
7
- class AssembliesWithUserRole < Rectify::Query
7
+ class AssembliesWithUserRole < Decidim::Query
8
8
  # Syntactic sugar to initialize the class and return the queried objects.
9
9
  #
10
10
  # user - a User that needs to find which assemblies can manage
@@ -3,7 +3,7 @@
3
3
  module Decidim
4
4
  module Assemblies
5
5
  # This query filters assemblies by type.
6
- class FilteredAssemblies < Rectify::Query
6
+ class FilteredAssemblies < Decidim::Query
7
7
  def initialize(filter)
8
8
  @filter = filter
9
9
  end
@@ -3,7 +3,7 @@
3
3
  module Decidim
4
4
  module Assemblies
5
5
  # This query class filters all assemblies given an organization.
6
- class OrganizationAssemblies < Rectify::Query
6
+ class OrganizationAssemblies < Decidim::Query
7
7
  def initialize(organization)
8
8
  @organization = organization
9
9
  end
@@ -4,14 +4,14 @@ module Decidim
4
4
  module Assemblies
5
5
  # This query class filters public assemblies given an organization in a
6
6
  # meaningful prioritized order.
7
- class OrganizationPrioritizedAssemblies < Rectify::Query
7
+ class OrganizationPrioritizedAssemblies < Decidim::Query
8
8
  def initialize(organization, user = nil)
9
9
  @organization = organization
10
10
  @user = user
11
11
  end
12
12
 
13
13
  def query
14
- Rectify::Query.merge(
14
+ Decidim::Query.merge(
15
15
  OrganizationPublishedAssemblies.new(@organization, @user),
16
16
  PrioritizedAssemblies.new
17
17
  ).query
@@ -3,14 +3,14 @@
3
3
  module Decidim
4
4
  module Assemblies
5
5
  # This query class filters published assemblies given an organization.
6
- class OrganizationPublishedAssemblies < Rectify::Query
6
+ class OrganizationPublishedAssemblies < Decidim::Query
7
7
  def initialize(organization, user = nil)
8
8
  @organization = organization
9
9
  @user = user
10
10
  end
11
11
 
12
12
  def query
13
- Rectify::Query.merge(
13
+ Decidim::Query.merge(
14
14
  OrganizationAssemblies.new(@organization),
15
15
  PublishedAssemblies.new,
16
16
  VisibleAssemblies.new(@user)
@@ -3,7 +3,7 @@
3
3
  module Decidim
4
4
  module Assemblies
5
5
  # This query filters assemblies so only parent assemblies are returned.
6
- class ParentAssemblies < Rectify::Query
6
+ class ParentAssemblies < Decidim::Query
7
7
  def query
8
8
  Decidim::Assembly.where(parent: nil)
9
9
  end
@@ -3,7 +3,7 @@
3
3
  module Decidim
4
4
  module Assemblies
5
5
  # This query filters assemblies that can be assigned as parents for an assembly.
6
- class ParentAssembliesForSelect < Rectify::Query
6
+ class ParentAssembliesForSelect < Decidim::Query
7
7
  # Syntactic sugar to initialize the class and return the queried objects.
8
8
  def self.for(organization, assembly)
9
9
  new(organization, assembly).query
@@ -4,7 +4,7 @@ module Decidim
4
4
  module Assemblies
5
5
  # This query orders assemblies by importance, prioritizing promoted
6
6
  # assemblies.
7
- class PrioritizedAssemblies < Rectify::Query
7
+ class PrioritizedAssemblies < Decidim::Query
8
8
  def query
9
9
  Decidim::Assembly.order(promoted: :desc)
10
10
  end
@@ -3,7 +3,7 @@
3
3
  module Decidim
4
4
  module Assemblies
5
5
  # This query filters assemblies so only promoted ones are returned.
6
- class PromotedAssemblies < Rectify::Query
6
+ class PromotedAssemblies < Decidim::Query
7
7
  def query
8
8
  Decidim::Assembly.promoted
9
9
  end
@@ -3,7 +3,7 @@
3
3
  module Decidim
4
4
  module Assemblies
5
5
  # This query filters published assemblies only.
6
- class PublishedAssemblies < Rectify::Query
6
+ class PublishedAssemblies < Decidim::Query
7
7
  def query
8
8
  Decidim::Assembly.published
9
9
  end
@@ -3,7 +3,7 @@
3
3
  module Decidim
4
4
  module Assemblies
5
5
  # This query class filters assemblies given a current_user.
6
- class VisibleAssemblies < Rectify::Query
6
+ class VisibleAssemblies < Decidim::Query
7
7
  def initialize(user)
8
8
  @user = user
9
9
  end
@@ -61,8 +61,9 @@ module Decidim
61
61
  meta_scope: attributes["meta_scope"],
62
62
  announcement: attributes["announcement"]
63
63
  )
64
- @imported_assembly.remote_hero_image_url = attributes["remote_hero_image_url"] if remote_file_exists?(attributes["remote_hero_image_url"])
65
- @imported_assembly.remote_banner_image_url = attributes["remote_banner_image_url"] if remote_file_exists?(attributes["remote_banner_image_url"])
64
+ @imported_assembly.attached_uploader(:hero_image).remote_url = attributes["remote_hero_image_url"] if attributes["remote_hero_image_url"].present?
65
+ @imported_assembly.attached_uploader(:banner_image).remote_url = attributes["remote_banner_image_url"] if attributes["remote_banner_image_url"].present?
66
+
66
67
  @imported_assembly.save!
67
68
  @imported_assembly
68
69
  end
@@ -107,7 +108,7 @@ module Decidim
107
108
  attachments["files"].map do |file|
108
109
  next unless remote_file_exists?(file["remote_file_url"])
109
110
 
110
- file_tmp = URI.open(file["remote_file_url"])
111
+ file_tmp = URI.parse(file["remote_file_url"]).open
111
112
 
112
113
  Decidim.traceability.perform_action!("create", Attachment, @user) do
113
114
  attachment = Attachment.new(
@@ -1,5 +1,5 @@
1
1
  <div id="assemblies-filter" class="inline-filters">
2
- <% if available_filters.any? %>
2
+ <% if available_filters.present? %>
3
3
  <div id="inline-filter-sort" class="dropdown-pane" data-position="bottom" data-alignment="right" data-dropdown data-auto-focus="true">
4
4
  <ul class="list-reset">
5
5
  <% available_filters.each do |title, id| %>
@@ -82,13 +82,13 @@
82
82
  <% end %>
83
83
  </td>
84
84
  <td class="table-list__actions">
85
- <% if allowed_to? :create, :assembly, assembly: assembly %>
85
+ <% if allowed_to? :export, :assembly, assembly: assembly %>
86
86
  <%= icon_link_to "data-transfer-download", assembly_export_path(assembly), t("actions.export", scope: "decidim.admin"), method: :post, class: "action-icon--export" %>
87
87
  <% else %>
88
88
  <span class="action-space icon"></span>
89
89
  <% end %>
90
90
 
91
- <% if allowed_to? :create, :assembly, assembly: assembly %>
91
+ <% if allowed_to? :copy, :assembly, assembly: assembly %>
92
92
  <%= icon_link_to "clipboard", new_assembly_copy_path(assembly), t("actions.duplicate", scope: "decidim.admin"), class: "action-icon--copy" %>
93
93
  <% else %>
94
94
  <span class="action-space icon"></span>
@@ -13,7 +13,7 @@
13
13
  </div>
14
14
  <div class="columns mediumlarge-8 large-6 card--process__column">
15
15
  <div class="card--full__image"
16
- style="background-image:url(<%= promoted_assembly.attached_uploader(:hero_image).path %>)">
16
+ style="background-image:url('<%= promoted_assembly.attached_uploader(:hero_image).path %>')">
17
17
  <div class="card__content row collapse">
18
18
  <div class="large-6 large-offset-6 columns">
19
19
  <%= link_to assembly_path(promoted_assembly), class: "button expanded button--sc" do %>
@@ -30,4 +30,6 @@ edit_link(
30
30
  <% end %>
31
31
  <% end %>
32
32
 
33
- <%= javascript_pack_tag "decidim_assemblies" %>
33
+ <% content_for :js_content do %>
34
+ <%= javascript_pack_tag "decidim_assemblies" %>
35
+ <% end %>