ecoportal-api-v2 0.8.9 → 0.8.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +63 -1
  3. data/lib/ecoportal/api/common/content/array_model.rb +1 -1
  4. data/lib/ecoportal/api/common/content/collection_model.rb +46 -21
  5. data/lib/ecoportal/api/common/content/doc_helpers.rb +2 -2
  6. data/lib/ecoportal/api/common/content/double_model.rb +97 -9
  7. data/lib/ecoportal/api/common/content/hash_diff_patch.rb +13 -3
  8. data/lib/ecoportal/api/v2/page/component/action.rb +4 -3
  9. data/lib/ecoportal/api/v2/page/component/action_field.rb +3 -3
  10. data/lib/ecoportal/api/v2/page/component/chart_field/config.rb +2 -2
  11. data/lib/ecoportal/api/v2/page/component/checklist_field.rb +3 -3
  12. data/lib/ecoportal/api/v2/page/component/checklist_item.rb +4 -3
  13. data/lib/ecoportal/api/v2/page/component/file.rb +13 -3
  14. data/lib/ecoportal/api/v2/page/component/files_field.rb +37 -1
  15. data/lib/ecoportal/api/v2/page/component/gauge_field.rb +3 -3
  16. data/lib/ecoportal/api/v2/page/component/gauge_stop.rb +5 -5
  17. data/lib/ecoportal/api/v2/page/component/image.rb +2 -1
  18. data/lib/ecoportal/api/v2/page/component/number_field.rb +1 -0
  19. data/lib/ecoportal/api/v2/page/component/people_field.rb +14 -2
  20. data/lib/ecoportal/api/v2/page/component/people_viewable_field.rb +14 -0
  21. data/lib/ecoportal/api/v2/page/component/selection_field.rb +3 -3
  22. data/lib/ecoportal/api/v2/page/component/selection_option.rb +4 -3
  23. data/lib/ecoportal/api/v2/page/component/signature_field.rb +3 -2
  24. data/lib/ecoportal/api/v2/page/component.rb +11 -7
  25. data/lib/ecoportal/api/v2/page/permit.rb +2 -1
  26. data/lib/ecoportal/api/v2/page/section.rb +12 -6
  27. data/lib/ecoportal/api/v2/page/sections.rb +16 -5
  28. data/lib/ecoportal/api/v2/page/stage.rb +2 -2
  29. data/lib/ecoportal/api/v2/page/stages.rb +3 -3
  30. data/lib/ecoportal/api/v2/page.rb +50 -2
  31. data/lib/ecoportal/api/v2/pages/page_stage.rb +13 -0
  32. data/lib/ecoportal/api/v2/pages.rb +3 -0
  33. data/lib/ecoportal/api/v2/registers/search_results.rb +13 -0
  34. data/lib/ecoportal/api/v2/registers.rb +15 -2
  35. data/lib/ecoportal/api/v2_version.rb +1 -1
  36. metadata +4 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5833ea731a9d1360c346264d234ce9f95266db92a5480180a17f413459f196de
4
- data.tar.gz: f3ef175580d2ab47c0ee7f51dc2731c0b42bd27ffa9f59600fb506d5cde38a4b
3
+ metadata.gz: 146b0998371f28683143b8a95ae1b68e11f8f079698502bede31c8e29369fc97
4
+ data.tar.gz: 4ce0f3dd75e4e1d822d4540fa0ff1e3e18a7c7dca1c54d7030bdb475adc21a93
5
5
  SHA512:
6
- metadata.gz: 52064ec37a32470e699f846ac1c6c57f8f535fb0be1d689a4f086836a47f9fb2805c0f84533842f5aaa4ee9e538c60e61c1569177ae16a015520c65248347174
7
- data.tar.gz: 0f8cd291558cad37b5157dba7ffdea6670548952b6aa5b0c90b34820abd2693d8f484009265bbc4c8c83fb46684f2968e9a40d4a65563e0ffc6704cca30885d0
6
+ metadata.gz: 21605169ab88cb159ee32a2f6f36e3100b183a03a7f9c895b33631934811bb9e3f16c6bc6101ddfac562854f8762f545a743b68c55d662c97be54ff35fc5b9e8
7
+ data.tar.gz: d2a66296e4b9194667983ba5c37c646fd6a12e037138870aa2771c743fc75dbf9b2ee91d07af7b1e4b501ad1afd846b427a8b92f5dc99ee4551200cc742dcd20
data/CHANGELOG.md CHANGED
@@ -1,7 +1,69 @@
1
1
  # Change Log
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
- ## [0.8.9] - 2021-06-xx
4
+ ## [0.8.13] - 2021-08-xx
5
+
6
+ ### Added
7
+ ### Changed
8
+ ### Fixed
9
+ - `Ecoportal::API::V2::Stage::Sections`
10
+ - `weight` fixing should only happen on entire page, **not** on stage sections that could change the order of section shared with other stages
11
+ - `#scope_weight` was not excluding the section when using `weight` of the last one
12
+ - Several classes with `embeds_many` were performing the `ordering` of those elements in the wrong way
13
+ - `Ecoportall::API::Common::Content::DoubleModel`
14
+ - `#replace_original_doc` had a couple of typos
15
+ - `#replace_doc` should only remove the variable referring to the current object and only if `new_doc` is `nil`
16
+ - `Ecoportal::API::Common::Content::CollectionModel` on insertion and deletion it was removing instance variable objects.
17
+ - There was no need for this approach, as the only necessary thing is to just keep those variable instances up to date in the correct unique access point to do so.
18
+ - Aside note: the reason why this was initially designed this way is because there were some difficulties to identify the existing elements in the subjacent model. Once `#passkey` as added, this difficulty could be overcome.
19
+ - `Ecoportal::API::Common::Content::ArrayModel` on initialize, default `doc` should be an `Array`
20
+
21
+ ## [0.8.12] - 2021-08-30
22
+
23
+ ### Added
24
+ - `Ecoportal::API::V2::Pages::PageStage#current_stage`
25
+
26
+ ### Fixed
27
+ - `Ecoportal::API::Common::Content::DocHelpers#get_body` typo and wrong parameters on call.
28
+ - `Ecoportal::API::V2::Pages#update` should always return `Result` object.
29
+ - `Ecoportal::API::V2::Registers#search` was not using `cursor_id` to iterate.
30
+
31
+ ## [0.8.11] - 2021-08-27
32
+
33
+ ### Added
34
+ - `Ecoportal::API::V2::Page#stages?`
35
+ - `Ecoportal::API::V2::Pages::PageStage#current_stage_id`
36
+ - `Ecoportal::API::V2::Registers#search` added option keyed parameter `:only_first`
37
+ - which will make the method return the first `Ecoportal::API::V2::Registers::SearchResults`
38
+ - This has been **added** with the aim of knowing how many results out of how many entries.
39
+
40
+ ### Changed
41
+ - `Ecoportal::API::V2::Pages::PageStage#update` won't update unless there's something to update.
42
+
43
+ ### Fixed
44
+
45
+
46
+ ## [0.8.10] - 2021-08-22
47
+
48
+ ### Added
49
+ - `Ecoportal::API::Common::Content::CollectionModel#[]` now supports position as well
50
+ - `Ecoportal::API::V2::Page::Component::FilesField#add_file`: support for adding files
51
+ - `Ecoportal::API::V2::Page::Component::PeopleField#viewable_fields`: support for managing `viewable_fields`
52
+
53
+ ### Changed
54
+
55
+ ### Fixed
56
+ - `Ecoportal::API::V2::Page::Component::FilesField`: was not requiring `File`
57
+ - `Ecoportal::API::V2::Page::Component::NumberField#value`: it was missing :/
58
+ - `Ecoportal::API::Common::Content::HashDiffPatch` did not support nested objects in Arrays, where the nested object wouldn't have a `patch_ver`. This **fix** allows for it
59
+ - `Ecoportal::API::Common::Content::DoubleModel.passforced` to define `methods` that should always be present. This allows to define `patch_ver` as a forced `key` in models that have it
60
+ - The enforcement (`self.class.enforce!`) happens on `initialize`
61
+ - `passenforced` subjacent model `forced_model_keys` is inheritable
62
+ - `Ecoportal::API::Common::Content::CollectionModel`:
63
+ - Method `upsert!` was not working fine the parameters `pos`, `before` and `after`
64
+ - Method `delete!` did not support position
65
+
66
+ ## [0.8.9] - 2021-08-16
5
67
 
6
68
  ### Added
7
69
  - `Ecoportal::API::Common::Content::ModelHelpers`
@@ -33,7 +33,7 @@ module Ecoportal
33
33
 
34
34
  end
35
35
 
36
- def initialize(doc = {}, parent: self, key: nil)
36
+ def initialize(doc = [], parent: self, key: nil)
37
37
  super(doc, parent: parent, key: key)
38
38
  end
39
39
 
@@ -110,6 +110,9 @@ module Ecoportal
110
110
  end
111
111
 
112
112
  # Transforms `value` into the actual `key` to access the object in the doc `Array`
113
+ # @note
114
+ # - The name of the method is after the paren't class method
115
+ # - This method would have been better called `_doc_pos` :)
113
116
  def _doc_key(value)
114
117
  #print "*(#{value.class})"
115
118
  return super(value) unless value.is_a?(Hash) || value.is_a?(Content::DoubleModel)
@@ -143,17 +146,21 @@ module Ecoportal
143
146
  end
144
147
 
145
148
  # Get an element usign the `key`.
149
+ # @param value [String, Hash, Ecoportal::API::Common::Content::DoubleModel]
150
+ # @return [Object] the `items_class` element object
146
151
  def [](value)
147
152
  items_by_key[get_key(value)]
148
153
  end
149
154
 
155
+ # @return [Array<Object>] the `items_class` element object
150
156
  def values_at(*keys)
151
157
  keys.map {|key| self[key]}
152
158
  end
153
159
 
154
160
  # Tries to find the element `value`, if it exists, it updates it
155
- # Otherwise it pushes it to the end
156
- # @return the element
161
+ # Otherwise it pushes it to the end
162
+ # @value [Hash, Ecoportal::API::Common::Content::DoubleModel] the eleement to be added
163
+ # @return [Object] the `items_class` element object
157
164
  def upsert!(value, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
158
165
  unless value.is_a?(Hash) || value.is_a?(Content::DoubleModel)
159
166
  raise "'Content::DoubleModel' or 'Hash' doc required"
@@ -163,7 +170,10 @@ module Ecoportal
163
170
  if item = self[value]
164
171
  item.replace_doc(item_doc)
165
172
  else
166
- _doc_upsert(item_doc, pos: pos, before: before, after: after)
173
+ _doc_upsert(item_doc, pos: pos, before: before, after: after).tap do |pos_idx|
174
+ _items.insert(pos_idx, new_item(item_doc))
175
+ @indexed = false
176
+ end
167
177
  end
168
178
  (item || self[item_doc]).tap do |item|
169
179
  yield(item) if block_given?
@@ -171,12 +181,18 @@ module Ecoportal
171
181
  end
172
182
 
173
183
  # Deletes `value` from this `CollectionModel` instance
184
+ # @param value [String, Hash, Ecoportal::API::Common::Content::DoubleModel]
185
+ # - When used as `String`, the `key` value (i.e. `id` value) is expected
186
+ # - When used as `Hash`, it should be the `doc` of the target element
187
+ # - When used as `DoubleModel`, it should be the specific object to be deleted
174
188
  def delete!(value)
175
- unless value.is_a?(Hash) || value.is_a?(Content::DoubleModel)
189
+ unless value.is_a?(Hash) || value.is_a?(Content::DoubleModel) || value.is_a?(String)
176
190
  raise "'Content::DoubleModel' or 'Hash' doc required"
177
191
  end
178
192
  if item = self[value]
179
193
  _doc_delete(item.doc)
194
+ @indexed = false
195
+ _items.delete(item)
180
196
  end
181
197
  end
182
198
 
@@ -187,7 +203,8 @@ module Ecoportal
187
203
  def items_key; self.class.items_key; end
188
204
 
189
205
  def on_change
190
- variables_remove!
206
+ @indexed = false
207
+ #variables_remove!
191
208
  end
192
209
 
193
210
  # Gets the `key` of the object `value`
@@ -199,6 +216,8 @@ module Ecoportal
199
216
  value[items_key]
200
217
  when String
201
218
  value
219
+ when Numeric
220
+ get_key(self.to_a[value])
202
221
  end
203
222
  end
204
223
 
@@ -243,25 +262,16 @@ module Ecoportal
243
262
  # @return [Object] the element deleted from `doc`
244
263
  def _doc_delete(value)
245
264
  if current_pos = _doc_key(value)
246
- _doc_items.delete_at(current_pos).tap do |deleted|
247
- on_change
248
- end
265
+ _doc_items.delete_at(current_pos)
249
266
  end
250
267
  end
251
268
 
252
269
  def _doc_upsert(value, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
253
- current_pos = _doc_key(value)
254
- pos = case
255
- when used_param?(pos)
256
- pos
257
- when used_param?(before)
258
- _doc_key(before)
259
- when used_param?(after)
260
- if i = _doc_key(after)
261
- i + 1
262
- end
263
- end
270
+ current_pos = if elem = self[value]
271
+ _doc_key(elem)
272
+ end
264
273
 
274
+ pos = scope_position(pos: pos, before: before, after: after)
265
275
  pos ||= current_pos
266
276
 
267
277
  if current_pos && pos
@@ -270,14 +280,29 @@ module Ecoportal
270
280
  end
271
281
 
272
282
  pos = (pos && pos < _doc_items.length)? pos : _doc_items.length
273
-
274
283
  pos.tap do |i|
275
284
  _doc_items.insert(pos, value)
276
- on_change
277
285
  end
278
286
 
279
287
  end
280
288
 
289
+ def scope_position(pos: NOT_USED, before: NOT_USED, after: NOT_USED)
290
+ case
291
+ when used_param?(pos)
292
+ if elem = self[pos]
293
+ _doc_key(elem) - 1
294
+ end
295
+ when used_param?(before)
296
+ if elem = self[before]
297
+ _doc_key(elem) - 1
298
+ end
299
+ when used_param?(after)
300
+ if elem = self[after]
301
+ _doc_key(elem)
302
+ end
303
+ end
304
+ end
305
+
281
306
  end
282
307
  end
283
308
  end
@@ -13,9 +13,9 @@ module Ecoportal
13
13
  when doc.respond_to?(:as_update)
14
14
  doc.as_update
15
15
  when doc.respond_to?(:as_json)
16
- Common::Content::HashPatchDiff.patch_diff(doc.as_json)
16
+ Common::Content::HashDiffPatch.patch_diff(doc.as_json, nil)
17
17
  when doc.is_a?(Hash)
18
- Common::Content::HashPatchDiff.patch_diff(doc)
18
+ Common::Content::HashDiffPatch.patch_diff(doc, nil)
19
19
  else
20
20
  raise "Could not get body for doc: #{doc}"
21
21
  end
@@ -37,6 +37,8 @@ module Ecoportal
37
37
 
38
38
  # Same as `attr_reader` but links to a subjacent `Hash` model property
39
39
  # @note it does **not** create an _instance variable_
40
+ # @param methods [Array<Symbol>] the method that exposes the value
41
+ # as well as its `key` in the underlying `Hash` model.
40
42
  def pass_reader(*methods)
41
43
  methods.each do |method|
42
44
  method = method.to_s.freeze
@@ -52,6 +54,8 @@ module Ecoportal
52
54
 
53
55
  # Same as `attr_writer` but links to a subjacent `Hash` model property
54
56
  # @note it does **not** create an _instance variable_
57
+ # @param methods [Array<Symbol>] the method that exposes the value
58
+ # as well as its `key` in the underlying `Hash` model.
55
59
  def pass_writer(*methods)
56
60
  methods.each do |method|
57
61
  method = method.to_s.freeze
@@ -70,6 +74,8 @@ module Ecoportal
70
74
  # no chance you can avoid invinite loop for `get_key` without setting an
71
75
  # instance variable key at the moment of the object creation, when the
72
76
  # `doc` is firstly received
77
+ # @param method [Symbol] the method that exposes the value
78
+ # as well as its `key` in the underlying `Hash` model.
73
79
  def passkey(method)
74
80
  method = method.to_s.freeze
75
81
  var = instance_variable_name(method)
@@ -91,7 +97,33 @@ module Ecoportal
91
97
  self
92
98
  end
93
99
 
100
+ # These are methods that should always be present in patch update
101
+ # @note
102
+ # - `DoubleModel` can be used with objects that do not use `patch_ver`
103
+ # - This ensures that does that do, will get the correct patch update model
104
+ # @param method [Symbol] the method that exposes the value
105
+ # as well as its `key` in the underlying `Hash` model.
106
+ # @param default [Value] the default value that
107
+ # this `key` will be written in the model when it doesn't exixt
108
+ def passforced(method, default: , read_only: false)
109
+ model_forced_keys[method.to_s.freeze] = default
110
+ passthrough(method, read_only: read_only)
111
+ end
112
+
113
+ # Ensures `doc` has the `model_forced_keys`. If it doesn't, it adds those missing
114
+ # with the defined `default` values
115
+ def enforce!(doc)
116
+ return unless doc && doc.is_a?(Hash)
117
+ return if model_forced_keys.empty?
118
+ model_forced_keys.each do |key, default|
119
+ doc[key] = default unless doc.key?(key)
120
+ end
121
+ doc
122
+ end
123
+
94
124
  # Same as `attr_accessor` but links to a subjacent `Hash` model property
125
+ # @param methods [Array<Symbol>] the method that exposes the value
126
+ # as well as its `key` in the underlying `Hash` model.
95
127
  # @param read_only [Boolean] should it only define the reader?
96
128
  def passthrough(*methods, read_only: false)
97
129
  pass_reader *methods
@@ -101,6 +133,8 @@ module Ecoportal
101
133
 
102
134
  # To link as a `Time` date to a subjacent `Hash` model property
103
135
  # @see Ecoportal::API::Common::Content::DoubleModel#passthrough
136
+ # @param methods [Array<Symbol>] the method that exposes the value
137
+ # as well as its `key` in the underlying `Hash` model.
104
138
  # @param read_only [Boolean] should it only define the reader?
105
139
  def passdate(*methods, read_only: false)
106
140
  pass_reader(*methods) {|value| to_time(value)}
@@ -111,6 +145,8 @@ module Ecoportal
111
145
  end
112
146
 
113
147
  # To link as a `Boolean` to a subjacent `Hash` model property
148
+ # @param methods [Array<Symbol>] the method that exposes the value
149
+ # as well as its `key` in the underlying `Hash` model.
114
150
  # @param read_only [Boolean] should it only define the reader?
115
151
  def passboolean(*methods, read_only: false)
116
152
  pass_reader(*methods) {|value| value}
@@ -121,6 +157,8 @@ module Ecoportal
121
157
  end
122
158
 
123
159
  # To link as plain `Array` to a subjacent `Hash` model property
160
+ # @param methods [Array<Symbol>] the method that exposes the value
161
+ # as well as its `key` in the underlying `Hash` model.
124
162
  # @param order_matters [Boolean] does the order matter
125
163
  # @param uniq [Boolean] should it contain unique elements
126
164
  def passarray(*methods, order_matters: true, uniq: true)
@@ -142,6 +180,10 @@ module Ecoportal
142
180
  end
143
181
 
144
182
  # Helper to embed one nested object under one property
183
+ # @param method [Symbol] the method that exposes the embeded object
184
+ # @param key [Symbol] the `key` that embeds it to the underlying `Hash` model
185
+ # @nullable [Boolean] to specify if this object can be `nil`
186
+ # @param klass [Class, String] the class of the embedded object
145
187
  def embeds_one(method, key: method, nullable: false, klass:)
146
188
  embed(method, key: key, nullable: nullable, multiple: false, klass: klass)
147
189
  end
@@ -149,7 +191,11 @@ module Ecoportal
149
191
  # @note
150
192
  # - if you have a dedicated `Enumerable` class to manage `many`, you should use `:enum_class`
151
193
  # - otherwise, just indicate the child class in `:klass` and it will auto generate the class
152
- # @param
194
+ # @param method [Symbol] the method that exposes the embeded object
195
+ # @param key [Symbol] the `key` that embeds it to the underlying `Hash` model
196
+ # @param order_matters [Boolean] to state if the order will matter
197
+ # @param klass [Class, String] the class of the individual elements it embeds
198
+ # @param enum_class [Class, String] the class of the collection that will hold the individual elements
153
199
  def embeds_many(method, key: method, order_matters: false, order_key: nil, klass: nil, enum_class: nil)
154
200
  if enum_class
155
201
  eclass = enum_class
@@ -186,8 +232,15 @@ module Ecoportal
186
232
  end
187
233
  end
188
234
 
235
+ # The list of keys that will be forced in the model
236
+ def model_forced_keys
237
+ @forced_model_keys ||= {}
238
+ end
239
+
189
240
  end
190
241
 
242
+ inheritable_class_vars :forced_model_keys
243
+
191
244
  attr_reader :_parent, :_key
192
245
 
193
246
  def initialize(doc = {}, parent: self, key: nil)
@@ -195,6 +248,8 @@ module Ecoportal
195
248
  @_parent = parent || self
196
249
  @_key = key || self
197
250
 
251
+ self.class.enforce!(doc)
252
+
198
253
  if _parent == self
199
254
  @doc = doc
200
255
  @original_doc = JSON.parse(@doc.to_json)
@@ -211,11 +266,13 @@ module Ecoportal
211
266
  _parent.root
212
267
  end
213
268
 
269
+ # @return [String] the `value` of the `key` method (i.e. `id` value)
214
270
  def key
215
271
  raise "No key_method defined for #{self.class}" unless key_method?
216
272
  self.method(key_method).call
217
273
  end
218
274
 
275
+ # @param [String] the `value` of the `key` method (i.e. `id` value)
219
276
  def key=(value)
220
277
  raise "No key_method defined for #{self.class}" unless key_method?
221
278
  method = "#{key_method}="
@@ -234,16 +291,25 @@ module Ecoportal
234
291
  end
235
292
  end
236
293
 
294
+ # @return [nil, Hash] the underlying `Hash` model as is (carrying current changes)
237
295
  def doc
238
296
  raise UnlinkedModel.new(from: "#{self.class}#doc", key: _key) unless linked?
239
- return @doc if is_root?
240
- _parent.doc.dig(*[_doc_key(_key)].flatten)
297
+ if is_root?
298
+ @doc
299
+ else
300
+ _parent.doc.dig(*[_doc_key(_key)].flatten)
301
+ end
241
302
  end
242
303
 
304
+ # The `original_doc` holds the model as is now on server-side.
305
+ # @return [nil, Hash] the underlying `Hash` model as after last `consolidate!` changes
243
306
  def original_doc
244
307
  raise UnlinkedModel.new(from: "#{self.class}#original_doc", key: _key) unless linked?
245
- return @original_doc if is_root?
246
- _parent.original_doc.dig(*[_doc_key(_key)].flatten)
308
+ if is_root?
309
+ @original_doc
310
+ else
311
+ _parent.original_doc.dig(*[_doc_key(_key)].flatten)
312
+ end
247
313
  end
248
314
 
249
315
  def as_json
@@ -254,19 +320,31 @@ module Ecoportal
254
320
  doc.to_json(*args)
255
321
  end
256
322
 
323
+ # @return [nil, Hash] the patch `Hash` model including only the changes between
324
+ # `original_doc` and `doc`
257
325
  def as_update
258
326
  new_doc = as_json
259
327
  Common::Content::HashDiffPatch.patch_diff(new_doc, original_doc)
260
328
  end
261
329
 
330
+ # @return [Boolean] stating if there are changes
262
331
  def dirty?
263
332
  as_update != {}
264
333
  end
265
334
 
335
+ # It makes `original_doc` to be like `doc`
336
+ # @note
337
+ # - after executing it, there will be no pending changes
338
+ # - you should technically run this command, after a successful update request to the server
266
339
  def consolidate!
267
340
  replace_original_doc(JSON.parse(doc.to_json))
268
341
  end
269
342
 
343
+ # It makes `doc` to be like `original`
344
+ # @note
345
+ # - after executing it, changes in `doc` will be lost
346
+ # - you should technically run this command only if you want to remove certain changes
347
+ # @key [Symbol] the specific part of the model you want to `reset`
270
348
  def reset!(key = nil)
271
349
  if key
272
350
  keys = [key].flatten.compact
@@ -289,8 +367,8 @@ module Ecoportal
289
367
  @doc = new_doc
290
368
  else
291
369
  dig_set(_parent.doc, [_doc_key(_key)].flatten, new_doc)
292
- _parent.variable_remove!(_key)
293
- variables_remove!
370
+ _parent.variable_remove!(_key) unless new_doc
371
+ #variables_remove!
294
372
  end
295
373
  end
296
374
 
@@ -307,9 +385,9 @@ module Ecoportal
307
385
  def replace_original_doc(new_doc)
308
386
  raise UnlinkedModel.new(from: "#{self.class}#replace_original_doc", key: _key) unless linked?
309
387
  if is_root?
310
- @orginal_doc = new_doc
388
+ @original_doc = new_doc
311
389
  else
312
- dig_set(_parent.orginal_doc, [_doc_key(_key)].flatten, new_doc)
390
+ dig_set(_parent.original_doc, [_doc_key(_key)].flatten, new_doc)
313
391
  end
314
392
  end
315
393
 
@@ -331,11 +409,21 @@ module Ecoportal
331
409
 
332
410
  # Removes all the persistent variables
333
411
  def variables_remove!
412
+ #puts "going to remove vars: #{@_dim_vars} on #{self.class} (parent: #{identify_parent(self._parent)})"
334
413
  @_dim_vars.dup.map {|k| variable_remove!(k)}
335
414
  end
336
415
 
337
416
  private
338
417
 
418
+ def identify_parent(object)
419
+ case object
420
+ when Ecoportal::API::V2::Page::Stage
421
+ "stage #{object.name}"
422
+ when Ecoportal::API::V2::Page::Section
423
+ "section #{object.heading}"
424
+ end
425
+ end
426
+
339
427
  def instance_variable_name(key)
340
428
  self.class.instance_variable_name(key)
341
429
  end
@@ -60,6 +60,8 @@ module Ecoportal
60
60
  a == b
61
61
  end
62
62
 
63
+ # Compares `a` as charring changes of `b`
64
+ # @return [Hash] patch data object with only changes
63
65
  def patch_data(a, b = nil, delete: false)
64
66
  {}.tap do |data_hash|
65
67
  if delete
@@ -75,11 +77,17 @@ module Ecoportal
75
77
  data_hash[key] = patch_diff(a_value, b_value)
76
78
  data_hash.delete(key) if data_hash[key] == NO_CHANGES
77
79
  end
80
+ #if (data_hash.keys - ID_KEYS).empty?
78
81
  if (data_hash.keys - META_KEYS).empty?
79
82
  return NO_CHANGES
80
83
  else
81
- patch_ver = (b && b["patch_ver"]) || 1
82
- data_hash["patch_ver"] = patch_ver
84
+ #patch_ver = (b && b["patch_ver"]) || 1
85
+ #data_hash["patch_ver"] = patch_ver
86
+ if b && b.key?("patch_ver")
87
+ data_hash["patch_ver"] = b["patch_ver"]
88
+ elsif a && a.key?("patch_ver")
89
+ data_hash["patch_ver"] = a["patch_ver"]
90
+ end
83
91
  end
84
92
  end
85
93
  end
@@ -172,7 +180,9 @@ module Ecoportal
172
180
  arr.any? {|a| nested_array?(a)}
173
181
  when arr.length == 1
174
182
  arr = arr.first
175
- arr.any? {|item| item.is_a?(Hash)}
183
+ arr.any? do |item|
184
+ item.is_a?(Hash) && item.has_key?("patch_ver")
185
+ end
176
186
  else
177
187
  false
178
188
  end
@@ -7,14 +7,15 @@ module Ecoportal
7
7
  class << self
8
8
  def new_doc
9
9
  {
10
- "id" => new_uuid,
11
- "weight" => 9999
10
+ "id" => new_uuid,
11
+ "weight" => 99
12
12
  }
13
13
  end
14
14
  end
15
15
 
16
16
  passkey :id
17
- passthrough :patch_ver, :name
17
+ passforced :patch_ver, default: 1
18
+ passthrough :name
18
19
  passthrough :weight, :other_information
19
20
  passboolean :complete
20
21
 
@@ -25,9 +25,9 @@ module Ecoportal
25
25
  end
26
26
 
27
27
  def ordered_tasks
28
- actions.each_with_index.sort_by do |task, index|
29
- (task.weight >= 9999) ? [index, index] : [task.weight, index]
30
- end.map(&:first)
28
+ actions.sort_by.with_index do |task, index|
29
+ [task.weight, index]
30
+ end
31
31
  end
32
32
 
33
33
  # Quick config helper
@@ -11,9 +11,9 @@ module Ecoportal
11
11
  {"id" => new_uuid}
12
12
  end
13
13
  end
14
-
14
+
15
15
  passkey :id
16
- passthrough :patch_ver
16
+ passforced :patch_ver, default: 1
17
17
  end
18
18
  end
19
19
  end
@@ -19,9 +19,9 @@ module Ecoportal
19
19
  end
20
20
 
21
21
  def ordered_items
22
- items.each_with_index.sort_by do |item, index|
23
- (item.weight >= 9999) ? [index, index] : [item.weight, index]
24
- end.map(&:first)
22
+ items.sort_by.with_index do |item, index|
23
+ [item.weight, index]
24
+ end
25
25
  end
26
26
 
27
27
  private
@@ -8,14 +8,15 @@ module Ecoportal
8
8
  class << self
9
9
  def new_doc
10
10
  {
11
- "id" => new_uuid,
12
- "weight" => 9999
11
+ "id" => new_uuid,
12
+ "weight" => 9999
13
13
  }
14
14
  end
15
15
  end
16
16
 
17
17
  passkey :id
18
- passthrough :patch_ver, :label
18
+ passforced :patch_ver, default: 1
19
+ passthrough :label
19
20
  passthrough :weight
20
21
  passboolean :checked
21
22
  end
@@ -4,10 +4,20 @@ module Ecoportal
4
4
  class Page
5
5
  class Component
6
6
  class File < Common::Content::DoubleModel
7
+ class << self
8
+ def new_doc
9
+ {
10
+ "id" => new_uuid,
11
+ "position" => 99
12
+ }
13
+ end
14
+ end
15
+
7
16
  passkey :id
8
- passthrough :patch_ver, :position
9
- passthrough :file_size, :token, read_only: true
10
- passthrough :content_type, :file_container_id
17
+ passforced :patch_ver, default: 1
18
+ passthrough :position
19
+ passthrough :file_size, :content_type, :token, read_only: true
20
+ passthrough :file_container_id
11
21
  passdate :file_update_at, read_only: true
12
22
  end
13
23
  end
@@ -4,10 +4,46 @@ module Ecoportal
4
4
  class Page
5
5
  class Component
6
6
  class FilesField < Page::Component
7
- embeds_many :items, klass: "Ecoportal::API::V2::Page::File", order_key: :position
7
+ embeds_many :items, klass: "Ecoportal::API::V2::Page::Component::File", order_key: :position
8
+
9
+ def add_file(container_id, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
10
+ file_doc = items.items_class.new_doc
11
+ items.upsert!(file_doc, pos: pos, before: before, after: after) do |file|
12
+ file.file_container_id = container_id
13
+ if prev = previous_file(file)
14
+ file.position = prev.position
15
+ end
16
+ yield(file) if block_given?
17
+ fix_file_positions!
18
+ end
19
+ end
20
+
21
+ def ordered_files
22
+ items.sort_by.with_index do |file, index|
23
+ [file.position, index]
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def fix_file_positions!
30
+ ordered_files.each_with_index do |file, index|
31
+ file.position = index
32
+ end
33
+ end
34
+
35
+ def previous_file(value)
36
+ fls = ordered_files
37
+ pos = fls.index(value) - 1
38
+ return if pos < 0
39
+ fls[pos]
40
+ end
41
+
8
42
  end
9
43
  end
10
44
  end
11
45
  end
12
46
  end
13
47
  end
48
+
49
+ require 'ecoportal/api/v2/page/component/file'
@@ -21,9 +21,9 @@ module Ecoportal
21
21
  end
22
22
 
23
23
  def ordered_stops
24
- stops.each_with_index.sort_by do |stop, index|
25
- (stop.threshold >= 9999) ? [index, index] : [stop.threshold, index]
26
- end.map(&:first)
24
+ stops.sort_by.with_index do |stop, index|
25
+ [stop.threshold, index]
26
+ end
27
27
  end
28
28
 
29
29
  end
@@ -8,16 +8,16 @@ module Ecoportal
8
8
  class << self
9
9
  def new_doc
10
10
  {
11
- "id" => new_uuid,
12
- "threshold" => nil,
13
- "color" => nil
11
+ "id" => new_uuid,
12
+ "threshold" => nil,
13
+ "color" => nil
14
14
  }
15
15
  end
16
16
  end
17
17
 
18
18
  passkey :id
19
- passthrough :patch_ver, :threshold
20
- passthrough :color
19
+ passforced :patch_ver, default: 1
20
+ passthrough :threshold, :color
21
21
 
22
22
  # Assign the color to the stop.
23
23
  # @note These are the available colors:
@@ -5,7 +5,8 @@ module Ecoportal
5
5
  class Component
6
6
  class Image < Common::Content::DoubleModel
7
7
  passkey :id
8
- passthrough :patch_ver, :weight
8
+ passforced :patch_ver, default: 1
9
+ passthrough :weight
9
10
  passthrough :height, :width, :caption
10
11
  passthrough :dimensions, :styles
11
12
  end
@@ -4,6 +4,7 @@ module Ecoportal
4
4
  class Page
5
5
  class Component
6
6
  class NumberField < Page::Component
7
+ passthrough :value
7
8
  end
8
9
  end
9
10
  end
@@ -7,7 +7,7 @@ module Ecoportal
7
7
  passboolean :is_me_button
8
8
  passthrough :attach_mode
9
9
  passthrough :person_schema_id
10
- pass_reader :viewable_fields
10
+ embeds_many :viewable_fields, klass: "Ecoportal::API::V2::Page::Component::PeopleViewableField"
11
11
 
12
12
  passboolean :singular
13
13
  passthrough :requires_number
@@ -30,6 +30,16 @@ module Ecoportal
30
30
  people_ids.reject! {|id| ids.include?(id)}
31
31
  end
32
32
 
33
+ # Adds a field to the `viewable_fields`
34
+ def add_viewable(field_id, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
35
+ viewable_fields.upsert!({"id" => field_id}, pos: pos, before: before, after: after)
36
+ end
37
+
38
+ # Deletes a field from the `viewable_fields`
39
+ def delete_viewable(field_id)
40
+ viewable_fields.delete!(field_id)
41
+ end
42
+
33
43
  # Quick config helper
34
44
  # @param conf [Symbol, Array<Symbol>]
35
45
  # - `:snapshot` to set mode to `snapshot`
@@ -64,7 +74,7 @@ module Ecoportal
64
74
  unless (rest = hash_except(cnf.dup, *supported)).empty?
65
75
  unused.push(rest)
66
76
  end
67
-
77
+
68
78
  if cnf.key?(:singular) then self.singular = !!cnf[:singular] end
69
79
  if cnf.key?(:permits)
70
80
  if permits = cnf[:permits]
@@ -121,3 +131,5 @@ module Ecoportal
121
131
  end
122
132
  end
123
133
  end
134
+
135
+ require 'ecoportal/api/v2/page/component/people_viewable_field'
@@ -0,0 +1,14 @@
1
+ module Ecoportal
2
+ module API
3
+ class V2
4
+ class Page
5
+ class Component
6
+ class PeopleViewableField < Common::Content::DoubleModel
7
+ passkey :id
8
+ passthrough :type, read_only: true
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -58,9 +58,9 @@ module Ecoportal
58
58
  end
59
59
 
60
60
  def ordered_options
61
- options.each_with_index.sort_by do |option, index|
62
- (option.weight >= 9999) ? [index, index] : [option.weight, index]
63
- end.map(&:first)
61
+ options.sort_by.with_index do |option, index|
62
+ [option.weight, index]
63
+ end
64
64
  end
65
65
 
66
66
  # Quick config helper
@@ -8,14 +8,15 @@ module Ecoportal
8
8
  class << self
9
9
  def new_doc
10
10
  {
11
- "id" => new_uuid,
12
- "weight" => 9999
11
+ "id" => new_uuid,
12
+ "weight" => 9999
13
13
  }
14
14
  end
15
15
  end
16
16
 
17
17
  passkey :id
18
- passthrough :patch_ver, :name, :value
18
+ passforced :patch_ver, default: 1
19
+ passthrough :name, :value
19
20
  passthrough :weight
20
21
  passboolean :selected
21
22
 
@@ -13,8 +13,9 @@ module Ecoportal
13
13
  end
14
14
  end
15
15
 
16
- passthrough :signed_by_id, :signed_by_name, :signature_url
17
- passdate :signature_updated_at
16
+ passthrough :signed_by_id, :signed_by_name, read_only: true
17
+ passthrough :signature_url, read_only: true
18
+ passdate :signature_updated_at, read_only: true
18
19
  passthrough :signature_content, :color
19
20
 
20
21
  end
@@ -26,13 +26,16 @@ module Ecoportal
26
26
 
27
27
  class << self
28
28
  def new_doc(type: nil)
29
- if type
30
- type_doc = {"type" => type}
31
- base_doc = get_class(type_doc)&.new_doc || {}
32
- base_doc.merge!(type_doc)
29
+ {
30
+ "id" => new_uuid
31
+ }.tap do |base_doc|
32
+ if type
33
+ base_doc.merge!({"type" => type})
34
+ if klass = get_class(base_doc)
35
+ base_doc.merge!(klass.new_doc || {})
36
+ end
37
+ end
33
38
  end
34
- return base_doc if base_doc&.key?("id")
35
- (base_doc || {}).merge("id" => new_uuid)
36
39
  end
37
40
 
38
41
  def get_class(doc)
@@ -82,7 +85,8 @@ module Ecoportal
82
85
  end
83
86
 
84
87
  passkey :id
85
- passthrough :patch_ver, :undeletable
88
+ passforced :patch_ver, default: 1
89
+ passboolean :undeletable
86
90
  passthrough :type, :label, :tooltip, :global_binding
87
91
  passboolean :hidden, :deindex, :required
88
92
  passthrough :accent
@@ -4,9 +4,10 @@ module Ecoportal
4
4
  class Page
5
5
  class Permit < Common::Content::DoubleModel
6
6
  passkey :id
7
- passthrough :patch_ver
7
+ passforced :patch_ver, default: 1
8
8
  passthrough :user_id, :user_name
9
9
  passthrough :editable, :flags
10
+ embeds_one :flags, klass: "Ecoportal::API::V2::Page::PermissionFlags"
10
11
  end
11
12
  end
12
13
  end
@@ -3,12 +3,14 @@ module Ecoportal
3
3
  class V2
4
4
  class Page
5
5
  class Section < Common::Content::DoubleModel
6
+ INITIAL_WEIGHT = 9999
7
+
6
8
  class << self
7
9
  def new_doc(split: false)
8
10
  {
9
- "id" => new_uuid,
10
- "type" => split ? "split" : "content",
11
- "weight" => 800
11
+ "id" => new_uuid,
12
+ "type" => split ? "split" : "content",
13
+ "weight" => INITIAL_WEIGHT
12
14
  }.tap do |out|
13
15
  component_ids = if split
14
16
  {
@@ -26,10 +28,11 @@ module Ecoportal
26
28
  end
27
29
 
28
30
  passkey :id
29
- passthrough :patch_ver, :weight, :type
31
+ passforced :patch_ver, default: 1
32
+ passthrough :weight, :type
30
33
  passthrough :heading, :left_heading, :right_heading
31
34
  passarray :component_ids, :left_component_ids, :right_component_ids
32
- passthrough :minimized
35
+ passboolean :minimized
33
36
 
34
37
  def split?
35
38
  doc && doc["type"] == "split"
@@ -77,8 +80,9 @@ module Ecoportal
77
80
  # @param field [Ecoportal::API::V2::Page::Component] the field to be added.
78
81
  def add_component(field, after: nil, side: nil)
79
82
  raise "field should be a Ecoportal::API::V2::Page::Component. Given: #{field.class}" unless field.is_a?(Ecoportal::API::V2::Page::Component)
83
+ # IMPORTANT NOTE: The code below creates objects, because field.section does a search on section.component_ids
80
84
  if field.section == self
81
- raise "Field with id '#{field.id}' already belongs to this section"
85
+ puts "Field with id '#{field.id}' already belongs to this section"
82
86
  elsif sec = field.section
83
87
  # Field belongs to another section
84
88
  raise "Field with id '#{field.id}' belongs to section '#{sec.heading || "Unnamed"}' (id: '#{sec.id}')"
@@ -91,6 +95,7 @@ module Ecoportal
91
95
  ids_ary = component_ids
92
96
  fields = components
93
97
  end
98
+
94
99
  if after
95
100
  after_fld = fields.find do |fld|
96
101
  found = nil
@@ -99,6 +104,7 @@ module Ecoportal
99
104
  found ||= same_string?(fld.label, after)
100
105
  end
101
106
  end
107
+
102
108
  ids_ary.insert_one(field.id, after: after_fld&.id)
103
109
  self
104
110
  end
@@ -8,11 +8,15 @@ module Ecoportal
8
8
  self.klass = :section_class
9
9
 
10
10
  # Creates a new `section`
11
+ # @note
12
+ # - It won't fix weights unless all the sections of the ooze are present
13
+ # - This means that it doesn't fix section weights on stages,
14
+ # as shared sections could change order in other stages
11
15
  def add(name: nil, split: false, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
12
16
  sec_doc = section_class.new_doc(split: split)
13
17
  upsert!(sec_doc) do |section| #, pos: pos, before: before, after: after) do |section|
14
18
  section.heading = name
15
- if weight = scope_weight(pos: pos, before: before, after: after)
19
+ if weight = scope_weight(section, pos: pos, before: before, after: after)
16
20
  section.weight = weight
17
21
  end
18
22
  fix_weights!
@@ -51,13 +55,13 @@ module Ecoportal
51
55
  # Gets the sections ordered by `weight` (as they appear in the page)
52
56
  def ordered
53
57
  self.sort_by.with_index do |section, index|
54
- (section.weight >= 9999) ? [index, index] : [section.weight, index]
58
+ [section.weight, index]
55
59
  end
56
60
  end
57
61
 
58
62
  private
59
63
 
60
- def scope_weight(pos: NOT_USED, before: NOT_USED, after: NOT_USED)
64
+ def scope_weight(section, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
61
65
  case
62
66
  when used_param?(pos)
63
67
  if pos = to_section(pos)
@@ -71,6 +75,11 @@ module Ecoportal
71
75
  if after = to_section(after)
72
76
  after.weight
73
77
  end
78
+ end.yield_self do |weight|
79
+ weight = ordered.reject do |sec|
80
+ sec.id == section.id
81
+ end.last&.weight
82
+ weight ||= section_class.const_get(:INITIAL_WEIGHT)
74
83
  end
75
84
  end
76
85
 
@@ -86,8 +95,10 @@ module Ecoportal
86
95
  end
87
96
 
88
97
  def fix_weights!
89
- ordered.each_with_index do |section, index|
90
- section.weight = index
98
+ unless self._parent.is_a?(Ecoportal::API::V2::Pages::PageStage)
99
+ ordered.each_with_index do |section, index|
100
+ section.weight = index
101
+ end
91
102
  end
92
103
  end
93
104
 
@@ -4,7 +4,7 @@ module Ecoportal
4
4
  class Page
5
5
  class Stage < Common::Content::DoubleModel
6
6
  passkey :id
7
- passthrough :patch_ver
7
+ passforced :patch_ver, default: 1
8
8
  passthrough :name, :ordering
9
9
  passarray :subtags, order_matters: false
10
10
  passarray :section_ids
@@ -22,7 +22,7 @@ module Ecoportal
22
22
  root.sections.values_at(*sec_ids).select.with_index do |sec, i|
23
23
  puts "Warning: section #{id} points to missing section #{sec_ids[i]}" if !sec
24
24
  fld && (!block_given? || yield(sec))
25
- end.sort_by {|sec| sec.weight}
25
+ end.sort_by.with_index {|sec, index| [sec.weight, index]}
26
26
  end
27
27
 
28
28
  def add_section(*secs)
@@ -14,9 +14,9 @@ module Ecoportal
14
14
  end
15
15
 
16
16
  #def ordered
17
- # self.each_with_index.sort_by do |stage, index|
18
- # (stage.ordering >= 9999) ? [index, index] : [stage.ordering, index]
19
- # end.map(&:first)
17
+ # self.sort_by.with_index do |stage, index|
18
+ # [stage.ordering, index]
19
+ # end
20
20
  #end
21
21
 
22
22
  end
@@ -2,9 +2,19 @@ module Ecoportal
2
2
  module API
3
3
  class V2
4
4
  class Page < Common::Content::DoubleModel
5
- ALLOWED_KEYS = %w[id patch_ver name template_id base_tags tags time_zone created_at updated_at can components sections stages]
5
+ ALLOWED_KEYS = [
6
+ "id", "patch_ver", "name", "template_id",
7
+ "base_tags", "tags",
8
+ "time_zone", "created_at", "updated_at",
9
+ "components", "sections", "stages",
10
+ "permits", "mould_counter", "mould",
11
+ "state", "task_priority",
12
+ "votes_enabled", "upvotes", "downvotes",
13
+ "force_errors", "subtags"
14
+ ]
15
+
6
16
  passkey :id
7
- passthrough :patch_ver
17
+ passforced :patch_ver, default: 1
8
18
  passthrough :name, :template_id
9
19
  passarray :base_tags, :tags, order_matters: false
10
20
  passthrough :time_zone
@@ -19,12 +29,50 @@ module Ecoportal
19
29
  embeds_many :sections, enum_class: :sections_class
20
30
  embeds_many :stages, enum_class: :stages_class
21
31
 
32
+ def initialize(doc = [], parent: self, key: nil)
33
+ super(_doc_bug_fix(doc), parent: parent, key: key)
34
+ end
35
+
22
36
  def as_update
23
37
  super.tap do |hash|
24
38
  unless !hash
25
39
  hash["data"].select! do |key, value|
26
40
  ALLOWED_KEYS.include?(key)
27
41
  end
42
+ return nil if (hash["data"].keys - ["patch_ver"]).empty?
43
+ end
44
+ end
45
+ end
46
+
47
+ def stages?
48
+ self.stages.count > 0
49
+ end
50
+
51
+ private
52
+
53
+ def _doc_bug_fix(hash)
54
+ hash.tap do |hash|
55
+ _fix_doc(hash["stages"], "flow_node_ids", "section_ids") if hash.key?("stages")
56
+ if hash.key?("sections")
57
+ _fix_doc(hash["sections"], "membrane_ids", "component_ids")
58
+ _fix_doc(hash["sections"], "left_membrane_ids", "left_component_ids")
59
+ _fix_doc(hash["sections"], "right_membrane_ids", "right_component_ids")
60
+ end
61
+ end
62
+ end
63
+
64
+ def _fix_doc(value, source, dest)
65
+ value.tap do |value|
66
+ case value
67
+ when Array
68
+ value.each {|v| _fix_doc(v, source, dest)}
69
+ when Hash
70
+ if value.key?(source) && !value.key?(dest)
71
+ value[dest] = value[source]
72
+ value.delete(source)
73
+ end
74
+ else
75
+ # Do nothing!
28
76
  end
29
77
  end
30
78
  end
@@ -9,6 +9,19 @@ module Ecoportal
9
9
 
10
10
  embeds_many :permits, klass: "Ecoportal::API::V2::Page::Permit"
11
11
  passarray :force_errors, :subtags, order_matters: false
12
+
13
+ # `id` of the stage we got the data of.
14
+ def current_stage_id
15
+ doc.dig("active_stage", "id") || doc["current_stage_id"]
16
+ end
17
+
18
+ # @return [Ecoportal::API::V2::Page::Stage]
19
+ def current_stage
20
+ if stage_id = current_stage_id
21
+ stages[stage_id]
22
+ end
23
+ end
24
+
12
25
  end
13
26
  end
14
27
  end
@@ -47,10 +47,13 @@ module Ecoportal
47
47
  end
48
48
 
49
49
  # Requests to update an existing page via api.
50
+ # @note It won't launch the update unless there are changes
50
51
  # @param doc [Hash, Page] data that at least contains an `id` (internal or external) of the target page.
51
52
  # @return [Response] an object with the api response.
52
53
  def update(doc)
53
54
  body = get_body(doc) # , level: "page"
55
+ # Launch only if there are changes
56
+ raise "Missing page object" unless body && body["page"]
54
57
  id = get_id(doc)
55
58
  client.patch("/pages/#{CGI.escape(id)}", data: body)
56
59
  end
@@ -0,0 +1,13 @@
1
+ module Ecoportal
2
+ module API
3
+ class V2
4
+ class Registers
5
+ class SearchResults < Common::Content::DoubleModel
6
+ passthrough :total, :total_before_filtering
7
+ passarray :tags, order_matters: false
8
+ embeds_many :results, klass: "Ecoportal::API::V2::Registers::PageResult"
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -9,6 +9,7 @@ module Ecoportal
9
9
 
10
10
  class_resolver :register_class, "Ecoportal::API::V2::Registers::Register"
11
11
  class_resolver :register_search_result_class, "Ecoportal::API::V2::Registers::PageResult"
12
+ class_resolver :register_search_results, "Ecoportal::API::V2::Registers::SearchResults"
12
13
 
13
14
  attr_reader :client
14
15
 
@@ -35,7 +36,12 @@ module Ecoportal
35
36
  # @param options [Hash] the search options
36
37
  # @option options [Hash<Symbol, String>] :query plain search (like the search box in register).
37
38
  # @option options [Hash<Symbol, Array<Object>>] :filters the set of filters.
39
+ # @option options [Boolean] if `true`, it only performs the first search and results `Ecoportal::API::V2::Registers::SearchResults`.
40
+ # @yield [result] something to do with search page-result.
41
+ # @yieldparam result [Ecoportal::V2::Registers::PageResult] a page result.
42
+ # @return [Ecoportal::API::V2::Registers, Ecoportal::API::V2::Registers::SearchResults]
38
43
  def search(register_id, options = {})
44
+ only_first = options.delete(:only_first)
39
45
  # supply a query string
40
46
  # or a filter array (copy/paste from dev tools in the browser)
41
47
  options = {query: nil, filters: []}.update(options)
@@ -49,6 +55,12 @@ module Ecoportal
49
55
  end
50
56
  end
51
57
 
58
+ if only_first
59
+ response = client.get("/registers/#{register_id}/search", params: options)
60
+ raise "Request failed - Status #{response.status}: #{response.body}" unless response.success?
61
+ return register_search_results.new(response.body["data"])
62
+ end
63
+
52
64
  cursor_id = nil
53
65
  results = 0
54
66
  loop do
@@ -70,8 +82,8 @@ module Ecoportal
70
82
  yield object
71
83
  end
72
84
 
73
- # break unless (cursor_id = data["cursor_id"])
74
- break if total == results
85
+ break if total <= results
86
+ break unless (cursor_id = data["cursor_id"])
75
87
  end
76
88
  self
77
89
  end
@@ -87,3 +99,4 @@ require 'ecoportal/api/v2/registers/register'
87
99
  require 'ecoportal/api/v2/registers/stage_result'
88
100
  require 'ecoportal/api/v2/registers/stages_result'
89
101
  require 'ecoportal/api/v2/registers/page_result'
102
+ require 'ecoportal/api/v2/registers/search_results'
@@ -1,5 +1,5 @@
1
1
  module Ecoportal
2
2
  module API
3
- GEM2_VERSION = "0.8.9"
3
+ GEM2_VERSION = "0.8.13"
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.9
4
+ version: 0.8.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oscar Segura
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-08-16 00:00:00.000000000 Z
11
+ date: 2021-09-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -209,6 +209,7 @@ files:
209
209
  - lib/ecoportal/api/v2/page/component/law_field.rb
210
210
  - lib/ecoportal/api/v2/page/component/number_field.rb
211
211
  - lib/ecoportal/api/v2/page/component/people_field.rb
212
+ - lib/ecoportal/api/v2/page/component/people_viewable_field.rb
212
213
  - lib/ecoportal/api/v2/page/component/plain_text_field.rb
213
214
  - lib/ecoportal/api/v2/page/component/reference_field.rb
214
215
  - lib/ecoportal/api/v2/page/component/rich_text_field.rb
@@ -230,6 +231,7 @@ files:
230
231
  - lib/ecoportal/api/v2/registers.rb
231
232
  - lib/ecoportal/api/v2/registers/page_result.rb
232
233
  - lib/ecoportal/api/v2/registers/register.rb
234
+ - lib/ecoportal/api/v2/registers/search_results.rb
233
235
  - lib/ecoportal/api/v2/registers/stage_result.rb
234
236
  - lib/ecoportal/api/v2/registers/stages_result.rb
235
237
  - lib/ecoportal/api/v2/registers/template.rb