ecoportal-api-v2 0.8.26 → 0.8.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f4693a8a82dab15ddfd0722b1b987efb80ddc7ef9d748e76b7ccff87c0317133
4
- data.tar.gz: 999fbaa368b677cdab96889fb34c38fe0c71c4235c000d82e6e38fedd0cf7d10
3
+ metadata.gz: ca7591fd58fc849aefad7508d07e7902d5016ccaa19642dc7f8bb94b2ad445ca
4
+ data.tar.gz: c0a76091ed2702c29973d7295654f447425bf8e819e9684913bc71132eeccc9a
5
5
  SHA512:
6
- metadata.gz: 76b33ecae1e147b8e1c1f1dffb118d7533eee71b4e9acc7a5e6609947c7880c4d6f2e3ffc32aac8c5df4af3133573103148861335bfe03a6e85ecf87af5b9e60
7
- data.tar.gz: bcd91f124438cfd8aad7b181ea1f62744c8b37d92053e394a5b681a18338f19254b0d7ca5b59e1d50fc16357b138985c0aa2a67a4a57930952f775b9fbcc4248
6
+ metadata.gz: aab5c8003ceb2d0bfc71169f9a2bcda26cb37253cad9a6ec277309c4d2c6bb1a3e4a4fc8717b69286a81b4b6cf43b8e3c969267171f5d4b529fefbe1c85e2da8
7
+ data.tar.gz: 96d45a7aba715ea08eb0b96f6920f2dae25a8f27383f460e4883bf79233a9efb2a26bea10025d7b8a7931b3450c9650e1518da52044c90e03f8edfcbba8f9058
data/CHANGELOG.md CHANGED
@@ -1,14 +1,95 @@
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.29] - 2022-06-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::V2::Page::Component::ActionField#permitted_person_schema_ids`
8
+ - Integration for the new feature
9
+ - `Ecoportal::API::V2::Pages::PageStage#uid` new method for directly rendering the uid
10
+
11
+ ### Changed
12
+ - `Ecoportal::API::V2::Page::Component::PeopleField#configure_permits`
13
+ - Allow for `can_view` to prevent unnecessary errors
14
+
15
+ ### Fixed
16
+ - `Ecoportal::API::V2::Page::PermissionFlags#configure` fixed typo
17
+
18
+ ## [0.8.28] - 2022-05-31
19
+
20
+ ### Added
21
+ - `Ecoportal::API::V2::Page::Component::File` added `label`
22
+ - `Ecoportal::API::V2::Page::Component::Image` added `upload_id` and `file_file_name`
23
+
24
+ ## [0.8.27] - 2022-04-25
25
+
26
+ ### Added
27
+ - `Ecoportal::API::Common::Content::CollectionModel#clear`
28
+ - It calls `#delete!` on each item from an `Array` copy
29
+ - `Ecoportal::API::V2::Page::Components#add`
30
+ - Now it allows to use a `Hash` _doc_ model to create the `Component`
31
+ - `Ecoportal::API::V2::Page::Component::SelectionField` **added** some methods:
32
+ - `#numeric?`, `#text?` to check the `data_type` of the _selection options_
33
+ - `#switch_type!` to switch the `data_type` between `txt` and `num`
34
+ - `#deselect` to mark as `false` the property `selected` of some _selection option_
35
+ - `#name` counterpart of `#value`
36
+ - `#values` and `#names` they return always an `Array` (no matter if the field is **not** `multiple`)
37
+ - `#options_by_value` which returns a `Hash` with all the options by their `value`
38
+ - `#options_by_name` which returns a `Hash` with all the options by their `name`
39
+ - `Ecoportal::API::V2::Page::Component` **added** some methods:
40
+ - `#forces`, `#bindings` and `#bindings?` to check if a _Component_ has bindings in what forces and what those bindings are.
41
+ - `Ecoportal::API::V2::Page::Force#bind` to add a _binding_
42
+ - `Ecoportal::API::V2::Page::Force::Binding` **added** a couple of methods:
43
+ - `#force` to refer to the _Force_ object of a binding
44
+ - `#reference` to retrieve the _component_ or _section_ the binding refers to
45
+ - `Ecoportal::API::V2::Page::Force::Bindings` **added** some methods:
46
+ - `#force` to refer to the _Force_ object of the bindings
47
+ - `#by_name` and `#by_reference` to obtain a `Hash` with all the _bindings_
48
+ - `#reference?` to check if a _section_ or _component_ have a binding to the _force_
49
+ - `#get_by_reference` to retrieve an `Array` with all the _bindings_ to one _section_ or _component_
50
+ - `Ecoportal::API::V2::Page::Forces#bindings_by_reference`
51
+ - For (script) **optimization** purposes. It gets all the _bindings_ as a `Hash` of _reference_ to `Array<Binding>`
52
+ - `Ecoportal::API::V2::Page::Section` **added** some methods:
53
+ - `#shared?` to know if the _section_ is shared by multiple stages
54
+ - `#bindings` to obtain the _bindings_ of the _section_ in any _force_
55
+ - `#forces` all the _forces_ that this _section_ has a _binding_ to
56
+ - `#bindings?` whether or not the _section_ has any force _binding_
57
+ - `Ecoportal::API::V2::Page::Sections` **added** some methods:
58
+ - `#any_shared?` whether or not there are shared sections
59
+ - `#move` to **move** the _section_ to some specific position
60
+
10
61
  ### Changed
62
+ - `ecoportal-api` dependency upgrade
63
+ - `Ecoportal::API::V2::Page::PermissionFlags#configure`
64
+ - Added option to pass a `Hash` with pairs `Symbol`, `Boolean`
65
+ - `flags.configure {subscribed: true}`
66
+ - `Ecoportal::API::Common::Content::ModelHelpers#same_string?`
67
+ - Added parameter `mild:` to compare the strings with only alphabetic characters
68
+ - `Ecoportal::API::V2::Page::Component::SelectionField` **added** some methods:
69
+ - `#selected` **added** parameters to modify the _returned_ value
70
+ - `by_name:` and `by_value:` to return a `Hash`
71
+ - `value:` and `name:` which combines respectively with the above, to cast them in the `Hash`
72
+ - `Ecoportal::API::V2::Page::Sections#get_by_heading`
73
+ - added `mild:` option to allow more flexibility on searches
74
+
11
75
  ### Fixed
76
+ - `Ecoportall::API::Common::Content::DoubleModel#dirty?`
77
+ - It was checking that `#as_update` equaled `{}`. Now it also checks on `null` too.
78
+ - `Ecoportal::API::V2::Page::Component::SelectionOption#numeric!`
79
+ - It was using `to_i` which would return `0` when the source `value` was not numeric.
80
+ - Now it uses `Float(value)`, provided that it can throw an exception
81
+ - `Ecoportal::API::V2::Pages::Stages#get`
82
+ - The _page_ `id` and `stage_id` were used exchanged in the message
83
+ - `Ecoportal::API::V2::Page::Forces` fixed the `weight` (position) scoping
84
+ - It was not positioning correctly
85
+ - `Ecoportal::API::V2::Page::Sections` fixed the `weight` (position) scoping
86
+ - It was not positioning correctly
87
+
88
+ ## [0.8.26] - 2022-03-25
89
+
90
+ ### Added
91
+ `Ecoportal::API::V2::Page::Stage#add_permit`
92
+ `Ecoportal::API::V2::Page::Permit.new_doc`
12
93
 
13
94
  ## [0.8.25] - 2022-02-04
14
95
 
@@ -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
@@ -7,7 +7,8 @@ module Ecoportal
7
7
  passboolean :create_actions
8
8
  passthrough :required_number_of_completed_actions
9
9
  passboolean :permits_and_rules_integration, :add_subscribed, :add_subscribed_to_tasks
10
-
10
+ passarray :permitted_person_schema_ids, order_matters: false
11
+
11
12
  embeds_many :actions, klass: "Ecoportal::API::V2::Page::Component::Action", order_key: :weight
12
13
 
13
14
  # Adds a task with `name` short description
@@ -16,6 +16,7 @@ module Ecoportal
16
16
  passkey :id
17
17
  passforced :patch_ver, default: 1
18
18
  passthrough :position
19
+ passthrough :label
19
20
  passthrough :file_size, :content_type, :token, read_only: true
20
21
  passthrough :file_container_id
21
22
  passdate :file_update_at, read_only: true
@@ -8,6 +8,7 @@ module Ecoportal
8
8
  passforced :patch_ver, default: 1
9
9
  passthrough :weight
10
10
  passthrough :height, :width, :caption
11
+ passthrough :upload_id, :file_file_name
11
12
  passthrough :dimensions, :styles
12
13
  end
13
14
  end
@@ -121,6 +121,8 @@ module Ecoportal
121
121
  self.apply_attached_people_permissions_to = "current_stage"
122
122
  when :can_edit
123
123
  self.attached_people_permissions_editable = true
124
+ when :can_view
125
+ # do nothing
124
126
  else
125
127
  flags.push(cnf)
126
128
  end
@@ -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(key)
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
@@ -10,6 +10,13 @@ module Ecoportal
10
10
  #embeds_many :permits, klass: "Ecoportal::API::V2::Page::Permit"
11
11
  passarray :force_errors, :subtags, order_matters: false
12
12
 
13
+ # @return [String] unique id
14
+ def uid
15
+ if counter = mould_counter
16
+ counter.render
17
+ end
18
+ end
19
+
13
20
  # @return [String] `id` of the stage we got the data of.
14
21
  def current_stage_id
15
22
  doc.dig("active_stage", "id") || doc["current_stage_id"]
@@ -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.29"
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.29
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-07-07 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'