ecoportal-api-oozes 0.5.5 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -0
- data/ecoportal-api-oozes.gemspec +2 -2
- data/lib/ecoportal/api-oozes.rb +2 -2
- data/lib/ecoportal/api/common/content/array_model.rb +0 -1
- data/lib/ecoportal/api/common/content/collection_model.rb +42 -8
- data/lib/ecoportal/api/common/content/double_model.rb +18 -11
- data/lib/ecoportal/api/common/content/hash_diff_patch.rb +21 -6
- data/lib/ecoportal/api/common/content/string_digest.rb +9 -4
- data/lib/ecoportal/api/v2.rb +0 -1
- data/lib/ecoportal/api/v2/page.rb +12 -0
- data/lib/ecoportal/api/v2/page/component.rb +11 -0
- data/lib/ecoportal/api/v2/page/component/action_field.rb +2 -2
- data/lib/ecoportal/api/v2/page/component/checklist_field.rb +2 -2
- data/lib/ecoportal/api/v2/page/component/files_field.rb +2 -2
- data/lib/ecoportal/api/v2/page/component/images_field.rb +2 -2
- data/lib/ecoportal/api/v2/page/component/people_field.rb +5 -0
- data/lib/ecoportal/api/v2/page/component/selection_field.rb +63 -2
- data/lib/ecoportal/api/v2/page/component/selection_option.rb +9 -0
- data/lib/ecoportal/api/v2/page/components.rb +22 -0
- data/lib/ecoportal/api/v2/page/section.rb +25 -3
- data/lib/ecoportal/api/v2/page/sections.rb +33 -0
- data/lib/ecoportal/api/v2/page/stage.rb +13 -0
- data/lib/ecoportal/api/v2/page/stages.rb +6 -0
- data/lib/ecoportal/api/v2/pages.rb +34 -7
- data/lib/ecoportal/api/v2/pages/page_stage.rb +11 -0
- data/lib/ecoportal/api/v2/pages/stages.rb +52 -0
- data/lib/ecoportal/api/v2/version.rb +1 -1
- metadata +13 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 65d013d143d1c5dc7b19de58086d973dedc454dbdc89f4ac1d5525e58342c457
|
4
|
+
data.tar.gz: f083e27753e51add116d0aeb12ebc13632dc1834a42e5b690f0da353216b2f4f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 90b0d48b663d8698b33e56d113a44b84197a48fc47b29640abae653fe4b49740bc975fb6e0781e24dea5ee5bc3a29dababafab008adc893c13fda0157ae91793
|
7
|
+
data.tar.gz: af2a47022b66bc5238b2c5a3235c192d5f164493d221d3f94c95f3156962dcbdb5749376abc8218cd8023d84b03c6a31fd8c23d54c2324f815c4e41b3e464041
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# Change Log
|
2
|
+
All notable changes to this project will be documented in this file.
|
3
|
+
|
4
|
+
## [0.6.0] - 2020-07-xx
|
5
|
+
|
6
|
+
### Added
|
7
|
+
### Changed
|
8
|
+
- upgraded `ecoportal-api` gem
|
9
|
+
### Fixed
|
10
|
+
|
11
|
+
## [0.5.9] - 2020-07-02
|
12
|
+
|
13
|
+
### Added
|
14
|
+
- helper `Ecoportal::API::Common::Content::StringDigest#indexable_label`: to see the part of a label that gets indexed
|
15
|
+
- this `CHANGELOG.md` file
|
16
|
+
### Changed
|
17
|
+
### Fixed
|
data/ecoportal-api-oozes.gemspec
CHANGED
@@ -5,7 +5,7 @@ require "ecoportal/api/v2/version"
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "ecoportal-api-oozes"
|
8
|
-
spec.version = Ecoportal::API::V2::
|
8
|
+
spec.version = Ecoportal::API::V2::GEM_VERSION
|
9
9
|
spec.authors = ["Oscar Segura"]
|
10
10
|
spec.email = ["rien@ecoportal.co.nz", "oscar@ecoportal.co.nz", "bozydar@ecoportal.co.nz"]
|
11
11
|
|
@@ -27,5 +27,5 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.add_development_dependency "redcarpet", "~> 3.5", ">= 3.5.0"
|
28
28
|
spec.add_development_dependency "pry"
|
29
29
|
|
30
|
-
spec.add_dependency 'ecoportal-api', '~> 0.
|
30
|
+
spec.add_dependency 'ecoportal-api', '~> 0.6', '>= 0.6.0'
|
31
31
|
end
|
data/lib/ecoportal/api-oozes.rb
CHANGED
@@ -145,18 +145,20 @@ module Ecoportal
|
|
145
145
|
# Tries to find the element `value`, if it exists, it updates it
|
146
146
|
# Otherwise it pushes it to the end
|
147
147
|
# @return the element
|
148
|
-
def upsert!(value)
|
148
|
+
def upsert!(value, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
|
149
149
|
unless value.is_a?(Hash) || value.is_a?(Content::DoubleModel)
|
150
150
|
raise "'Content::DoubleModel' or 'Hash' doc required"
|
151
151
|
end
|
152
152
|
item_doc = value.is_a?(Content::DoubleModel)? value.doc : value
|
153
|
+
item_doc = JSON.parse(item_doc.to_json)
|
153
154
|
if item = self[value]
|
154
|
-
item.replace_doc(
|
155
|
+
item.replace_doc(item_doc)
|
155
156
|
else
|
156
|
-
|
157
|
-
|
157
|
+
_doc_upsert(item_doc, pos: pos, before: before, after: after)
|
158
|
+
end
|
159
|
+
(item || self[item_doc]).tap do |item|
|
160
|
+
yield(item) if block_given?
|
158
161
|
end
|
159
|
-
item
|
160
162
|
end
|
161
163
|
|
162
164
|
protected
|
@@ -165,6 +167,10 @@ module Ecoportal
|
|
165
167
|
def uniq?; self.class.uniq; end
|
166
168
|
def items_key; self.class.items_key; end
|
167
169
|
|
170
|
+
def on_change
|
171
|
+
variables_remove!
|
172
|
+
end
|
173
|
+
|
168
174
|
# Gets the `key` of the object
|
169
175
|
def get_key(value)
|
170
176
|
case value
|
@@ -198,11 +204,9 @@ module Ecoportal
|
|
198
204
|
self.class.new_item(value, parent: self)
|
199
205
|
end
|
200
206
|
|
201
|
-
private
|
202
|
-
|
203
207
|
# Helper to remove tracked down instance variables
|
204
208
|
def variable_remove!(key)
|
205
|
-
if (k = get_key(key)) && (item = @items_by_key[k])
|
209
|
+
if @items_by_key && (k = get_key(key)) && (item = @items_by_key[k])
|
206
210
|
_items.delete(item) if _items.include?(item)
|
207
211
|
@items_by_key.delete(k)
|
208
212
|
else
|
@@ -216,6 +220,36 @@ module Ecoportal
|
|
216
220
|
super
|
217
221
|
end
|
218
222
|
|
223
|
+
def _doc_upsert(value, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
|
224
|
+
current_pos = _doc_key(value)
|
225
|
+
pos = case
|
226
|
+
when used_param?(pos)
|
227
|
+
pos
|
228
|
+
when used_param?(before)
|
229
|
+
_doc_key(before)
|
230
|
+
when used_param?(after)
|
231
|
+
puts "to add after #{after.id}"
|
232
|
+
if i = _doc_key(after)
|
233
|
+
i + 1
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
pos ||= current_pos
|
238
|
+
|
239
|
+
if current_pos && pos
|
240
|
+
_doc_items.delete(current_pos)
|
241
|
+
pos = (pos <= current_pos)? pos : pos - 1
|
242
|
+
end
|
243
|
+
|
244
|
+
pos = (pos && pos < _doc_items.length)? pos : _doc_items.length
|
245
|
+
|
246
|
+
pos.tap do |i|
|
247
|
+
_doc_items.insert(pos, value)
|
248
|
+
on_change
|
249
|
+
end
|
250
|
+
|
251
|
+
end
|
252
|
+
|
219
253
|
end
|
220
254
|
end
|
221
255
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
1
3
|
module Ecoportal
|
2
4
|
module API
|
3
5
|
module Common
|
@@ -28,6 +30,10 @@ module Ecoportal
|
|
28
30
|
@key = value.to_s.freeze
|
29
31
|
end
|
30
32
|
|
33
|
+
def new_uuid(length: 12)
|
34
|
+
SecureRandom.hex(length)
|
35
|
+
end
|
36
|
+
|
31
37
|
# Same as `attr_reader` but links to a subjacent `Hash` model property
|
32
38
|
# @note it does **not** create an _instance variable_
|
33
39
|
def pass_reader(*methods)
|
@@ -153,6 +159,7 @@ module Ecoportal
|
|
153
159
|
|
154
160
|
embeds_one(method, key: key, multiple: true, klass: dim_class)
|
155
161
|
end
|
162
|
+
|
156
163
|
end
|
157
164
|
|
158
165
|
attr_reader :_parent, :_key
|
@@ -250,16 +257,6 @@ module Ecoportal
|
|
250
257
|
# self
|
251
258
|
#end
|
252
259
|
|
253
|
-
protected
|
254
|
-
|
255
|
-
def is_root?
|
256
|
-
_parent == self && !!defined?(@doc)
|
257
|
-
end
|
258
|
-
|
259
|
-
def linked?
|
260
|
-
is_root? || !!_parent.doc
|
261
|
-
end
|
262
|
-
|
263
260
|
def replace_doc(new_doc)
|
264
261
|
raise UnlinkedModel.new(from: "#{self.class}#replace_doc", key: _key) unless linked?
|
265
262
|
if is_root?
|
@@ -271,6 +268,16 @@ module Ecoportal
|
|
271
268
|
end
|
272
269
|
end
|
273
270
|
|
271
|
+
protected
|
272
|
+
|
273
|
+
def is_root?
|
274
|
+
_parent == self && !!defined?(@doc)
|
275
|
+
end
|
276
|
+
|
277
|
+
def linked?
|
278
|
+
is_root? || !!_parent.doc
|
279
|
+
end
|
280
|
+
|
274
281
|
def replace_original_doc(new_doc)
|
275
282
|
raise UnlinkedModel.new(from: "#{self.class}#replace_original_doc", key: _key) unless linked?
|
276
283
|
if is_root?
|
@@ -298,7 +305,7 @@ module Ecoportal
|
|
298
305
|
|
299
306
|
# Removes all the persistent variables
|
300
307
|
def variables_remove!
|
301
|
-
@_dim_vars.map {|k| variable_remove!(k)}
|
308
|
+
@_dim_vars.dup.map {|k| variable_remove!(k)}
|
302
309
|
end
|
303
310
|
|
304
311
|
private
|
@@ -31,6 +31,8 @@ module Ecoportal
|
|
31
31
|
# 3. the `data` property holds the specific changes of the object
|
32
32
|
# - the `patch_ver` (compulsory) is **incremental** (for data integrity)
|
33
33
|
# - the properties that have changed
|
34
|
+
# @note
|
35
|
+
# * there should not be difference between `null` and `""` (empty string)
|
34
36
|
# @param a [Hash] current hash model
|
35
37
|
# @param b [Hash] previous hash model
|
36
38
|
# @return [Hash] a `patch data`
|
@@ -51,12 +53,19 @@ module Ecoportal
|
|
51
53
|
|
52
54
|
private
|
53
55
|
|
56
|
+
def equal_values(a, b)
|
57
|
+
if a.is_a?(String) || b.is_a?(String)
|
58
|
+
return true if a.to_s.strip.empty? && b.to_s.strip.empty?
|
59
|
+
end
|
60
|
+
a == b
|
61
|
+
end
|
62
|
+
|
54
63
|
def patch_data(a, b = nil)
|
55
64
|
{}.tap do |data_hash|
|
56
65
|
a.each do |key, a_value|
|
57
66
|
b_value = b[key] if b_has_key = b && b.key?(key)
|
58
67
|
is_meta_key = META_KEYS.include?(key)
|
59
|
-
skip_equals = b_has_key && a_value
|
68
|
+
skip_equals = b_has_key && equal_values(a_value, b_value)
|
60
69
|
next if is_meta_key || skip_equals
|
61
70
|
data_hash[key] = patch_diff(a_value, b_value)
|
62
71
|
data_hash.delete(key) if data_hash[key] == NO_CHANGES
|
@@ -99,14 +108,19 @@ module Ecoportal
|
|
99
108
|
end
|
100
109
|
|
101
110
|
def patch_data_array(a, b)
|
111
|
+
original_b = b
|
102
112
|
a ||= []; b ||= []
|
103
113
|
if !nested_array?(a, b)
|
104
114
|
if a.length == b.length && (a & b).length == b.length
|
105
|
-
|
115
|
+
if original_b
|
116
|
+
NO_CHANGES
|
117
|
+
else
|
118
|
+
a
|
119
|
+
end
|
106
120
|
else
|
107
121
|
a
|
108
122
|
end
|
109
|
-
else
|
123
|
+
else # array with nested elements
|
110
124
|
a_ids = array_ids(a)
|
111
125
|
b_ids = array_ids(b)
|
112
126
|
|
@@ -116,19 +130,20 @@ module Ecoportal
|
|
116
130
|
|
117
131
|
arr_delete = del_ids.map do |id|
|
118
132
|
patch_delete(array_id_item(b, id))
|
119
|
-
end
|
133
|
+
end.compact
|
120
134
|
|
121
135
|
arr_update = oth_ids.map do |id|
|
122
136
|
patch_update(array_id_item(a, id), array_id_item(b, id))
|
123
|
-
end
|
137
|
+
end.compact
|
124
138
|
|
125
139
|
arr_new = new_ids.map do |id|
|
126
140
|
patch_new(array_id_item(a, id))
|
127
|
-
end
|
141
|
+
end.compact
|
128
142
|
|
129
143
|
(arr_delete.concat(arr_update).concat(arr_new)).tap do |patch_array|
|
130
144
|
# remove data with no `id`
|
131
145
|
patch_array.reject! {|item| !item.is_a?(Hash)}
|
146
|
+
return NO_CHANGES if patch_array.empty?
|
132
147
|
end
|
133
148
|
end
|
134
149
|
end
|
@@ -7,12 +7,17 @@ module Ecoportal
|
|
7
7
|
module StringDigest
|
8
8
|
MAX_HASH_LABEL = 64
|
9
9
|
|
10
|
+
def indexable_label(str)
|
11
|
+
return nil unless str
|
12
|
+
lbl = str.downcase.gsub(/[^A-Za-z]+/,"-").slice(0, MAX_HASH_LABEL)
|
13
|
+
return nil unless lbl.length >= 3
|
14
|
+
lbl
|
15
|
+
end
|
16
|
+
|
10
17
|
# Calculates the Hash of the field based on label
|
11
18
|
def hash_label(str)
|
12
|
-
return
|
13
|
-
|
14
|
-
return false unless label.length >= 3
|
15
|
-
return "z" + Digest::MD5.hexdigest(label).slice(0, 8);
|
19
|
+
return nil unless lbl = indexable_label(str)
|
20
|
+
"z" + Digest::MD5.hexdigest(lbl).slice(0, 8);
|
16
21
|
end
|
17
22
|
|
18
23
|
end
|
data/lib/ecoportal/api/v2.rb
CHANGED
@@ -2,6 +2,7 @@ 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
6
|
passkey :id
|
6
7
|
passthrough :patch_ver
|
7
8
|
passthrough :name, :template_id
|
@@ -17,6 +18,17 @@ module Ecoportal
|
|
17
18
|
embeds_one :components, multiple: true, klass: :components_class
|
18
19
|
embeds_one :sections, multiple: true, klass: :sections_class
|
19
20
|
embeds_one :stages, multiple: true, klass: :stages_class
|
21
|
+
|
22
|
+
def as_update
|
23
|
+
super.tap do |hash|
|
24
|
+
unless !hash
|
25
|
+
hash["data"].select! do |key, value|
|
26
|
+
ALLOWED_KEYS.include?(key)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
20
32
|
end
|
21
33
|
end
|
22
34
|
end
|
@@ -23,6 +23,13 @@ module Ecoportal
|
|
23
23
|
class_resolver :law_field_class, "Ecoportal::API::V2::Page::Component::LawField"
|
24
24
|
|
25
25
|
class << self
|
26
|
+
def new_doc(type:)
|
27
|
+
{
|
28
|
+
"id" => new_uuid,
|
29
|
+
"type" => type
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
26
33
|
def get_class(doc)
|
27
34
|
if doc.is_a?(Hash)
|
28
35
|
case doc["type"]
|
@@ -81,6 +88,10 @@ module Ecoportal
|
|
81
88
|
root.sections.find {|sec| sec.component?(id)}
|
82
89
|
end
|
83
90
|
|
91
|
+
def indexable_label
|
92
|
+
self.class.indexable_label(label)
|
93
|
+
end
|
94
|
+
|
84
95
|
end
|
85
96
|
end
|
86
97
|
end
|
@@ -4,8 +4,8 @@ module Ecoportal
|
|
4
4
|
class Page
|
5
5
|
class Component
|
6
6
|
class ActionField < Page::Component
|
7
|
-
class_resolver :action_class, "Ecoportal::API::V2::Page::Component::Action"
|
8
|
-
embeds_multiple :actions, klass:
|
7
|
+
#class_resolver :action_class, "Ecoportal::API::V2::Page::Component::Action"
|
8
|
+
embeds_multiple :actions, klass: "Ecoportal::API::V2::Page::Component::Action", order_key: :weight
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
@@ -4,8 +4,8 @@ module Ecoportal
|
|
4
4
|
class Page
|
5
5
|
class Component
|
6
6
|
class ChecklistField < Page::Component
|
7
|
-
class_resolver :checklist_item_class, "Ecoportal::API::V2::Page::Component::ChecklistItem"
|
8
|
-
embeds_multiple :items, klass:
|
7
|
+
#class_resolver :checklist_item_class, "Ecoportal::API::V2::Page::Component::ChecklistItem"
|
8
|
+
embeds_multiple :items, klass: "Ecoportal::API::V2::Page::Component::ChecklistItem", order_key: :weight
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
@@ -4,8 +4,8 @@ module Ecoportal
|
|
4
4
|
class Page
|
5
5
|
class Component
|
6
6
|
class FilesField < Page::Component
|
7
|
-
class_resolver :file_class, "Ecoportal::API::V2::Page::File"
|
8
|
-
embeds_multiple :items, klass:
|
7
|
+
#class_resolver :file_class, "Ecoportal::API::V2::Page::File"
|
8
|
+
embeds_multiple :items, klass: "Ecoportal::API::V2::Page::File", order_key: :position
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
@@ -4,8 +4,8 @@ module Ecoportal
|
|
4
4
|
class Page
|
5
5
|
class Component
|
6
6
|
class ImagesField < Page::Component
|
7
|
-
class_resolver :image_class, "Ecoportal::API::V2::Page::Image"
|
8
|
-
embeds_multiple :images, klass:
|
7
|
+
#class_resolver :image_class, "Ecoportal::API::V2::Page::Image"
|
8
|
+
embeds_multiple :images, klass: "Ecoportal::API::V2::Page::Image", order_key: :weight
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
@@ -6,8 +6,69 @@ module Ecoportal
|
|
6
6
|
class SelectionField < Page::Component
|
7
7
|
passthrough :multiple, :other, :other_desc
|
8
8
|
|
9
|
-
class_resolver :selection_option_class, "Ecoportal::API::V2::Page::Component::SelectionOption"
|
10
|
-
embeds_multiple :options, klass:
|
9
|
+
#class_resolver :selection_option_class, "Ecoportal::API::V2::Page::Component::SelectionOption"
|
10
|
+
embeds_multiple :options, klass: "Ecoportal::API::V2::Page::Component::SelectionOption", order_key: :weight
|
11
|
+
|
12
|
+
def select(value)
|
13
|
+
opt = options.find {|opt| opt.value == value}
|
14
|
+
sel = selected
|
15
|
+
return true if !multiple && opt == sel
|
16
|
+
sel.selected = false if !multiple && sel
|
17
|
+
opt.selected = true unless !opt
|
18
|
+
end
|
19
|
+
|
20
|
+
def selected
|
21
|
+
if multiple
|
22
|
+
options.select {|opt| opt.selected}
|
23
|
+
else
|
24
|
+
options.find {|opt| opt.selected}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def value
|
29
|
+
if multiple
|
30
|
+
selected.map {|opt| opt.value}
|
31
|
+
else
|
32
|
+
selected&.value
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# a server bug prevents to add new options to an existing field
|
37
|
+
def add_option(name:, value:, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
|
38
|
+
opt_doc = Ecoportal::API::V2::Page::Component::SelectionOption.new_doc
|
39
|
+
options.upsert!(opt_doc, pos: pos, before: before, after: after) do |option|
|
40
|
+
option.name = name
|
41
|
+
option.value = value
|
42
|
+
if prev = previous_option(option)
|
43
|
+
option.weight = prev.weight
|
44
|
+
end
|
45
|
+
yield(option) if block_given?
|
46
|
+
fix_option_weights!
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def ordered_options
|
51
|
+
options.each_with_index.sort_by do |option, index|
|
52
|
+
(option.weight >= 9999) ? [index, index] : [option.weight, index]
|
53
|
+
end.map(&:first)
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def fix_option_weights!
|
59
|
+
ordered_options.each_with_index do |option, index|
|
60
|
+
option.weight = index
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def previous_option(value)
|
65
|
+
opts = ordered_options
|
66
|
+
pos = opts.index(value) - 1
|
67
|
+
return if pos < 0
|
68
|
+
opts[pos]
|
69
|
+
end
|
70
|
+
|
71
|
+
|
11
72
|
end
|
12
73
|
end
|
13
74
|
end
|
@@ -4,6 +4,15 @@ module Ecoportal
|
|
4
4
|
class Page
|
5
5
|
class Component
|
6
6
|
class SelectionOption < Common::Content::DoubleModel
|
7
|
+
class << self
|
8
|
+
def new_doc
|
9
|
+
{
|
10
|
+
"id" => new_uuid,
|
11
|
+
"weight" => 9999
|
12
|
+
}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
7
16
|
passkey :id
|
8
17
|
passthrough :patch_ver, :name, :value
|
9
18
|
passthrough :weight, :selected
|
@@ -13,6 +13,28 @@ module Ecoportal
|
|
13
13
|
|
14
14
|
order_matters = true
|
15
15
|
|
16
|
+
def get_by_type(type)
|
17
|
+
self.select do |comp|
|
18
|
+
comp.type.downcase == type.to_s.strip.downcase
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def get_by_name(name, type: nil)
|
23
|
+
pool = type ? get_by_type(type) : self
|
24
|
+
|
25
|
+
pool.select do |comp|
|
26
|
+
comp.label.to_s.strip.downcase == name.to_s.strip.downcase
|
27
|
+
end.first
|
28
|
+
end
|
29
|
+
|
30
|
+
def add(label:, type:)
|
31
|
+
fld_doc = Ecoportal::API::V2::Page::Component.new_doc(type: type)
|
32
|
+
upsert!(fld_doc) do |fld|
|
33
|
+
fld.label = label
|
34
|
+
yield(fld) if block_given?
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
16
38
|
end
|
17
39
|
end
|
18
40
|
end
|
@@ -3,6 +3,28 @@ module Ecoportal
|
|
3
3
|
class V2
|
4
4
|
class Page
|
5
5
|
class Section < Common::Content::DoubleModel
|
6
|
+
class << self
|
7
|
+
def new_doc(split: false)
|
8
|
+
{
|
9
|
+
"id" => new_uuid,
|
10
|
+
"type" => split ? "split" : "content",
|
11
|
+
"weight" => 9999
|
12
|
+
}.tap do |out|
|
13
|
+
component_ids = if split
|
14
|
+
{
|
15
|
+
"left_component_ids" => [],
|
16
|
+
"right_component_ids" => []
|
17
|
+
}
|
18
|
+
else
|
19
|
+
{
|
20
|
+
"component_ids" => []
|
21
|
+
}
|
22
|
+
end
|
23
|
+
out.merge!(component_ids)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
6
28
|
passkey :id
|
7
29
|
passthrough :patch_ver, :weight, :type
|
8
30
|
passthrough :heading, :left_heading, :right_heading
|
@@ -22,9 +44,9 @@ module Ecoportal
|
|
22
44
|
end
|
23
45
|
|
24
46
|
def components
|
25
|
-
|
26
|
-
root.components.values_at(*
|
27
|
-
puts "Warning:
|
47
|
+
fld_ids = all_component_ids
|
48
|
+
root.components.values_at(*fld_ids).select.with_index do |fld, i|
|
49
|
+
puts "Warning: field #{id} points to missing field #{fld_ids[i]}" if !fld
|
28
50
|
fld && (!block_given? || yield(fld))
|
29
51
|
end
|
30
52
|
end
|
@@ -7,6 +7,39 @@ module Ecoportal
|
|
7
7
|
|
8
8
|
self.klass = :section_class
|
9
9
|
|
10
|
+
def add(name: nil, split: false, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
|
11
|
+
sec_doc = Ecoportal::API::V2::Page::Section.new_doc(split: split)
|
12
|
+
upsert!(sec_doc, pos: pos, before: before, after: after) do |section|
|
13
|
+
section.heading = name
|
14
|
+
if prev = previous_section(section)
|
15
|
+
section.weight = prev.weight
|
16
|
+
end
|
17
|
+
yield(section) if block_given?
|
18
|
+
#fix_weights! # a server bug prevents to set the weight of existing sections
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def ordered
|
23
|
+
each_with_index.sort_by do |section, index|
|
24
|
+
(section.weight >= 9999) ? [index, index] : [section.weight, index]
|
25
|
+
end.map(&:first)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def fix_weights!
|
31
|
+
ordered.each_with_index do |section, index|
|
32
|
+
section.weight = index
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def previous_section(value)
|
37
|
+
secs = ordered
|
38
|
+
pos = secs.index(value) - 1
|
39
|
+
return if pos < 0
|
40
|
+
secs[pos]
|
41
|
+
end
|
42
|
+
|
10
43
|
end
|
11
44
|
end
|
12
45
|
end
|
@@ -9,6 +9,19 @@ module Ecoportal
|
|
9
9
|
passarray :subtags, order_matters: false
|
10
10
|
passarray :section_ids
|
11
11
|
passthrough :can
|
12
|
+
|
13
|
+
def sections
|
14
|
+
sec_ids = section_ids.to_a
|
15
|
+
root.sections.values_at(*sec_ids).select.with_index do |sec, i|
|
16
|
+
puts "Warning: section #{id} points to missing section #{sec_ids[i]}" if !sec
|
17
|
+
fld && (!block_given? || yield(sec))
|
18
|
+
end.sort_by {|sec| sec.weight}
|
19
|
+
end
|
20
|
+
|
21
|
+
def attach_section(section)
|
22
|
+
section_ids.insert_one(section.id)
|
23
|
+
end
|
24
|
+
|
12
25
|
end
|
13
26
|
end
|
14
27
|
end
|
@@ -3,9 +3,11 @@ module Ecoportal
|
|
3
3
|
class V2
|
4
4
|
# @attr_reader client [Common::Client] a `Common::Client` object that holds the configuration of the api connection.
|
5
5
|
class Pages
|
6
|
+
STAGE_REX = /stages\/(?<sid>.*)/
|
6
7
|
extend Common::BaseClass
|
7
8
|
include Common::Content::DocHelpers
|
8
9
|
|
10
|
+
class_resolver :stages_class, "Ecoportal::API::V2::Pages::Stages"
|
9
11
|
class_resolver :page_class, "Ecoportal::API::V2::Page"
|
10
12
|
|
11
13
|
attr_reader :client
|
@@ -16,14 +18,30 @@ module Ecoportal
|
|
16
18
|
@client = client
|
17
19
|
end
|
18
20
|
|
21
|
+
# Obtain specific object for pages api requests.
|
22
|
+
# @return [V2::Pages::Stages] an instance object ready to make pages api requests.
|
23
|
+
def stages
|
24
|
+
stages_class.new(client)
|
25
|
+
end
|
26
|
+
|
19
27
|
# Gets a page via api.
|
20
|
-
# @note
|
28
|
+
# @note
|
29
|
+
# - if the request has `success?` the returned `object.result` gives an object with that `Page`.
|
30
|
+
# - if it failed to obtain the full page, it returns a `PageStage` with the active stage data.
|
21
31
|
# @param doc [String, Hash, Page] data containing an `id` of the target page.
|
22
|
-
# @return [Ecoportal::API::V2::Page] the target page.
|
32
|
+
# @return [Ecoportal::API::V2::Page, Ecoportal::API::V2::Pages::PageStage] the target page.
|
23
33
|
def get(doc)
|
24
|
-
|
25
|
-
response = client.get("/pages/#{CGI.escape(
|
26
|
-
Common::Content::WrappedResponse.new(response, page_class)
|
34
|
+
pid = get_id(doc)
|
35
|
+
response = client.get("/pages/#{CGI.escape(pid)}")
|
36
|
+
wrapped = Common::Content::WrappedResponse.new(response, page_class)
|
37
|
+
|
38
|
+
return wrapped.result if wrapped.success?
|
39
|
+
if (response.status == 302) && (url = response.body["data"])
|
40
|
+
if sid = url_to_stage_id(url)
|
41
|
+
return stages.get(pid: pid, sid: sid)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
raise "Could not get page #{pid} - Error #{response.status}: #{response.body}"
|
27
45
|
end
|
28
46
|
|
29
47
|
# Gets a `new` non-existing page via api with all the ids initialized.
|
@@ -32,8 +50,10 @@ module Ecoportal
|
|
32
50
|
def get_new(from)
|
33
51
|
id = get_id(from)
|
34
52
|
response = client.get("/pages/new", params: {template_id: id})
|
35
|
-
|
36
|
-
|
53
|
+
wrapped = Common::Content::WrappedResponse.new(response, page_class)
|
54
|
+
|
55
|
+
return wrapped.result if wrapped.success?
|
56
|
+
raise "Could not get new page from template #{id} - Error #{response.status}: #{response.body}"
|
37
57
|
end
|
38
58
|
|
39
59
|
# Requests a creation of a page via api.
|
@@ -55,9 +75,16 @@ module Ecoportal
|
|
55
75
|
client.patch("/pages/#{CGI.escape(id)}", data: body)
|
56
76
|
end
|
57
77
|
|
78
|
+
private
|
79
|
+
|
80
|
+
def url_to_stage_id(url)
|
81
|
+
(matches = url.match(STAGE_REX)) && matches[:sid]
|
82
|
+
end
|
83
|
+
|
58
84
|
end
|
59
85
|
end
|
60
86
|
end
|
61
87
|
end
|
62
88
|
|
63
89
|
require 'ecoportal/api/v2/page'
|
90
|
+
require 'ecoportal/api/v2/pages/stages'
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Ecoportal
|
2
|
+
module API
|
3
|
+
class V2
|
4
|
+
class Pages
|
5
|
+
# This API Integration level has been added due to relative permissions
|
6
|
+
# - a **user** with api access may have access to a specific `stage` but not to the full `page`
|
7
|
+
#
|
8
|
+
# @attr_reader client [Common::Client] a `Common::Client` object that holds the configuration of the api connection.
|
9
|
+
class Stages
|
10
|
+
extend Common::BaseClass
|
11
|
+
include Common::Content::DocHelpers
|
12
|
+
|
13
|
+
class_resolver :page_stage_class, "Ecoportal::API::V2::Pages::PageStage"
|
14
|
+
|
15
|
+
attr_reader :client
|
16
|
+
|
17
|
+
# @param client [Common::Client] a `Common::Client` object that holds the configuration of the api connection.
|
18
|
+
# @return [Schemas] an instance object ready to make schema api requests.
|
19
|
+
def initialize(client)
|
20
|
+
@client = client
|
21
|
+
end
|
22
|
+
|
23
|
+
# Gets a stage via api.
|
24
|
+
# @note if the request has `success?` the returned `object.result` gives an object with that `Stage`.
|
25
|
+
# @param doc [String, Hash, Stage] data containing an `id` of the target page.
|
26
|
+
# @return [Ecoportal::API::V2::Stage, Ecoportal::API::V2::Pages::PageStage] the target stage.
|
27
|
+
def get(pid:, sid:)
|
28
|
+
pid = get_id(pid)
|
29
|
+
response = client.get("/pages/#{CGI.escape(pid)}/stages/#{CGI.escape(sid)}/")
|
30
|
+
wrapped = Common::Content::WrappedResponse.new(response, page_stage_class)
|
31
|
+
|
32
|
+
return wrapped.result if wrapped.success?
|
33
|
+
raise "Could not get stage {#{sid}} of page #{pid} - Error #{response.status}: #{response.body}"
|
34
|
+
end
|
35
|
+
|
36
|
+
# Requests to update an existing stage via api.
|
37
|
+
# @param doc [Hash, Stage] data that at least contains an `id` (internal or external) of the target stage.
|
38
|
+
# @return [Response] an object with the api response.
|
39
|
+
def update(doc, pid: nil, sid:)
|
40
|
+
body = get_body(doc)
|
41
|
+
pid = pid || get_id(doc)
|
42
|
+
path = "/pages/#{CGI.escape(pid)}/stages/#{CGI.escape(sid)}/"
|
43
|
+
client.patch(path, data: body)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
require 'ecoportal/api/v2/pages/page_stage'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ecoportal-api-oozes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Oscar Segura
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-07-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -110,22 +110,22 @@ dependencies:
|
|
110
110
|
name: ecoportal-api
|
111
111
|
requirement: !ruby/object:Gem::Requirement
|
112
112
|
requirements:
|
113
|
-
- - "~>"
|
114
|
-
- !ruby/object:Gem::Version
|
115
|
-
version: '0.5'
|
116
113
|
- - ">="
|
117
114
|
- !ruby/object:Gem::Version
|
118
|
-
version: 0.
|
115
|
+
version: 0.6.0
|
116
|
+
- - "~>"
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0.6'
|
119
119
|
type: :runtime
|
120
120
|
prerelease: false
|
121
121
|
version_requirements: !ruby/object:Gem::Requirement
|
122
122
|
requirements:
|
123
|
-
- - "~>"
|
124
|
-
- !ruby/object:Gem::Version
|
125
|
-
version: '0.5'
|
126
123
|
- - ">="
|
127
124
|
- !ruby/object:Gem::Version
|
128
|
-
version: 0.
|
125
|
+
version: 0.6.0
|
126
|
+
- - "~>"
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0.6'
|
129
129
|
description:
|
130
130
|
email:
|
131
131
|
- rien@ecoportal.co.nz
|
@@ -140,6 +140,7 @@ files:
|
|
140
140
|
- ".rubocop.yml"
|
141
141
|
- ".travis.yml"
|
142
142
|
- ".yardopts"
|
143
|
+
- CHANGELOG.md
|
143
144
|
- Gemfile
|
144
145
|
- LICENSE
|
145
146
|
- README.md
|
@@ -189,6 +190,8 @@ files:
|
|
189
190
|
- lib/ecoportal/api/v2/page/stage.rb
|
190
191
|
- lib/ecoportal/api/v2/page/stages.rb
|
191
192
|
- lib/ecoportal/api/v2/pages.rb
|
193
|
+
- lib/ecoportal/api/v2/pages/page_stage.rb
|
194
|
+
- lib/ecoportal/api/v2/pages/stages.rb
|
192
195
|
- lib/ecoportal/api/v2/register.rb
|
193
196
|
- lib/ecoportal/api/v2/registers.rb
|
194
197
|
- lib/ecoportal/api/v2/template.rb
|