ecoportal-api-v2 0.8.10 → 0.8.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +80 -1
  3. data/lib/ecoportal/api/common/content/array_model.rb +10 -17
  4. data/lib/ecoportal/api/common/content/collection_model.rb +23 -6
  5. data/lib/ecoportal/api/common/content/doc_helpers.rb +2 -2
  6. data/lib/ecoportal/api/common/content/double_model.rb +15 -5
  7. data/lib/ecoportal/api/common/content/hash_diff_patch.rb +1 -1
  8. data/lib/ecoportal/api/v2/page/component/action.rb +1 -1
  9. data/lib/ecoportal/api/v2/page/component/action_field.rb +3 -3
  10. data/lib/ecoportal/api/v2/page/component/checklist_field.rb +3 -3
  11. data/lib/ecoportal/api/v2/page/component/file.rb +1 -1
  12. data/lib/ecoportal/api/v2/page/component/files_field.rb +3 -3
  13. data/lib/ecoportal/api/v2/page/component/gauge_field.rb +3 -3
  14. data/lib/ecoportal/api/v2/page/component/selection_field.rb +3 -3
  15. data/lib/ecoportal/api/v2/page/component.rb +17 -0
  16. data/lib/ecoportal/api/v2/page/components.rb +24 -0
  17. data/lib/ecoportal/api/v2/page/force/binding.rb +54 -0
  18. data/lib/ecoportal/api/v2/page/force/bindings.rb +126 -0
  19. data/lib/ecoportal/api/v2/page/force.rb +34 -0
  20. data/lib/ecoportal/api/v2/page/forces.rb +103 -0
  21. data/lib/ecoportal/api/v2/page/permission_flags.rb +0 -2
  22. data/lib/ecoportal/api/v2/page/section.rb +77 -17
  23. data/lib/ecoportal/api/v2/page/sections.rb +36 -6
  24. data/lib/ecoportal/api/v2/page/stage.rb +39 -3
  25. data/lib/ecoportal/api/v2/page/stages.rb +9 -3
  26. data/lib/ecoportal/api/v2/page.rb +46 -1
  27. data/lib/ecoportal/api/v2/pages/page_stage.rb +51 -0
  28. data/lib/ecoportal/api/v2/pages.rb +3 -0
  29. data/lib/ecoportal/api/v2/registers/search_results.rb +13 -0
  30. data/lib/ecoportal/api/v2/registers.rb +15 -2
  31. data/lib/ecoportal/api/v2_version.rb +1 -1
  32. metadata +7 -2
@@ -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
@@ -57,9 +57,7 @@ module Ecoportal
57
57
  end.yield_self do |unused|
58
58
  raise "Unknown configuaration options #{unused}" unless unused.empty?
59
59
  end
60
-
61
60
  end
62
-
63
61
  end
64
62
  end
65
63
  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
11
  "id" => new_uuid,
10
12
  "type" => split ? "split" : "content",
11
- "weight" => 800
13
+ "weight" => INITIAL_WEIGHT
12
14
  }.tap do |out|
13
15
  component_ids = if split
14
16
  {
@@ -32,19 +34,48 @@ module Ecoportal
32
34
  passarray :component_ids, :left_component_ids, :right_component_ids
33
35
  passboolean :minimized
34
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
35
52
  def split?
36
53
  doc && doc["type"] == "split"
37
54
  end
38
55
 
56
+ # @return [Array<String>] all the `ids` of the components/fields in this section
39
57
  def all_component_ids
40
58
  return component_ids.to_a unless split?
41
59
  left_component_ids.to_a | right_component_ids.to_a
42
60
  end
43
61
 
44
- def component?(id)
45
- all_component_ids.include?(id)
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
46
75
  end
47
76
 
77
+ # It looks up the components that belong to this section.
78
+ # @return [Array<Ecoportal::API::V2::Page::Component>]
48
79
  def components(side: nil)
49
80
  case side
50
81
  when :right
@@ -58,11 +89,17 @@ module Ecoportal
58
89
  end
59
90
  end
60
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>]
61
95
  def components_left
62
96
  raise "You are trying to retrieve side components in a Split Section" unless split?
63
97
  components_by_id(*left_component_ids)
64
98
  end
65
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>]
66
103
  def components_right
67
104
  raise "You are trying to retrieve side components in a Split Section" unless split?
68
105
  components_by_id(*right_component_ids)
@@ -75,32 +112,41 @@ module Ecoportal
75
112
  # - If `after` is specified, it searches field
76
113
  # - On the specific `side`, if specified (and split section)
77
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
78
118
  # @param field [Ecoportal::API::V2::Page::Component] the field to be added.
79
- def add_component(field, after: nil, side: nil)
80
- raise "field should be a Ecoportal::API::V2::Page::Component. Given: #{field.class}" unless field.is_a?(Ecoportal::API::V2::Page::Component)
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
129
+ # IMPORTANT NOTE: The code below creates objects, because field.section does a search on section.component_ids
81
130
  if field.section == self
82
- raise "Field with id '#{field.id}' already belongs to this section"
131
+ puts "Field with id '#{field.id}' already belongs to this section"
83
132
  elsif sec = field.section
84
133
  # Field belongs to another section
85
134
  raise "Field with id '#{field.id}' belongs to section '#{sec.heading || "Unnamed"}' (id: '#{sec.id}')"
86
135
  end
87
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
+
88
143
  if split?
89
144
  ids_ary = side == :right ? right_component_ids : left_component_ids
90
- fields = components(side: side || :left)
91
145
  else
92
146
  ids_ary = component_ids
93
- fields = components
94
- end
95
- if after
96
- after_fld = fields.find do |fld|
97
- found = nil
98
- found ||= !!after if after.is_a?(Ecoportal::API::V2::Page::Component)
99
- found ||= fld.id == after
100
- found ||= same_string?(fld.label, after)
101
- end
102
147
  end
103
- ids_ary.insert_one(field.id, after: after_fld&.id)
148
+
149
+ ids_ary.insert_one(field.id, before: before_fld&.id, after: after_fld&.id)
104
150
  self
105
151
  end
106
152
 
@@ -113,6 +159,20 @@ module Ecoportal
113
159
  end
114
160
  end
115
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
116
176
  end
117
177
  end
118
178
  end
@@ -7,12 +7,20 @@ 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`
15
+ # @note
16
+ # - It won't fix weights unless all the sections of the ooze are present
17
+ # - This means that it doesn't fix section weights on stages,
18
+ # as shared sections could change order in other stages
11
19
  def add(name: nil, split: false, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
12
20
  sec_doc = section_class.new_doc(split: split)
13
21
  upsert!(sec_doc) do |section| #, pos: pos, before: before, after: after) do |section|
14
22
  section.heading = name
15
- if weight = scope_weight(pos: pos, before: before, after: after)
23
+ if weight = scope_weight(section, pos: pos, before: before, after: after)
16
24
  section.weight = weight
17
25
  end
18
26
  fix_weights!
@@ -20,12 +28,21 @@ module Ecoportal
20
28
  end
21
29
  end
22
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>]
23
39
  def get_by_type(type)
24
40
  ordered.select do |sec|
25
41
  sec.type == type
26
42
  end
27
43
  end
28
44
 
45
+ # @return [Array<Ecoportal::API::V2::Page::Section>]
29
46
  def get_by_heading(heading)
30
47
  ordered.select do |sec|
31
48
  value = heading == :unnamed ? nil : heading
@@ -34,6 +51,7 @@ module Ecoportal
34
51
  end
35
52
 
36
53
  # Gets all the sections between `sec1` and `sec2`
54
+ # @return [Array<Ecoportal::API::V2::Page::Section>]
37
55
  def between(sec1, sec2, included: false)
38
56
  sorted_secs = ordered
39
57
  pos1 = (sec1 = to_section(sec1)) && sorted_secs.index(sec1)
@@ -49,15 +67,21 @@ module Ecoportal
49
67
  end
50
68
 
51
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`
52
71
  def ordered
53
72
  self.sort_by.with_index do |section, index|
54
- (section.weight >= 9999) ? [index, index] : [section.weight, index]
73
+ [section.weight, index]
55
74
  end
56
75
  end
57
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
+
58
82
  private
59
83
 
60
- def scope_weight(pos: NOT_USED, before: NOT_USED, after: NOT_USED)
84
+ def scope_weight(section, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
61
85
  case
62
86
  when used_param?(pos)
63
87
  if pos = to_section(pos)
@@ -71,6 +95,11 @@ module Ecoportal
71
95
  if after = to_section(after)
72
96
  after.weight
73
97
  end
98
+ end.yield_self do |weight|
99
+ weight = ordered.reject do |sec|
100
+ sec.id == section.id
101
+ end.last&.weight
102
+ weight ||= section_class.const_get(:INITIAL_WEIGHT)
74
103
  end
75
104
  end
76
105
 
@@ -86,8 +115,10 @@ module Ecoportal
86
115
  end
87
116
 
88
117
  def fix_weights!
89
- ordered.each_with_index do |section, index|
90
- section.weight = index
118
+ unless self._parent.is_a?(Ecoportal::API::V2::Pages::PageStage)
119
+ ordered.each_with_index do |section, index|
120
+ section.weight = index
121
+ end
91
122
  end
92
123
  end
93
124
 
@@ -97,7 +128,6 @@ module Ecoportal
97
128
  return if pos < 0
98
129
  secs[pos]
99
130
  end
100
-
101
131
  end
102
132
  end
103
133
  end
@@ -17,19 +17,55 @@ 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|
23
30
  puts "Warning: section #{id} points to missing section #{sec_ids[i]}" if !sec
24
31
  fld && (!block_given? || yield(sec))
25
- end.sort_by {|sec| sec.weight}
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 {|sec| section_ids.insert_one(sec.id)}
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)
@@ -14,9 +20,9 @@ module Ecoportal
14
20
  end
15
21
 
16
22
  #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)
23
+ # self.sort_by.with_index do |stage, index|
24
+ # [stage.ordering, index]
25
+ # end
20
26
  #end
21
27
 
22
28
  end
@@ -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,10 +24,20 @@ 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
33
+
34
+ def initialize(doc = [], parent: self, key: nil)
35
+ super(_doc_bug_fix(doc), parent: parent, key: key)
36
+ end
37
+
38
+ def ooze
39
+ self
40
+ end
31
41
 
32
42
  def as_update
33
43
  super.tap do |hash|
@@ -40,6 +50,39 @@ module Ecoportal
40
50
  end
41
51
  end
42
52
 
53
+ def stages?
54
+ self.stages.count > 0
55
+ end
56
+
57
+ private
58
+
59
+ def _doc_bug_fix(hash)
60
+ hash.tap do |hash|
61
+ _fix_doc(hash["stages"], "flow_node_ids", "section_ids") if hash.key?("stages")
62
+ if hash.key?("sections")
63
+ _fix_doc(hash["sections"], "membrane_ids", "component_ids")
64
+ _fix_doc(hash["sections"], "left_membrane_ids", "left_component_ids")
65
+ _fix_doc(hash["sections"], "right_membrane_ids", "right_component_ids")
66
+ end
67
+ end
68
+ end
69
+
70
+ def _fix_doc(value, source, dest)
71
+ value.tap do |value|
72
+ case value
73
+ when Array
74
+ value.each {|v| _fix_doc(v, source, dest)}
75
+ when Hash
76
+ if value.key?(source) && !value.key?(dest)
77
+ value[dest] = value[source]
78
+ value.delete(source)
79
+ end
80
+ else
81
+ # Do nothing!
82
+ end
83
+ end
84
+ end
85
+
43
86
  end
44
87
  end
45
88
  end
@@ -53,3 +96,5 @@ require 'ecoportal/api/v2/page/section'
53
96
  require 'ecoportal/api/v2/page/sections'
54
97
  require 'ecoportal/api/v2/page/stage'
55
98
  require 'ecoportal/api/v2/page/stages'
99
+ require 'ecoportal/api/v2/page/force'
100
+ require 'ecoportal/api/v2/page/forces'
@@ -9,6 +9,57 @@ 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
+ # @return [String] `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
+
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
+
12
63
  end
13
64
  end
14
65
  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