ecoportal-api-v2 0.8.26 → 0.8.27

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f4693a8a82dab15ddfd0722b1b987efb80ddc7ef9d748e76b7ccff87c0317133
4
- data.tar.gz: 999fbaa368b677cdab96889fb34c38fe0c71c4235c000d82e6e38fedd0cf7d10
3
+ metadata.gz: 82d67186b579f8307a36bb9e17d649eaef352bab449e1628aea603198a6ffb3f
4
+ data.tar.gz: 390106d2c6aafe1eb2e6154b7a81aba3622400234738140db187704a30bcba86
5
5
  SHA512:
6
- metadata.gz: 76b33ecae1e147b8e1c1f1dffb118d7533eee71b4e9acc7a5e6609947c7880c4d6f2e3ffc32aac8c5df4af3133573103148861335bfe03a6e85ecf87af5b9e60
7
- data.tar.gz: bcd91f124438cfd8aad7b181ea1f62744c8b37d92053e394a5b681a18338f19254b0d7ca5b59e1d50fc16357b138985c0aa2a67a4a57930952f775b9fbcc4248
6
+ metadata.gz: 9aa958e8c59e53b7c9a71059f8333b8949ee35ce02bc2df4e65810b2f5c8291f67c1271dd2c44a27c37559ccd6c7ad614a31e2ede665437b9e7ed2d84bfa6624
7
+ data.tar.gz: 2884d7264fd3d1f72d970c144a6eecf3ab6298a81a3427fb87ad8ad05d4024b2280e66d9f22ac60998d39e957924e4496cd73c589cdcd54808d8c84dfeb72a12
data/CHANGELOG.md CHANGED
@@ -1,14 +1,75 @@
1
1
  # Change Log
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
- ## [0.8.26] - 2022-02-xx
4
+ ## [0.8.27] - 2022-03-xx
5
5
 
6
6
  ### Added
7
- `Ecoportal::API::V2::Page::Stage#add_permit`
8
- `Ecoportal::API::V2::Page::Permit.new_doc`
9
-
7
+ - `Ecoportal::API::Common::Content::CollectionModel#clear`
8
+ - It calls `#delete!` on each item from an `Array` copy
9
+ - `Ecoportal::API::V2::Page::Components#add`
10
+ - Now it allows to use a `Hash` _doc_ model to create the `Component`
11
+ - `Ecoportal::API::V2::Page::Component::SelectionField` **added** some methods:
12
+ - `#numeric?`, `#text?` to check the `data_type` of the _selection options_
13
+ - `#switch_type!` to switch the `data_type` between `txt` and `num`
14
+ - `#deselect` to mark as `false` the property `selected` of some _selection option_
15
+ - `#name` counterpart of `#value`
16
+ - `#values` and `#names` they return always an `Array` (no matter if the field is **not** `multiple`)
17
+ - `#options_by_value` which returns a `Hash` with all the options by their `value`
18
+ - `#options_by_name` which returns a `Hash` with all the options by their `name`
19
+ - `Ecoportal::API::V2::Page::Component` **added** some methods:
20
+ - `#forces`, `#bindings` and `#bindings?` to check if a _Component_ has bindings in what forces and what those bindings are.
21
+ - `Ecoportal::API::V2::Page::Force#bind` to add a _binding_
22
+ - `Ecoportal::API::V2::Page::Force::Binding` **added** a couple of methods:
23
+ - `#force` to refer to the _Force_ object of a binding
24
+ - `#reference` to retrieve the _component_ or _section_ the binding refers to
25
+ - `Ecoportal::API::V2::Page::Force::Bindings` **added** some methods:
26
+ - `#force` to refer to the _Force_ object of the bindings
27
+ - `#by_name` and `#by_reference` to obtain a `Hash` with all the _bindings_
28
+ - `#reference?` to check if a _section_ or _component_ have a binding to the _force_
29
+ - `#get_by_reference` to retrieve an `Array` with all the _bindings_ to one _section_ or _component_
30
+ - `Ecoportal::API::V2::Page::Forces#bindings_by_reference`
31
+ - For (script) **optimization** purposes. It gets all the _bindings_ as a `Hash` of _reference_ to `Array<Binding>`
32
+ - `Ecoportal::API::V2::Page::Section` **added** some methods:
33
+ - `#shared?` to know if the _section_ is shared by multiple stages
34
+ - `#bindings` to obtain the _bindings_ of the _section_ in any _force_
35
+ - `#forces` all the _forces_ that this _section_ has a _binding_ to
36
+ - `#bindings?` whether or not the _section_ has any force _binding_
37
+ - `Ecoportal::API::V2::Page::Sections` **added** some methods:
38
+ - `#any_shared?` whether or not there are shared sections
39
+ - `#move` to **move** the _section_ to some specific position
40
+
10
41
  ### Changed
42
+ - `ecoportal-api` dependency upgrade
43
+ - `Ecoportal::API::V2::Page::PermissionFlags#configure`
44
+ - Added option to pass a `Hash` with pairs `Symbol`, `Boolean`
45
+ - `flags.configure {subscribed: true}`
46
+ - `Ecoportal::API::Common::Content::ModelHelpers#same_string?`
47
+ - Added parameter `mild:` to compare the strings with only alphabetic characters
48
+ - `Ecoportal::API::V2::Page::Component::SelectionField` **added** some methods:
49
+ - `#selected` **added** parameters to modify the _returned_ value
50
+ - `by_name:` and `by_value:` to return a `Hash`
51
+ - `value:` and `name:` which combines respectively with the above, to cast them in the `Hash`
52
+ - `Ecoportal::API::V2::Page::Sections#get_by_heading`
53
+ - added `mild:` option to allow more flexibility on searches
54
+
11
55
  ### Fixed
56
+ - `Ecoportall::API::Common::Content::DoubleModel#dirty?`
57
+ - It was checking that `#as_update` equaled `{}`. Now it also checks on `null` too.
58
+ - `Ecoportal::API::V2::Page::Component::SelectionOption#numeric!`
59
+ - It was using `to_i` which would return `0` when the source `value` was not numeric.
60
+ - Now it uses `Float(value)`, provided that it can throw an exception
61
+ - `Ecoportal::API::V2::Pages::Stages#get`
62
+ - The _page_ `id` and `stage_id` were used exchanged in the message
63
+ - `Ecoportal::API::V2::Page::Forces` fixed the `weight` (position) scoping
64
+ - It was not positioning correctly
65
+ - `Ecoportal::API::V2::Page::Sections` fixed the `weight` (position) scoping
66
+ - It was not positioning correctly
67
+
68
+ ## [0.8.26] - 2022-03-25
69
+
70
+ ### Added
71
+ `Ecoportal::API::V2::Page::Stage#add_permit`
72
+ `Ecoportal::API::V2::Page::Permit.new_doc`
12
73
 
13
74
  ## [0.8.25] - 2022-02-04
14
75
 
@@ -29,5 +29,5 @@ Gem::Specification.new do |spec|
29
29
  spec.add_development_dependency "redcarpet", ">= 3.5.1", "< 3.6"
30
30
  spec.add_development_dependency "pry" , ">= 0.14"
31
31
 
32
- spec.add_dependency 'ecoportal-api', '>= 0.8.4', '< 0.9'
32
+ spec.add_dependency 'ecoportal-api', '>= 0.8.5', '< 0.9'
33
33
  end
@@ -191,6 +191,11 @@ module Ecoportal
191
191
  end
192
192
  end
193
193
 
194
+ # Deletes all the elements of this `CollectionModel` instance
195
+ def clear
196
+ self.to_a.each {|item| delete!(item)}
197
+ end
198
+
194
199
  # Deletes `value` from this `CollectionModel` instance
195
200
  # @param value [String, Hash, Ecoportal::API::Common::Content::DoubleModel]
196
201
  # - When used as `String`, the `key` value (i.e. `id` value) is expected
@@ -329,7 +329,8 @@ module Ecoportal
329
329
 
330
330
  # @return [Boolean] stating if there are changes
331
331
  def dirty?
332
- as_update != {}
332
+ au = as_update
333
+ !((au == {}) || (au == nil))
333
334
  end
334
335
 
335
336
  # It makes `original_doc` to be like `doc`
@@ -7,13 +7,21 @@ module Ecoportal
7
7
  private
8
8
 
9
9
  # Offers multiple ways to compare two strings
10
- def same_string?(value1, value2, exact: false)
10
+ # Offers multiple ways to compare two strings
11
+ def same_string?(value1, value2, exact: false, mild: false)
11
12
  case
12
13
  when value1.is_a?(String) && value2.is_a?(String)
13
14
  if exact
14
15
  value1 == value2
15
16
  else
16
- value1.to_s.strip.downcase == value2.to_s.strip.downcase
17
+ v1 = value1.to_s.strip.downcase
18
+ v2 = value2.to_s.strip.downcase
19
+
20
+ if mild
21
+ v1 = v1.gsub(/[^a-z ]+/, ' ').gsub(/\s+/, ' ').strip
22
+ v2 = v2.gsub(/[^a-z ]+/, ' ').gsub(/\s+/, ' ').strip
23
+ end
24
+ v1 == v2
17
25
  end
18
26
  when value1.is_a?(Regexp) && value2.is_a?(String)
19
27
  value2 =~ value1
@@ -10,6 +10,14 @@ module Ecoportal
10
10
 
11
11
  embeds_many :options, klass: "Ecoportal::API::V2::Page::Component::SelectionOption", order_key: :weight
12
12
 
13
+ def numeric?
14
+ self.data_type == "num"
15
+ end
16
+
17
+ def text?
18
+ self.data_type == "txt"
19
+ end
20
+
13
21
  def numeric!(&block)
14
22
  ordered_options.each {|opt| opt.numeric!(&block)}
15
23
  self.data_type = "num"
@@ -20,19 +28,42 @@ module Ecoportal
20
28
  self.data_type = "str"
21
29
  end
22
30
 
23
- def select(value)
24
- opt = options.find {|opt| opt.value == value}
31
+ def switch_type!(&block)
32
+ numeric? ? text!(&block) : numeric!(&block)
33
+ end
34
+
35
+ def select(value_name, by_name: false)
36
+ opt = find_option(value_name, by_name: by_name)
25
37
  sel = selected
26
38
  return true if !multiple && opt == sel
27
39
  sel.selected = false if !multiple && sel
28
40
  opt.selected = true unless !opt
29
41
  end
30
42
 
31
- def selected
32
- if multiple
33
- options.select {|opt| opt.selected}
43
+ def deselect(value_name, by_name: false)
44
+ if opt = find_option(value_name, by_name: by_name)
45
+ opt.selected = false
46
+ end
47
+ end
48
+
49
+ def selected(by_name: false, by_value: false, value: false, name: false)
50
+ case
51
+ when by_value
52
+ elems = [selected].flatten.compact
53
+ options_hash(elems) do |option|
54
+ name ? option.name : option
55
+ end
56
+ when by_name
57
+ elems = [selected].flatten.compact
58
+ options_hash(elems, by_name: true) do |option|
59
+ value ? option.value : option
60
+ end
34
61
  else
35
- options.find {|opt| opt.selected}
62
+ if multiple
63
+ ordered_options.select {|opt| opt.selected}
64
+ else
65
+ options.find {|opt| opt.selected}
66
+ end
36
67
  end
37
68
  end
38
69
 
@@ -44,6 +75,22 @@ module Ecoportal
44
75
  end
45
76
  end
46
77
 
78
+ def values
79
+ [value].flatten.compact
80
+ end
81
+
82
+ def name
83
+ if multiple
84
+ selected.map {|opt| opt.name}
85
+ else
86
+ selected&.name
87
+ end
88
+ end
89
+
90
+ def names
91
+ [name].flatten.compact
92
+ end
93
+
47
94
  def add_option(value:, name: nil, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
48
95
  opt_doc = options.items_class.new_doc
49
96
  options.upsert!(opt_doc, pos: pos, before: before, after: after) do |option|
@@ -63,6 +110,26 @@ module Ecoportal
63
110
  end
64
111
  end
65
112
 
113
+ # @param name [Boolean] whether or not the values of the `Hash` should be the `names`
114
+ # @return [Hash] of **key** _value_ and **value**:
115
+ # 1. _option_ if `name` is `false`
116
+ # 2. _name_ if `name` is `true`
117
+ def options_by_value(name: false)
118
+ options_hash do |option|
119
+ name ? option.name : option
120
+ end
121
+ end
122
+
123
+ # @param value [Boolean] whether or not the values of the `Hash` should be the `values`
124
+ # @return [Hash] of **key** _name_ and **value**:
125
+ # 1. _option_ if `value` is `false`
126
+ # 2. _value_ if `value` is `true`
127
+ def options_by_name(value: false)
128
+ options_hash(by_name: true) do |option|
129
+ value ? option.value : option
130
+ end
131
+ end
132
+
66
133
  def to_s(name: true, delimiter: "\n")
67
134
  [selected].flatten.compact.map do |opt|
68
135
  name ? opt.name : opt.value
@@ -75,7 +142,7 @@ module Ecoportal
75
142
  # - `:multiple` to allow multiple selection
76
143
  # - `:single` to set to singular selection
77
144
  # - `:other` to enable `other` button
78
- # - `:options` to add options (`Hash<value, name>`)
145
+ # - `:options` to add options (`Hash<value, name>`) or update option names
79
146
  # - `:type` to define the type
80
147
  # - `:num`
81
148
  # - `:str`
@@ -122,8 +189,13 @@ module Ecoportal
122
189
  private
123
190
 
124
191
  def configure_options(opts)
192
+ hopts = self.options_by_value
125
193
  opts.each do |val, nm|
126
- add_option(value: val, name: nm)
194
+ if option = hopts[val]
195
+ option.name = nm
196
+ else
197
+ add_option(value: val, name: nm)
198
+ end
127
199
  end
128
200
  end
129
201
 
@@ -140,7 +212,20 @@ module Ecoportal
140
212
  opts[pos]
141
213
  end
142
214
 
215
+ def find_option(value_name, by_name: false)
216
+ if by_name
217
+ opt = options.find {|opt| same_string?(opt.name, value_name)}
218
+ else
219
+ opt = options.find {|opt| opt.value == value_name}
220
+ end
221
+ end
143
222
 
223
+ def options_hash(elems = ordered_options, by_name: false)
224
+ elems.each_with_object({}) do |option, hash|
225
+ key = by_name ? option.name : option.value
226
+ hash[key] = block_given?? yield(option) : option
227
+ end
228
+ end
144
229
  end
145
230
  end
146
231
  end
@@ -21,13 +21,27 @@ module Ecoportal
21
21
  passboolean :selected
22
22
 
23
23
  def numeric!
24
- self.value = block_given?? yield(value) : value.to_i
24
+ self.value = block_given?? yield(value) : to_i(value)
25
25
  end
26
26
 
27
27
  def text!
28
28
  self.value = block_given?? yield(value) : value.to_s
29
29
  end
30
30
 
31
+ private
32
+
33
+ def to_i
34
+ Float(value).to_i
35
+ end
36
+
37
+ # https://stackoverflow.com/a/5661695/4352306
38
+ def is_number?(value)
39
+ begin
40
+ true if Float(value)
41
+ rescue ArgumentError => e
42
+ false
43
+ end
44
+ end
31
45
  end
32
46
  end
33
47
  end
@@ -124,6 +124,26 @@ module Ecoportal
124
124
  secs.length > 1
125
125
  end
126
126
 
127
+ # @return [Array<Ecoportal::API::V2::Page::Force::Binding] the force bindings if any.
128
+ def bindings
129
+ ooze.forces.each_with_object([]) do |force, out|
130
+ out.push(*force.bindings.get_by_reference(self))
131
+ end
132
+ out
133
+ end
134
+
135
+ # @return [Array<Ecoportal::API::V2::Page::Force] the forces this component is bound to if any.
136
+ def forces
137
+ ooze.forces.select do |force|
138
+ force.bindings.reference?(self)
139
+ end
140
+ end
141
+
142
+ # @return [Boolean] `true` if the component is bound to any force, `false` otherwise
143
+ def bindings?
144
+ forces.count > 0
145
+ end
146
+
127
147
  def indexable_label
128
148
  self.class.indexable_label(label)
129
149
  end
@@ -42,15 +42,18 @@ module Ecoportal
42
42
  end
43
43
 
44
44
  # It creates a **new** component
45
+ # @note
46
+ # - You can use either `type` and `label` **or** `doc`
45
47
  # @param label [String, nil]
46
48
  # @param type [String] the type of the field
49
+ # @param doc [Hash] to copy another field model
47
50
  # @yield [field] do some stuff with field
48
51
  # @yieldparam [Ecoportal::API::V2::Page::Component] the created field
49
52
  # @return [Ecoportal::API::V2::Page::Component] the created field.
50
- def add(label:, type:)
51
- fld_doc = component_class.new_doc(type: type)
53
+ def add(doc: nil, label: doc && doc["label"], type: doc && doc["type"])
54
+ fld_doc = doc ? JSON.parse(doc.to_json) : component_class.new_doc(type: type)
52
55
  upsert!(fld_doc) do |fld|
53
- fld.label = label
56
+ fld.label = label if !doc
54
57
  yield(fld) if block_given?
55
58
  end
56
59
  end
@@ -22,6 +22,10 @@ module Ecoportal
22
22
  self._parent.ooze
23
23
  end
24
24
 
25
+ def force
26
+ self._parent.force
27
+ end
28
+
25
29
  # @return [Boolean] whether or not this the binding refers to a Component
26
30
  def component?
27
31
  type == COMPONENT_TYPE
@@ -43,6 +47,11 @@ module Ecoportal
43
47
  raise "This is not a section binding, but a component binding" unless section?
44
48
  ooze.sections.get_by_id(reference_id)
45
49
  end
50
+
51
+ # @return [Ecoportal::API::V2::Page::Component, Ecoportal::API::V2::Page::Section]
52
+ def reference
53
+ self.component? ? component : section
54
+ end
46
55
  end
47
56
  end
48
57
  end
@@ -13,6 +13,63 @@ module Ecoportal
13
13
  self._parent.ooze
14
14
  end
15
15
 
16
+ def force
17
+ self._parent
18
+ end
19
+
20
+ # @note first local binding name will shadow later ones
21
+ # @param only_winner [Boolean] specifies if retrieving multiple bindings with same name or just the winner
22
+ # @return [Hash] where **key** is `name` and **value** is
23
+ # 1. a single _binding_, if `only_winner` is `true`
24
+ # 2. an `Array` of _bindings_ with same _name_, otherwise
25
+ def by_name(only_winner: false)
26
+ self.each_with_object({}) do |binding, hash|
27
+ if winner_only
28
+ hash[binding.name] ||= binding
29
+ else
30
+ hash[binding.name] ||= []
31
+ hash[binding.name].push(binding)
32
+ end
33
+ end
34
+ end
35
+
36
+
37
+ # @note first local binding name will shadow later ones.
38
+ # @param only_winner [Boolean] specifies if shadowed bindings (inactive) should be excluded (`true`)
39
+ # @return [Hash] where **key** is a _section_ or a _component_ and **value** is eitheran `Array` of _bindings_.
40
+ def by_reference(only_winner: false)
41
+ if only_winner
42
+ by_name(only_winner: true).each_with_object({}) do |(name, binds), hash|
43
+ if binds.is_a?(Array)
44
+ binds.each {|binding| (hash[binding.reference] ||= []).push(binding)}
45
+ else
46
+ (hash[binds.reference] ||= []).push(binds)
47
+ end
48
+ end
49
+ else
50
+ self.each_with_object({}) do |binding, hash|
51
+ (hash[binding.reference] ||= []).push(binding)
52
+ end
53
+ end
54
+ end
55
+
56
+ # @param obj [Ecoportal::API::V2::Page::Section, Ecoportal::API::V2::Page::Component)] the referred component or section.
57
+ # @return [Boolean] `true` if `obj` is referred in the bindings, `false` otherwise
58
+ def reference?(obj)
59
+ get_by_reference(obj).count > 0
60
+ end
61
+
62
+ # @param obj [Ecoportal::API::V2::Page::Section, Ecoportal::API::V2::Page::Component)] the referred component or section.
63
+ # @return [Array<Ecoportal::API::V2::Page::Force::Binding>] binding to the component or section.
64
+ def get_by_reference(obj)
65
+ unless obj.is_a?(Ecoportal::API::V2::Page::Section) || obj.is_a?(Ecoportal::API::V2::Page::Component)
66
+ raise ArgumentError.new("Expected either a Ecoportal::API::V2::Page::Section or a Ecoportal::API::V2::Page::Component. Given: #{obj.class}")
67
+ end
68
+ self.select do |bind|
69
+ bind.reference == obj
70
+ end
71
+ end
72
+
16
73
  # @param id [String] the `id` of the binding to find.
17
74
  # @return [Ecoportal::API::V2::Page::Force::Binding] binding with `id`
18
75
  def get_by_id(id)
@@ -24,6 +24,11 @@ module Ecoportal
24
24
  def ooze
25
25
  self._parent.ooze
26
26
  end
27
+
28
+ # @see Ecoportal::API::V2::Page::Force::Bindings#add
29
+ def bind(reference, **kargs, &block)
30
+ bindings.add(reference, **kargs, &block)
31
+ end
27
32
  end
28
33
  end
29
34
  end
@@ -12,6 +12,18 @@ module Ecoportal
12
12
  self._parent.ooze
13
13
  end
14
14
 
15
+ # Helper to optimize binding searches
16
+ # @return [Hash] where
17
+ # - **key** is a _section_ or a _component_
18
+ # - **value** is `Array<Ecoportal::API::V2::Page::Force::Binding>`.
19
+ def bindings_by_reference(only_winner: false)
20
+ self.each_with_object({}) do |force, out|
21
+ force.bindings.by_reference(only_winner: only_winner).each do |ref, bindings|
22
+ (out[ref] ||= []).push(*bindings)
23
+ end
24
+ end
25
+ end
26
+
15
27
  # @return [Ecoportal::API::V2::Page::Force]
16
28
  def get_by_id(id)
17
29
  self.find do |force|
@@ -79,7 +91,7 @@ module Ecoportal
79
91
  after.weight
80
92
  end
81
93
  end.yield_self do |weight|
82
- weight = ordered.reject do |frc|
94
+ weight ||= ordered.reject do |frc|
83
95
  frc.id == force.id
84
96
  end.last&.weight
85
97
  weight ||= force_class.const_get(:INITIAL_WEIGHT)
@@ -36,26 +36,40 @@ module Ecoportal
36
36
  # - `:subscribed_to_tasks`
37
37
  def configure(*conf)
38
38
  conf.each_with_object([]) do |cnf, unused|
39
- case cnf
40
- when :restructure
41
- self.can_restructure = true
42
- when :configure
43
- self.can_configure = true
44
- when :can_permission
45
- self.can_permission = true
46
- when :create_actions
47
- self.can_create_actions = true
48
- when :admin_actions
49
- self.can_administrate_actions = true
50
- when :subscribed
51
- self.subscribed = true
52
- when :subscribed_to_tasks
53
- self.subscribed_to_tasks = true
39
+ if cnf.is_a?(Symbol)
40
+ set_flag(cnf, true, residual: unused)
41
+ elsif cnf.is_a?(Hash)
42
+ cnf.each do |key, val|
43
+ set_flag(key, val, residual: unused)
44
+ end
54
45
  else
55
- unused.push(cnf)
46
+ raise ArgumentError.new("Expecting 'Symbol' or 'Hash'. Given: #{cnf.class}")
56
47
  end
57
48
  end.yield_self do |unused|
58
- raise "Unknown configuaration options #{unused}" unless unused.empty?
49
+ raise ArgumentError.new("Unknown configuaration options #{unused}") unless unused.empty?
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def set_flag(key, val = true, residual: [])
56
+ case key
57
+ when :restructure
58
+ self.can_restructure = val
59
+ when :configure
60
+ self.can_configure = val
61
+ when :can_permission
62
+ self.can_permission = val
63
+ when :create_actions
64
+ self.can_create_actions = val
65
+ when :admin_actions
66
+ self.can_administrate_actions = val
67
+ when :subscribed
68
+ self.subscribed = val
69
+ when :subscribed_to_tasks
70
+ self.subscribed_to_tasks = val
71
+ else
72
+ residual.push(cnf)
59
73
  end
60
74
  end
61
75
  end
@@ -43,6 +43,30 @@ module Ecoportal
43
43
  ooze.stages.select {|stg| stg.section?(self)}
44
44
  end
45
45
 
46
+ # @return [Boolean] `true` if the section belongs to more than 1 stage, `false` otherwise
47
+ def shared?
48
+ stages.count > 1
49
+ end
50
+
51
+ # @return [Array<Ecoportal::API::V2::Page::Force::Binding] the force bindings if any.
52
+ def bindings
53
+ ooze.forces.each_with_object([]) do |force, out|
54
+ out.push(*force.bindings.get_by_reference(self))
55
+ end
56
+ end
57
+
58
+ # @return [Array<Ecoportal::API::V2::Page::Force] the forces this section is bound to if any.
59
+ def forces
60
+ ooze.forces.select do |force|
61
+ force.bindings.reference?(self)
62
+ end
63
+ end
64
+
65
+ # @return [Boolean] `true` if the section is bound to any force, `false` otherwise
66
+ def bindings?
67
+ force.count > 0
68
+ end
69
+
46
70
  # @return [Boolean] whether or not the section appears in an ooze instance
47
71
  def attached?
48
72
  !ooze.stages? || stages.any? {|stg| stg.section?(self)}
@@ -11,23 +11,33 @@ module Ecoportal
11
11
  self._parent.ooze
12
12
  end
13
13
 
14
+ # @return [Boolean] `true` if there is one or more sections shared, `false` otherwise
15
+ def any_shared?
16
+ self.any? {|sec| sec.shared?}
17
+ end
18
+
14
19
  # Creates a new `section`
15
20
  # @note
16
- # - It won't fix weights unless all the sections of the ooze are present
21
+ # - It won't fix weights unless all the sections of the ooze are present or there aren't shared sections
17
22
  # - This means that it doesn't fix section weights on stages,
18
23
  # as shared sections could change order in other stages
19
24
  def add(name: nil, split: false, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
20
25
  sec_doc = section_class.new_doc(split: split)
21
26
  upsert!(sec_doc) do |section| #, pos: pos, before: before, after: after) do |section|
22
27
  section.heading = name
23
- if weight = scope_weight(section, pos: pos, before: before, after: after)
24
- section.weight = weight
25
- end
26
- fix_weights!
28
+ move(section, pos: pos, before: before, after: after)
27
29
  yield(section) if block_given?
28
30
  end
29
31
  end
30
32
 
33
+ # Moves an existing `section`
34
+ def move(section, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
35
+ if weight = scope_weight(section, pos: pos, before: before, after: after)
36
+ section.weight = weight
37
+ end
38
+ fix_weights!
39
+ end
40
+
31
41
  # @return [Ecoportal::API::V2::Page::Section]
32
42
  def get_by_id(id)
33
43
  self.find do |sec|
@@ -42,11 +52,12 @@ module Ecoportal
42
52
  end
43
53
  end
44
54
 
55
+ # @param mild [Boolean] modifier to only compare alphabetic characters
45
56
  # @return [Array<Ecoportal::API::V2::Page::Section>]
46
- def get_by_heading(heading)
57
+ def get_by_heading(heading, mild: false)
47
58
  ordered.select do |sec|
48
59
  value = heading == :unnamed ? nil : heading
49
- same_string?(sec.heading, value)
60
+ same_string?(sec.heading, value, mild: mild)
50
61
  end
51
62
  end
52
63
 
@@ -96,7 +107,7 @@ module Ecoportal
96
107
  after.weight
97
108
  end
98
109
  end.yield_self do |weight|
99
- weight = ordered.reject do |sec|
110
+ weight ||= ordered.reject do |sec|
100
111
  sec.id == section.id
101
112
  end.last&.weight
102
113
  weight ||= section_class.const_get(:INITIAL_WEIGHT)
@@ -115,7 +126,7 @@ module Ecoportal
115
126
  end
116
127
 
117
128
  def fix_weights!
118
- unless self._parent.is_a?(Ecoportal::API::V2::Pages::PageStage)
129
+ unless self.any_shared? && self._parent.is_a?(Ecoportal::API::V2::Pages::PageStage)
119
130
  ordered.each_with_index do |section, index|
120
131
  section.weight = index
121
132
  end
@@ -31,7 +31,7 @@ module Ecoportal
31
31
  wrapped = Common::Content::WrappedResponse.new(response, page_stage_class)
32
32
 
33
33
  return wrapped.result if wrapped.success?
34
- raise "Could not get stage {#{id}} of page #{stage_id} - Error #{response.status}: #{response.body}"
34
+ raise "Could not get stage {#{stage_id}} of page #{id} - Error #{response.status}: #{response.body}"
35
35
  end
36
36
 
37
37
  # Requests to update an existing stage via api.
@@ -1,5 +1,5 @@
1
1
  module Ecoportal
2
2
  module API
3
- GEM2_VERSION = "0.8.26"
3
+ GEM2_VERSION = "0.8.27"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ecoportal-api-v2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.26
4
+ version: 0.8.27
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oscar Segura
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-24 00:00:00.000000000 Z
11
+ date: 2022-04-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -130,7 +130,7 @@ dependencies:
130
130
  requirements:
131
131
  - - ">="
132
132
  - !ruby/object:Gem::Version
133
- version: 0.8.4
133
+ version: 0.8.5
134
134
  - - "<"
135
135
  - !ruby/object:Gem::Version
136
136
  version: '0.9'
@@ -140,7 +140,7 @@ dependencies:
140
140
  requirements:
141
141
  - - ">="
142
142
  - !ruby/object:Gem::Version
143
- version: 0.8.4
143
+ version: 0.8.5
144
144
  - - "<"
145
145
  - !ruby/object:Gem::Version
146
146
  version: '0.9'