ecoportal-api-v2 0.8.13 → 0.8.14
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 +39 -2
- data/lib/ecoportal/api/common/content/array_model.rb +9 -16
- data/lib/ecoportal/api/common/content/collection_model.rb +11 -0
- data/lib/ecoportal/api/common/content/hash_diff_patch.rb +1 -1
- data/lib/ecoportal/api/v2/page/component.rb +17 -0
- data/lib/ecoportal/api/v2/page/components.rb +24 -0
- data/lib/ecoportal/api/v2/page/force/binding.rb +54 -0
- data/lib/ecoportal/api/v2/page/force/bindings.rb +126 -0
- data/lib/ecoportal/api/v2/page/force.rb +34 -0
- data/lib/ecoportal/api/v2/page/forces.rb +103 -0
- data/lib/ecoportal/api/v2/page/permission_flags.rb +0 -2
- data/lib/ecoportal/api/v2/page/section.rb +71 -16
- data/lib/ecoportal/api/v2/page/sections.rb +20 -1
- data/lib/ecoportal/api/v2/page/stage.rb +38 -2
- data/lib/ecoportal/api/v2/page/stages.rb +6 -0
- data/lib/ecoportal/api/v2/page.rb +9 -1
- data/lib/ecoportal/api/v2/pages/page_stage.rb +39 -1
- data/lib/ecoportal/api/v2_version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3480ab100855337eef9de50609f4f4776418de1b09a5a1eac3ee31f936f4cd00
|
4
|
+
data.tar.gz: 2520bf687a1d00df3d925788600f78c266fcc6599ac816dac1f7df08703bc9e9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 011752c7161177026fdcd59a01ee7eb048094eb29c5688e2b68e6ad2aec0a263e93990726c1fca86eb1bfc86d000d360db4d8cf685783f7c2ab8257570258740
|
7
|
+
data.tar.gz: 012ed55b7472c56f76b2e1bdafd3ce8cb926c67d5d94e6b3349a7c21ade9ff3a20c2caa4974fe9cdc30a6dba8312663edc633ae7d0a66b31117b57e795727dde
|
data/CHANGELOG.md
CHANGED
@@ -1,12 +1,49 @@
|
|
1
1
|
# Change Log
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
-
## [0.8.
|
4
|
+
## [0.8.14] - 2021-09-xx
|
5
5
|
|
6
6
|
### Added
|
7
|
+
- `Ecoportal::API::Common::Content::CollectionModel`
|
8
|
+
- `#_doc_pos` for clarity
|
9
|
+
- `#include?` to check if an element is present in the collection
|
10
|
+
- `Ecoportal::API::V2::Page::Stage#section?` check if section belongs to stage
|
11
|
+
- `Ecoportal::API::V2::Page::Sections`
|
12
|
+
- `#get_by_id`
|
13
|
+
- `#unattached` sections that are not attached to any stage
|
14
|
+
- `Ecoportal::API::V2::Page::Section`
|
15
|
+
- `#add_component` **added** parameter `before`: to cover case where you want to add it at the beginning
|
16
|
+
- `#component?` **widened** parameter type
|
17
|
+
- `#stages` stages where this section is attached
|
18
|
+
- `attached?` whether or not the section is attached
|
19
|
+
- `Ecoportal::API::V2::Page::Component`
|
20
|
+
- `#attached?` whether or not the field is attached to some section
|
21
|
+
- `#multi_section?` if the field is attached to more than one section :/
|
22
|
+
- **added** support for `forces`
|
23
|
+
- `Ecoportal::API::V2::Page::Force`
|
24
|
+
- `Ecoportal::API::V2::Page::Forces`
|
25
|
+
- `Ecoportal::API::V2::Page::Force::Binding`
|
26
|
+
- `Ecoportal::API::V2::Page::Force::Bindings`
|
27
|
+
- **added** shortcut to `#ooze` throughout all the model
|
28
|
+
- **validations** in some methods
|
29
|
+
- `Ecoportal::API::V2::Page::Stage#add_section`: section should be in `ooze.sections`
|
30
|
+
- `Ecoportal::API::V2::Page::Section#add_component`: component should be in `ooze.components`
|
31
|
+
- `Ecoportal::API::V2::Page::Force::Bindings#add`:
|
32
|
+
- section to be in `ooze.sections`
|
33
|
+
- component to be in `ooze.components`
|
34
|
+
- `Ecoportal::API::V2::Pages::PageStage#as_update` on page instances, it checks that
|
35
|
+
- Fields do not belong to more than one section
|
36
|
+
- Fields belong at least to one section
|
37
|
+
- Sections belong to at least one stage
|
38
|
+
|
7
39
|
### Changed
|
8
40
|
### Fixed
|
9
|
-
- `Ecoportal::API::
|
41
|
+
- `Ecoportal::API::Common::Content::ArrayModel#insert_one` was not inserting when not found. Should insert at least at the end.
|
42
|
+
|
43
|
+
## [0.8.13] - 2021-09-03
|
44
|
+
|
45
|
+
### Fixed
|
46
|
+
- `Ecoportal::API::V2::Page::Sections`
|
10
47
|
- `weight` fixing should only happen on entire page, **not** on stage sections that could change the order of section shared with other stages
|
11
48
|
- `#scope_weight` was not excluding the section when using `weight` of the last one
|
12
49
|
- Several classes with `embeds_many` were performing the `ordering` of those elements in the wrong way
|
@@ -224,25 +224,18 @@ module Ecoportal
|
|
224
224
|
i = index(value)
|
225
225
|
return i if (i && uniq?)
|
226
226
|
pos = case
|
227
|
-
when used_param?(pos)
|
228
|
-
pos
|
229
|
-
when used_param?(before)
|
230
|
-
|
231
|
-
when used_param?(after)
|
232
|
-
if after
|
233
|
-
if i = index(after) then i + 1 end
|
234
|
-
else
|
235
|
-
length
|
236
|
-
end
|
237
|
-
else
|
238
|
-
length
|
227
|
+
when used_param?(pos) && pos
|
228
|
+
pos
|
229
|
+
when used_param?(before) && before
|
230
|
+
index(before)
|
231
|
+
when used_param?(after) && after
|
232
|
+
if i = index(after) then i + 1 end
|
239
233
|
end
|
240
234
|
|
235
|
+
pos ||= length
|
241
236
|
pos.tap do |i|
|
242
|
-
|
243
|
-
|
244
|
-
on_change
|
245
|
-
end
|
237
|
+
_items.insert(pos, value)
|
238
|
+
on_change
|
246
239
|
end
|
247
240
|
end
|
248
241
|
|
@@ -109,6 +109,10 @@ module Ecoportal
|
|
109
109
|
self.class.klass
|
110
110
|
end
|
111
111
|
|
112
|
+
def _doc_pos(value)
|
113
|
+
_doc_key(value)
|
114
|
+
end
|
115
|
+
|
112
116
|
# Transforms `value` into the actual `key` to access the object in the doc `Array`
|
113
117
|
# @note
|
114
118
|
# - The name of the method is after the paren't class method
|
@@ -152,6 +156,13 @@ module Ecoportal
|
|
152
156
|
items_by_key[get_key(value)]
|
153
157
|
end
|
154
158
|
|
159
|
+
# Checks if an element exists in the collection
|
160
|
+
# @param value [String, Hash, Ecoportal::API::Common::Content::DoubleModel]
|
161
|
+
# @return [Boolean] whether or not it is included
|
162
|
+
def include?(value)
|
163
|
+
items_by_key.key?(get_key(value))
|
164
|
+
end
|
165
|
+
|
155
166
|
# @return [Array<Object>] the `items_class` element object
|
156
167
|
def values_at(*keys)
|
157
168
|
keys.map {|key| self[key]}
|
@@ -93,6 +93,10 @@ module Ecoportal
|
|
93
93
|
passboolean :hide_view, :hidden_on_reports, :hidden_on_mobile
|
94
94
|
passarray :refs
|
95
95
|
|
96
|
+
def ooze
|
97
|
+
self._parent.ooze
|
98
|
+
end
|
99
|
+
|
96
100
|
def ref_backend
|
97
101
|
refs.first
|
98
102
|
end
|
@@ -103,10 +107,23 @@ module Ecoportal
|
|
103
107
|
end
|
104
108
|
end
|
105
109
|
|
110
|
+
# Looks up the section that this component belongs to.
|
111
|
+
# @return [Ecoportal::API::V2::Page::Section, nil] the section where this field is attached to.
|
106
112
|
def section
|
107
113
|
root.sections.find {|sec| sec.component?(id)}
|
108
114
|
end
|
109
115
|
|
116
|
+
# @return [Boolean] whether or not this field is attached to any section.
|
117
|
+
def attached?
|
118
|
+
!!section
|
119
|
+
end
|
120
|
+
|
121
|
+
# @return [Boolean] whether or not the component has been attached to more than one section.
|
122
|
+
def multi_section?
|
123
|
+
secs = ooze.sections.select {|sec| sec.component?(id)}
|
124
|
+
secs.length > 1
|
125
|
+
end
|
126
|
+
|
110
127
|
def indexable_label
|
111
128
|
self.class.indexable_label(label)
|
112
129
|
end
|
@@ -13,18 +13,27 @@ module Ecoportal
|
|
13
13
|
|
14
14
|
order_matters = true
|
15
15
|
|
16
|
+
def ooze
|
17
|
+
self._parent.ooze
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [Ecoportal::API::V2::Page::Component] the field with `id`
|
16
21
|
def get_by_id(id)
|
17
22
|
self.find do |comp|
|
18
23
|
comp.id == id
|
19
24
|
end
|
20
25
|
end
|
21
26
|
|
27
|
+
# @return [Array<Ecoportal::API::V2::Page::Component>] the fields of that `type`
|
22
28
|
def get_by_type(type)
|
23
29
|
self.select do |comp|
|
24
30
|
comp.type.downcase == type.to_s.strip.downcase
|
25
31
|
end
|
26
32
|
end
|
27
33
|
|
34
|
+
# @param name [String, Regexp] the `name` to search the field based on their `label`
|
35
|
+
# @param type [String] the `type` of the fields to be included
|
36
|
+
# @return [Array<Ecoportal::API::V2::Page::Component>] the fields that match `name`.
|
28
37
|
def get_by_name(name, type: nil)
|
29
38
|
pool = type ? get_by_type(type) : self
|
30
39
|
pool.select do |comp|
|
@@ -32,6 +41,12 @@ module Ecoportal
|
|
32
41
|
end
|
33
42
|
end
|
34
43
|
|
44
|
+
# It creates a **new** component
|
45
|
+
# @param label [String, nil]
|
46
|
+
# @param type [String] the type of the field
|
47
|
+
# @yield [field] do some stuff with field
|
48
|
+
# @yieldparam [Ecoportal::API::V2::Page::Component] the created field
|
49
|
+
# @return [Ecoportal::API::V2::Page::Component] the created field.
|
35
50
|
def add(label:, type:)
|
36
51
|
fld_doc = component_class.new_doc(type: type)
|
37
52
|
upsert!(fld_doc) do |fld|
|
@@ -40,6 +55,15 @@ module Ecoportal
|
|
40
55
|
end
|
41
56
|
end
|
42
57
|
|
58
|
+
# @return [Array<Ecoportal::API::V2::Page::Component>] **orphaned** fields (with no section).
|
59
|
+
def unattached
|
60
|
+
select {|comp| !comp.attached?}
|
61
|
+
end
|
62
|
+
|
63
|
+
# @return [Array<Ecoportal::API::V2::Page::Component>] fields belonging to more than one section.
|
64
|
+
def multi_section
|
65
|
+
select {|comp| comp.multi_section?}
|
66
|
+
end
|
43
67
|
end
|
44
68
|
end
|
45
69
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Ecoportal
|
2
|
+
module API
|
3
|
+
class V2
|
4
|
+
class Page
|
5
|
+
class Force
|
6
|
+
class Binding < Common::Content::DoubleModel
|
7
|
+
class << self
|
8
|
+
def new_doc
|
9
|
+
{
|
10
|
+
"id" => new_uuid
|
11
|
+
}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
COMPONENT_TYPE = "membrane_binding"
|
15
|
+
SECTION_TYPE = "flow_node_binding"
|
16
|
+
|
17
|
+
passkey :id
|
18
|
+
passforced :patch_ver, default: 1
|
19
|
+
passthrough :name, :reference_id, :type
|
20
|
+
|
21
|
+
def ooze
|
22
|
+
self._parent.ooze
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [Boolean] whether or not this the binding refers to a Component
|
26
|
+
def component?
|
27
|
+
type == COMPONENT_TYPE
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [Boolean] whether or not this the binding refers to a Section
|
31
|
+
def section?
|
32
|
+
type == SECTION_TYPE
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return [Ecoportal::API::V2::Page::Component] field referenced by this binding.
|
36
|
+
def component
|
37
|
+
raise "This is not a component binding, but a section binding" unless component?
|
38
|
+
ooze.components.get_by_id(reference_id)
|
39
|
+
end
|
40
|
+
|
41
|
+
# @return [Ecoportal::API::V2::Page::Section] section referenced by this binding.
|
42
|
+
def section
|
43
|
+
raise "This is not a section binding, but a component binding" unless section?
|
44
|
+
ooze.sections.get_by_id(reference_id)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
require 'ecoportal/api/v2/page/force/binding'
|
54
|
+
require 'ecoportal/api/v2/page/force/bindings'
|
@@ -0,0 +1,126 @@
|
|
1
|
+
module Ecoportal
|
2
|
+
module API
|
3
|
+
class V2
|
4
|
+
class Page
|
5
|
+
class Force
|
6
|
+
class Bindings < Common::Content::CollectionModel
|
7
|
+
class_resolver :binding_class, "Ecoportal::API::V2::Page::Force::Binding"
|
8
|
+
|
9
|
+
self.klass = :binding_class
|
10
|
+
order_matters = true
|
11
|
+
|
12
|
+
def ooze
|
13
|
+
self._parent.ooze
|
14
|
+
end
|
15
|
+
|
16
|
+
# @param id [String] the `id` of the binding to find.
|
17
|
+
# @return [Ecoportal::API::V2::Page::Force::Binding] binding with `id`
|
18
|
+
def get_by_id(id)
|
19
|
+
self.find do |bind|
|
20
|
+
bind.id == id
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param type [String] target `type` of binding
|
25
|
+
# 1. Ecoportal::API::V2::Page::Force::Binding::COMPONENT_TYPE
|
26
|
+
# 2. Ecoportal::API::V2::Page::Force::Binding::SECTION_TYPE
|
27
|
+
# @return [Array<Ecoportal::API::V2::Page::Force::Binding>] the bindings of type `type`
|
28
|
+
def get_by_type(type = Ecoportal::API::V2::Page::Force::Binding::COMPONENT_TYPE)
|
29
|
+
self.select do |bind|
|
30
|
+
bind.type.downcase == type.to_s.strip.downcase
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# @param type [String] target `type` of binding
|
35
|
+
# 1. Ecoportal::API::V2::Page::Force::Binding::COMPONENT_TYPE
|
36
|
+
# 2. Ecoportal::API::V2::Page::Force::Binding::SECTION_TYPE
|
37
|
+
# @return [Array<Ecoportal::API::V2::Page::Force::Binding>] the bindings matching `name`
|
38
|
+
def get_by_name(name, type: nil)
|
39
|
+
pool = type ? get_by_type(type) : self
|
40
|
+
pool.select do |bind|
|
41
|
+
same_string?(bind.name, name)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Creates a new `binding`
|
46
|
+
# @note
|
47
|
+
# - As there's no position property, it will upsert to the array of bindings
|
48
|
+
# @raise [ArgumentError] when `reference` is neither of Component or Section
|
49
|
+
# @raise [Exception] when
|
50
|
+
# 1. `reference` is a field missing in ooze.components
|
51
|
+
# 2. `reference` is a section missing in ooze.sections
|
52
|
+
# @param reference [Ecoportal::API::V2::Page::Component, Ecoportal::API::V2::Page::Section]
|
53
|
+
# The field or the section to bind.
|
54
|
+
# @yield [binding] do some stuff with binding
|
55
|
+
# @yieldparam binding [Ecoportal::API::V2::Page::Force::Binding] the created binding
|
56
|
+
# @return [Ecoportal::API::V2::Page::Force::Binding] the created binding.
|
57
|
+
def add(reference, name:, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
|
58
|
+
binding_doc = binding_class.new_doc
|
59
|
+
|
60
|
+
type = case reference
|
61
|
+
when Ecoportal::API::V2::Page::Component
|
62
|
+
unless ooze.components.include?(reference)
|
63
|
+
msg = "The field '#{reference.label}' (#{reference.id}) is not present in ooze.components.\n"
|
64
|
+
msg += "Review your script (i.e. @var where you store previous ooze runs)."
|
65
|
+
raise msg
|
66
|
+
end
|
67
|
+
Ecoportal::API::V2::Page::Force::Binding::COMPONENT_TYPE
|
68
|
+
when Ecoportal::API::V2::Page::Section
|
69
|
+
unless ooze.sections.include?(reference)
|
70
|
+
msg = "The section '#{reference.heading}' (#{reference.id}) is not present in ooze.sections.\n"
|
71
|
+
msg += "Review your script (i.e. @var where you store previous ooze runs)."
|
72
|
+
raise msg
|
73
|
+
end
|
74
|
+
Ecoportal::API::V2::Page::Force::Binding::SECTION_TYPE
|
75
|
+
else
|
76
|
+
msg = "You can only create bindings with Component and Section. Given: #{reference.class}"
|
77
|
+
raise ArgumentError.new(msg)
|
78
|
+
end
|
79
|
+
|
80
|
+
position = scope_position(pos: pos, before: before, after: after)
|
81
|
+
upsert!(binding_doc, pos: position) do |bind|
|
82
|
+
bind.name = name
|
83
|
+
bind.reference_id = reference.id
|
84
|
+
bind.type = type
|
85
|
+
yield(bind) if block_given?
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def scope_position(pos: NOT_USED, before: NOT_USED, after: NOT_USED)
|
92
|
+
case
|
93
|
+
when used_param?(pos)
|
94
|
+
if pos = to_binding(pos)
|
95
|
+
_doc_pos(pos) - 1
|
96
|
+
end
|
97
|
+
when used_param?(before)
|
98
|
+
if before = to_binding(before)
|
99
|
+
_doc_pos(before) - 1
|
100
|
+
end
|
101
|
+
when used_param?(after)
|
102
|
+
if after = to_binding(after)
|
103
|
+
_doc_pos(after) - 1
|
104
|
+
end
|
105
|
+
end.yield_self do |position|
|
106
|
+
position ||= self.count
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def to_binding(value)
|
111
|
+
case value
|
112
|
+
when Ecoportal::API::V2::Page::Force::Binding
|
113
|
+
value
|
114
|
+
when Numeric
|
115
|
+
self[value]
|
116
|
+
else
|
117
|
+
get_by_name(value).first
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Ecoportal
|
2
|
+
module API
|
3
|
+
class V2
|
4
|
+
class Page
|
5
|
+
class Force < Common::Content::DoubleModel
|
6
|
+
INITIAL_WEIGHT = 9999
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def new_doc
|
10
|
+
{
|
11
|
+
"id" => new_uuid,
|
12
|
+
"weight" => INITIAL_WEIGHT
|
13
|
+
}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class_resolver :bindings_class, "Ecoportal::API::V2::Page::Force::Bindings"
|
18
|
+
|
19
|
+
passkey :id
|
20
|
+
passforced :patch_ver, default: 1
|
21
|
+
passthrough :name, :weight, :script
|
22
|
+
embeds_many :bindings, enum_class: :bindings_class
|
23
|
+
|
24
|
+
def ooze
|
25
|
+
self._parent.ooze
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
require 'ecoportal/api/v2/page/force/binding'
|
34
|
+
require 'ecoportal/api/v2/page/force/bindings'
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module Ecoportal
|
2
|
+
module API
|
3
|
+
class V2
|
4
|
+
class Page
|
5
|
+
class Forces < Common::Content::CollectionModel
|
6
|
+
class_resolver :force_class, "Ecoportal::API::V2::Page::Force"
|
7
|
+
|
8
|
+
self.klass = :force_class
|
9
|
+
order_matters = true
|
10
|
+
|
11
|
+
def ooze
|
12
|
+
self._parent.ooze
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [Ecoportal::API::V2::Page::Force]
|
16
|
+
def get_by_id(id)
|
17
|
+
self.find do |force|
|
18
|
+
force.id == id
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [Array<Ecoportal::API::V2::Page::Force>]
|
23
|
+
def get_by_name(name)
|
24
|
+
self.select do |force|
|
25
|
+
same_string?(force.name, name)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Creates a new `force`
|
30
|
+
# @note
|
31
|
+
# - It won't fix weights unless all the forces of the ooze are present
|
32
|
+
# - This means that it doesn't fix forces weights on stages,
|
33
|
+
# as shared forces could change order in other stages
|
34
|
+
# @yield [force] to do some stuff with the `force`
|
35
|
+
# @yieldparam force [Ecoportal::API::V2::Page::Force] the created force
|
36
|
+
# @return [Ecoportal::API::V2::Page::Force]
|
37
|
+
def add(name, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
|
38
|
+
force_doc = force_class.new_doc
|
39
|
+
upsert!(force_doc) do |force| #, pos: pos, before: before, after: after) do |section|
|
40
|
+
force.name = name
|
41
|
+
if weight = scope_weight(force, pos: pos, before: before, after: after)
|
42
|
+
force.weight = weight
|
43
|
+
end
|
44
|
+
fix_weights!
|
45
|
+
yield(force) if block_given?
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Gets the forces ordered by `weight` (as they appear in the page)
|
50
|
+
# @return [Array<Ecoportal::API::V2::Page::Force>] forces ordered by `weight`
|
51
|
+
def ordered
|
52
|
+
self.sort_by.with_index do |force, index|
|
53
|
+
[force.weight, index]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def fix_weights!
|
60
|
+
unless self._parent.is_a?(Ecoportal::API::V2::Pages::PageStage)
|
61
|
+
ordered.each_with_index do |force, index|
|
62
|
+
force.weight = index
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def scope_weight(force, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
|
68
|
+
case
|
69
|
+
when used_param?(pos)
|
70
|
+
if pos = to_force(pos)
|
71
|
+
pos.weight - 1
|
72
|
+
end
|
73
|
+
when used_param?(before)
|
74
|
+
if before = to_force(before)
|
75
|
+
before.weight - 1
|
76
|
+
end
|
77
|
+
when used_param?(after)
|
78
|
+
if after = to_force(after)
|
79
|
+
after.weight
|
80
|
+
end
|
81
|
+
end.yield_self do |weight|
|
82
|
+
weight = ordered.reject do |frc|
|
83
|
+
frc.id == force.id
|
84
|
+
end.last&.weight
|
85
|
+
weight ||= force_class.const_get(:INITIAL_WEIGHT)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def to_force(value)
|
90
|
+
case value
|
91
|
+
when Ecoportal::API::V2::Page::Force
|
92
|
+
value
|
93
|
+
when Numeric
|
94
|
+
ordered[value]
|
95
|
+
else
|
96
|
+
get_by_name(value).first
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -34,19 +34,48 @@ module Ecoportal
|
|
34
34
|
passarray :component_ids, :left_component_ids, :right_component_ids
|
35
35
|
passboolean :minimized
|
36
36
|
|
37
|
+
def ooze
|
38
|
+
self._parent.ooze
|
39
|
+
end
|
40
|
+
|
41
|
+
# @return [Array<Ecoportal::API::V2::Page::Stage>] the stage(s) this section belongs to.
|
42
|
+
def stages
|
43
|
+
ooze.stages.select {|stg| stg.has_section?(self)}
|
44
|
+
end
|
45
|
+
|
46
|
+
# @return [Boolean] whether or not the section appears in an ooze instance
|
47
|
+
def attached?
|
48
|
+
!ooze.stages? || stages.any?
|
49
|
+
end
|
50
|
+
|
51
|
+
# @return [Boolean] whether or not this section is a split section
|
37
52
|
def split?
|
38
53
|
doc && doc["type"] == "split"
|
39
54
|
end
|
40
55
|
|
56
|
+
# @return [Array<String>] all the `ids` of the components/fields in this section
|
41
57
|
def all_component_ids
|
42
58
|
return component_ids.to_a unless split?
|
43
59
|
left_component_ids.to_a | right_component_ids.to_a
|
44
60
|
end
|
45
61
|
|
46
|
-
|
47
|
-
|
62
|
+
# @raise [ArgumentError] if `com_or_id` is not of any of the allowed types
|
63
|
+
# @param com_or_id [Ecoportal::API::V2::Page::Component, String] Component or `id` thereof
|
64
|
+
# @return [Boolean] whether or not a component/field belongs to this section.
|
65
|
+
def component?(com_or_id)
|
66
|
+
case
|
67
|
+
when Ecoportal::API::V2::Page::Component
|
68
|
+
component?(com_or_id.id)
|
69
|
+
when String
|
70
|
+
all_component_ids.include?(id)
|
71
|
+
else
|
72
|
+
msg = "Missuse: com_or_id should be a Component or a String. Given: #{com_or_id.class}"
|
73
|
+
raise ArgumentError.new(msg)
|
74
|
+
end
|
48
75
|
end
|
49
76
|
|
77
|
+
# It looks up the components that belong to this section.
|
78
|
+
# @return [Array<Ecoportal::API::V2::Page::Component>]
|
50
79
|
def components(side: nil)
|
51
80
|
case side
|
52
81
|
when :right
|
@@ -60,11 +89,17 @@ module Ecoportal
|
|
60
89
|
end
|
61
90
|
end
|
62
91
|
|
92
|
+
# It looks up the components that belong to the `left` side of this section.
|
93
|
+
# @raise [Exception] if this is not a `split` section
|
94
|
+
# @return [Array<Ecoportal::API::V2::Page::Component>]
|
63
95
|
def components_left
|
64
96
|
raise "You are trying to retrieve side components in a Split Section" unless split?
|
65
97
|
components_by_id(*left_component_ids)
|
66
98
|
end
|
67
99
|
|
100
|
+
# It looks up the components that belong to the `right` side of this section.
|
101
|
+
# @raise [Exception] if this is not a `split` section
|
102
|
+
# @return [Array<Ecoportal::API::V2::Page::Component>]
|
68
103
|
def components_right
|
69
104
|
raise "You are trying to retrieve side components in a Split Section" unless split?
|
70
105
|
components_by_id(*right_component_ids)
|
@@ -77,9 +112,20 @@ module Ecoportal
|
|
77
112
|
# - If `after` is specified, it searches field
|
78
113
|
# - On the specific `side`, if specified (and split section)
|
79
114
|
# - And adds the `field` after it, when found, or at the end if `after` is not found
|
115
|
+
# @raise [ArgumentError] if `field` is not a Component
|
116
|
+
# @raise [Exception] if the field does not belong to ooze.components
|
117
|
+
# @raise [Exception] if the field belongs to another section
|
80
118
|
# @param field [Ecoportal::API::V2::Page::Component] the field to be added.
|
81
|
-
def add_component(field, after: nil, side: nil)
|
82
|
-
|
119
|
+
def add_component(field, before: nil, after: nil, side: nil)
|
120
|
+
unless field.is_a?(Ecoportal::API::V2::Page::Component)
|
121
|
+
msg = "Expected Ecoportal::API::V2::Page::Component. Given: #{field.class}"
|
122
|
+
raise ArgumentError.new(msg)
|
123
|
+
end
|
124
|
+
unless ooze.components.include?(field)
|
125
|
+
msg = "The field '#{field.label}' (#{field.id}) is not present in ooze.components.\n"
|
126
|
+
msg += "Review your script (i.e. @var where you store previous ooze runs)."
|
127
|
+
raise msg
|
128
|
+
end
|
83
129
|
# IMPORTANT NOTE: The code below creates objects, because field.section does a search on section.component_ids
|
84
130
|
if field.section == self
|
85
131
|
puts "Field with id '#{field.id}' already belongs to this section"
|
@@ -88,24 +134,19 @@ module Ecoportal
|
|
88
134
|
raise "Field with id '#{field.id}' belongs to section '#{sec.heading || "Unnamed"}' (id: '#{sec.id}')"
|
89
135
|
end
|
90
136
|
|
137
|
+
if before
|
138
|
+
before_fld = to_component(before, side: side)
|
139
|
+
elsif after
|
140
|
+
after_fld = to_component(afterm, side: side)
|
141
|
+
end
|
142
|
+
|
91
143
|
if split?
|
92
144
|
ids_ary = side == :right ? right_component_ids : left_component_ids
|
93
|
-
fields = components(side: side || :left)
|
94
145
|
else
|
95
146
|
ids_ary = component_ids
|
96
|
-
fields = components
|
97
|
-
end
|
98
|
-
|
99
|
-
if after
|
100
|
-
after_fld = fields.find do |fld|
|
101
|
-
found = nil
|
102
|
-
found ||= !!after if after.is_a?(Ecoportal::API::V2::Page::Component)
|
103
|
-
found ||= fld.id == after
|
104
|
-
found ||= same_string?(fld.label, after)
|
105
|
-
end
|
106
147
|
end
|
107
148
|
|
108
|
-
ids_ary.insert_one(field.id, after: after_fld&.id)
|
149
|
+
ids_ary.insert_one(field.id, before: before_fld&.id, after: after_fld&.id)
|
109
150
|
self
|
110
151
|
end
|
111
152
|
|
@@ -118,6 +159,20 @@ module Ecoportal
|
|
118
159
|
end
|
119
160
|
end
|
120
161
|
|
162
|
+
def to_component(value, side: nil)
|
163
|
+
if split?
|
164
|
+
fields = components(side: side || :left)
|
165
|
+
else
|
166
|
+
fields = components
|
167
|
+
end
|
168
|
+
|
169
|
+
fields.find do |fld|
|
170
|
+
found = nil
|
171
|
+
found ||= !!value if value.is_a?(Ecoportal::API::V2::Page::Component)
|
172
|
+
found ||= fld.id == value
|
173
|
+
found ||= same_string?(fld.label, value)
|
174
|
+
end
|
175
|
+
end
|
121
176
|
end
|
122
177
|
end
|
123
178
|
end
|
@@ -7,6 +7,10 @@ module Ecoportal
|
|
7
7
|
|
8
8
|
self.klass = :section_class
|
9
9
|
|
10
|
+
def ooze
|
11
|
+
self._parent.ooze
|
12
|
+
end
|
13
|
+
|
10
14
|
# Creates a new `section`
|
11
15
|
# @note
|
12
16
|
# - It won't fix weights unless all the sections of the ooze are present
|
@@ -24,12 +28,21 @@ module Ecoportal
|
|
24
28
|
end
|
25
29
|
end
|
26
30
|
|
31
|
+
# @return [Ecoportal::API::V2::Page::Section]
|
32
|
+
def get_by_id(id)
|
33
|
+
self.find do |sec|
|
34
|
+
sec.id == id
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# @return [Array<Ecoportal::API::V2::Page::Section>]
|
27
39
|
def get_by_type(type)
|
28
40
|
ordered.select do |sec|
|
29
41
|
sec.type == type
|
30
42
|
end
|
31
43
|
end
|
32
44
|
|
45
|
+
# @return [Array<Ecoportal::API::V2::Page::Section>]
|
33
46
|
def get_by_heading(heading)
|
34
47
|
ordered.select do |sec|
|
35
48
|
value = heading == :unnamed ? nil : heading
|
@@ -38,6 +51,7 @@ module Ecoportal
|
|
38
51
|
end
|
39
52
|
|
40
53
|
# Gets all the sections between `sec1` and `sec2`
|
54
|
+
# @return [Array<Ecoportal::API::V2::Page::Section>]
|
41
55
|
def between(sec1, sec2, included: false)
|
42
56
|
sorted_secs = ordered
|
43
57
|
pos1 = (sec1 = to_section(sec1)) && sorted_secs.index(sec1)
|
@@ -53,12 +67,18 @@ module Ecoportal
|
|
53
67
|
end
|
54
68
|
|
55
69
|
# Gets the sections ordered by `weight` (as they appear in the page)
|
70
|
+
# @return [Array<Ecoportal::API::V2::Page::Section>] section sorted by `weight`
|
56
71
|
def ordered
|
57
72
|
self.sort_by.with_index do |section, index|
|
58
73
|
[section.weight, index]
|
59
74
|
end
|
60
75
|
end
|
61
76
|
|
77
|
+
# @return [Array<Ecoportal::API::V2::Page::Section>] sections not attached to any stage
|
78
|
+
def unattached
|
79
|
+
select {|sec| !sec.attached?}
|
80
|
+
end
|
81
|
+
|
62
82
|
private
|
63
83
|
|
64
84
|
def scope_weight(section, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
|
@@ -108,7 +128,6 @@ module Ecoportal
|
|
108
128
|
return if pos < 0
|
109
129
|
secs[pos]
|
110
130
|
end
|
111
|
-
|
112
131
|
end
|
113
132
|
end
|
114
133
|
end
|
@@ -17,6 +17,13 @@ module Ecoportal
|
|
17
17
|
embeds_one :creator_flags, klass: "Ecoportal::API::V2::Page::PermissionFlags"
|
18
18
|
passthrough :can
|
19
19
|
|
20
|
+
def ooze
|
21
|
+
self._parent.ooze
|
22
|
+
end
|
23
|
+
|
24
|
+
# @yield [section] do some stuff with section.
|
25
|
+
# @yieldparam section [Ecoportal::API::V2::Page::Section] one of the sections of this stage
|
26
|
+
# @return [Array<Ecoportal::API::V2::Page::Section>] sections attached to this stage.
|
20
27
|
def sections
|
21
28
|
sec_ids = section_ids.to_a
|
22
29
|
root.sections.values_at(*sec_ids).select.with_index do |sec, i|
|
@@ -25,11 +32,40 @@ module Ecoportal
|
|
25
32
|
end.sort_by.with_index {|sec, index| [sec.weight, index]}
|
26
33
|
end
|
27
34
|
|
35
|
+
# Check if a section belongs to a stage
|
36
|
+
# @raise [ArgumentError] if none of the valid types of `sec_or_id` are used
|
37
|
+
# @param sec_or_id [String, Ecoportal::API::V2::Page::Section]
|
38
|
+
# @return [Boolean] whether or not the section belongs to the stage
|
39
|
+
def section?(sec_or_id)
|
40
|
+
case sec_or_id
|
41
|
+
when Ecoportal::API::V2::Page::Section
|
42
|
+
section?(sec_or_id.id)
|
43
|
+
when String
|
44
|
+
self.section_ids.include?(id)
|
45
|
+
else
|
46
|
+
raise ArgumentError.new("sec_or_id must be either a Section or a String. Given: #{sec_or_id.class}")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Adds one or more sections to this stage
|
51
|
+
# @raise [ArgumentError] if any of the elements is not a Section
|
52
|
+
# @raise [Exception] if any of the sections does not belong to ooze.sections
|
53
|
+
# @param secs [Array<Ecoportal::API::V2::Page::Section>] sections to be added to this stage.
|
28
54
|
def add_section(*secs)
|
29
|
-
secs.each
|
55
|
+
secs.each do |sec|
|
56
|
+
unless sec.is_a?(Ecoportal::API::V2::Page::Section)
|
57
|
+
msg = "Expected Ecoportal::API::V2::Page::Section. Given: #{sec.class}"
|
58
|
+
raise ArgumentError.new(msg)
|
59
|
+
end
|
60
|
+
unless ooze.sections.include?(sec)
|
61
|
+
msg = "The section '#{sec.heading}' (#{sec.id}) is not present in ooze.sections.\n"
|
62
|
+
msg += "Review your script (i.e. @var where you store previous ooze runs)."
|
63
|
+
raise msg
|
64
|
+
end
|
65
|
+
section_ids.insert_one(sec.id)
|
66
|
+
end
|
30
67
|
self
|
31
68
|
end
|
32
|
-
|
33
69
|
end
|
34
70
|
end
|
35
71
|
end
|
@@ -7,6 +7,12 @@ module Ecoportal
|
|
7
7
|
|
8
8
|
self.klass = :stage_class
|
9
9
|
|
10
|
+
def ooze
|
11
|
+
self._parent.ooze
|
12
|
+
end
|
13
|
+
|
14
|
+
# @param name [String, Regexp] the `name` of the stage to find.
|
15
|
+
# @return [Ecoportal::API::V2::Page::Stage, nil]
|
10
16
|
def get_by_name(name)
|
11
17
|
self.find do |stage|
|
12
18
|
same_string?(stage.name, name)
|
@@ -10,7 +10,7 @@ module Ecoportal
|
|
10
10
|
"permits", "mould_counter", "mould",
|
11
11
|
"state", "task_priority",
|
12
12
|
"votes_enabled", "upvotes", "downvotes",
|
13
|
-
"force_errors", "subtags"
|
13
|
+
"forces", "force_errors", "subtags"
|
14
14
|
]
|
15
15
|
|
16
16
|
passkey :id
|
@@ -24,15 +24,21 @@ module Ecoportal
|
|
24
24
|
class_resolver :components_class, "Ecoportal::API::V2::Page::Components"
|
25
25
|
class_resolver :sections_class, "Ecoportal::API::V2::Page::Sections"
|
26
26
|
class_resolver :stages_class, "Ecoportal::API::V2::Page::Stages"
|
27
|
+
class_resolver :forces_class, "Ecoportal::API::V2::Page::Forces"
|
27
28
|
|
28
29
|
embeds_many :components, enum_class: :components_class
|
29
30
|
embeds_many :sections, enum_class: :sections_class
|
30
31
|
embeds_many :stages, enum_class: :stages_class
|
32
|
+
embeds_many :forces, enum_class: :forces_class
|
31
33
|
|
32
34
|
def initialize(doc = [], parent: self, key: nil)
|
33
35
|
super(_doc_bug_fix(doc), parent: parent, key: key)
|
34
36
|
end
|
35
37
|
|
38
|
+
def ooze
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
36
42
|
def as_update
|
37
43
|
super.tap do |hash|
|
38
44
|
unless !hash
|
@@ -90,3 +96,5 @@ require 'ecoportal/api/v2/page/section'
|
|
90
96
|
require 'ecoportal/api/v2/page/sections'
|
91
97
|
require 'ecoportal/api/v2/page/stage'
|
92
98
|
require 'ecoportal/api/v2/page/stages'
|
99
|
+
require 'ecoportal/api/v2/page/force'
|
100
|
+
require 'ecoportal/api/v2/page/forces'
|
@@ -10,7 +10,7 @@ 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
|
-
# `id` of the stage we got the data of.
|
13
|
+
# @return [String] `id` of the stage we got the data of.
|
14
14
|
def current_stage_id
|
15
15
|
doc.dig("active_stage", "id") || doc["current_stage_id"]
|
16
16
|
end
|
@@ -22,6 +22,44 @@ module Ecoportal
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
+
# @raise [Exception] if for this page instance, there are any of:
|
26
|
+
# 1. orphaned components (fields not belonging to any section)
|
27
|
+
# 2. components multi-section (fields belonging to more than one section)
|
28
|
+
# 3. orphaned sections (sections not belonging to any stage)
|
29
|
+
def as_update(*args, **kargs)
|
30
|
+
validate.tap do |validation|
|
31
|
+
raise validation if validation.is_a?(String)
|
32
|
+
end
|
33
|
+
super(*args, **kargs)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def validate
|
39
|
+
msg = ""
|
40
|
+
if (orphans = components.unattached).length > 0
|
41
|
+
msg += "There are fields not attached to any sections:"
|
42
|
+
msg += orphans.map do |fld|
|
43
|
+
fld.label
|
44
|
+
end.join("\n • ") + "\n"
|
45
|
+
end
|
46
|
+
|
47
|
+
if (multi = components.multi_section).length > 0
|
48
|
+
msg += "There are fields attached to more than one section:"
|
49
|
+
msg += orphans.map do |fld|
|
50
|
+
fld.label
|
51
|
+
end.join("\n • ") + "\n"
|
52
|
+
end
|
53
|
+
|
54
|
+
if (orphans = sections.unattached).length > 0
|
55
|
+
msg += "There are sections not attached to any stage:"
|
56
|
+
msg += orphans.map do |sec|
|
57
|
+
"'#{sec.header}' (#{sec.id})"
|
58
|
+
end.join("\n • ") + "\n"
|
59
|
+
end
|
60
|
+
msg.empty?? true : msg
|
61
|
+
end
|
62
|
+
|
25
63
|
end
|
26
64
|
end
|
27
65
|
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.
|
4
|
+
version: 0.8.14
|
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-09-
|
11
|
+
date: 2021-09-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -218,6 +218,10 @@ files:
|
|
218
218
|
- lib/ecoportal/api/v2/page/component/signature_field.rb
|
219
219
|
- lib/ecoportal/api/v2/page/component/tag_field.rb
|
220
220
|
- lib/ecoportal/api/v2/page/components.rb
|
221
|
+
- lib/ecoportal/api/v2/page/force.rb
|
222
|
+
- lib/ecoportal/api/v2/page/force/binding.rb
|
223
|
+
- lib/ecoportal/api/v2/page/force/bindings.rb
|
224
|
+
- lib/ecoportal/api/v2/page/forces.rb
|
221
225
|
- lib/ecoportal/api/v2/page/permission_flags.rb
|
222
226
|
- lib/ecoportal/api/v2/page/permit.rb
|
223
227
|
- lib/ecoportal/api/v2/page/section.rb
|