ecoportal-api-v2 0.8.6 → 0.8.10

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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +73 -28
  3. data/bin/console +1 -1
  4. data/ecoportal-api-v2.gemspec +5 -5
  5. data/lib/ecoportal/api-v2.rb +2 -2
  6. data/lib/ecoportal/api/common.v2.rb +8 -0
  7. data/lib/ecoportal/api/common/content.rb +1 -0
  8. data/lib/ecoportal/api/common/content/array_model.rb +8 -6
  9. data/lib/ecoportal/api/common/content/collection_model.rb +45 -20
  10. data/lib/ecoportal/api/common/content/double_model.rb +98 -9
  11. data/lib/ecoportal/api/common/content/hash_diff_patch.rb +44 -22
  12. data/lib/ecoportal/api/common/content/model_helpers.rb +36 -0
  13. data/lib/ecoportal/api/v2/page.rb +15 -2
  14. data/lib/ecoportal/api/v2/page/component.rb +44 -10
  15. data/lib/ecoportal/api/v2/page/component/action.rb +17 -8
  16. data/lib/ecoportal/api/v2/page/component/action_field.rb +37 -2
  17. data/lib/ecoportal/api/v2/page/component/chart_field.rb +43 -5
  18. data/lib/ecoportal/api/v2/page/component/chart_field/benchmark.rb +30 -0
  19. data/lib/ecoportal/api/v2/page/component/chart_field/config.rb +23 -0
  20. data/lib/ecoportal/api/v2/page/component/chart_field/frequency.rb +3 -4
  21. data/lib/ecoportal/api/v2/page/component/chart_field/heatmap.rb +1 -3
  22. data/lib/ecoportal/api/v2/page/component/chart_field/indicator.rb +4 -5
  23. data/lib/ecoportal/api/v2/page/component/chart_field/multiseries.rb +3 -5
  24. data/lib/ecoportal/api/v2/page/component/chart_field/sankey.rb +1 -3
  25. data/lib/ecoportal/api/v2/page/component/chart_field/serie.rb +3 -4
  26. data/lib/ecoportal/api/v2/page/component/chart_field/series_config.rb +5 -7
  27. data/lib/ecoportal/api/v2/page/component/chart_fr_field.rb +7 -5
  28. data/lib/ecoportal/api/v2/page/component/checklist_field.rb +1 -1
  29. data/lib/ecoportal/api/v2/page/component/checklist_item.rb +7 -5
  30. data/lib/ecoportal/api/v2/page/component/date_field.rb +71 -4
  31. data/lib/ecoportal/api/v2/page/component/file.rb +14 -3
  32. data/lib/ecoportal/api/v2/page/component/files_field.rb +37 -1
  33. data/lib/ecoportal/api/v2/page/component/gauge_field.rb +2 -2
  34. data/lib/ecoportal/api/v2/page/component/gauge_stop.rb +5 -5
  35. data/lib/ecoportal/api/v2/page/component/geo_coordinates.rb +13 -0
  36. data/lib/ecoportal/api/v2/page/component/geo_field.rb +4 -1
  37. data/lib/ecoportal/api/v2/page/component/image.rb +2 -1
  38. data/lib/ecoportal/api/v2/page/component/images_field.rb +57 -1
  39. data/lib/ecoportal/api/v2/page/component/number_field.rb +1 -0
  40. data/lib/ecoportal/api/v2/page/component/people_field.rb +117 -7
  41. data/lib/ecoportal/api/v2/page/component/people_viewable_field.rb +14 -0
  42. data/lib/ecoportal/api/v2/page/component/plain_text_field.rb +34 -2
  43. data/lib/ecoportal/api/v2/page/component/reference_field.rb +32 -3
  44. data/lib/ecoportal/api/v2/page/component/selection_field.rb +65 -7
  45. data/lib/ecoportal/api/v2/page/component/selection_option.rb +16 -5
  46. data/lib/ecoportal/api/v2/page/component/signature_field.rb +3 -2
  47. data/lib/ecoportal/api/v2/page/component/tag_field.rb +31 -1
  48. data/lib/ecoportal/api/v2/page/components.rb +8 -3
  49. data/lib/ecoportal/api/v2/page/permission_flags.rb +67 -0
  50. data/lib/ecoportal/api/v2/page/permit.rb +15 -0
  51. data/lib/ecoportal/api/v2/page/section.rb +70 -9
  52. data/lib/ecoportal/api/v2/page/sections.rb +64 -6
  53. data/lib/ecoportal/api/v2/page/stage.rb +12 -4
  54. data/lib/ecoportal/api/v2/page/stages.rb +7 -7
  55. data/lib/ecoportal/api/v2/pages/page_stage.rb +3 -3
  56. data/lib/ecoportal/api/v2_version.rb +5 -0
  57. metadata +17 -10
  58. data/lib/ecoportal/api/common.rb +0 -18
  59. data/lib/ecoportal/api/v2/version.rb +0 -7
@@ -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,41 +77,59 @@ 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
86
94
 
87
95
  def patch_delete(b)
88
- return NO_CHANGES unless b.is_a?(Hash) && id = get_id(b, exception: false)
89
- {
90
- "id" => id,
91
- "operation" => "deleted",
92
- "data" => patch_data(b, delete: true)
93
- }
96
+ return NO_CHANGES unless b.is_a?(Hash)
97
+ if id = get_id(b, exception: false)
98
+ {
99
+ "id" => id,
100
+ "operation" => "deleted",
101
+ "data" => patch_data(b, delete: true)
102
+ }
103
+ else
104
+ nil
105
+ end
94
106
  end
95
107
 
96
108
  def patch_new(a)
97
- return NO_CHANGES unless a.is_a?(Hash) && id = get_id(a, exception: false)
98
- {
99
- "id" => id,
100
- "operation" => "new",
101
- "data" => patch_data(a)
102
- }
109
+ return NO_CHANGES unless a.is_a?(Hash)
110
+ if id = get_id(a, exception: false)
111
+ {
112
+ "id" => id,
113
+ "operation" => "new",
114
+ "data" => patch_data(a)
115
+ }
116
+ else
117
+ a
118
+ end
103
119
  end
104
120
 
105
121
  def patch_update(a, b)
106
- return NO_CHANGES unless a.is_a?(Hash) && id = get_id(a, exception: false)
107
- {
108
- "id" => id,
109
- "operation" => "changed",
110
- "data" => patch_data(a, b)
111
- }.tap do |update_hash|
112
- return nil unless update_hash["data"] != NO_CHANGES
122
+ return NO_CHANGES unless a.is_a?(Hash)
123
+ if id = get_id(a, exception: false)
124
+ {
125
+ "id" => id,
126
+ "operation" => "changed",
127
+ "data" => patch_data(a, b)
128
+ }.tap do |update_hash|
129
+ return nil unless update_hash["data"] != NO_CHANGES
130
+ end
131
+ else
132
+ a
113
133
  end
114
134
  end
115
135
 
@@ -160,7 +180,9 @@ module Ecoportal
160
180
  arr.any? {|a| nested_array?(a)}
161
181
  when arr.length == 1
162
182
  arr = arr.first
163
- arr.any? {|item| item.is_a?(Hash)}
183
+ arr.any? do |item|
184
+ item.is_a?(Hash) && item.has_key?("patch_ver")
185
+ end
164
186
  else
165
187
  false
166
188
  end
@@ -0,0 +1,36 @@
1
+ module Ecoportal
2
+ module API
3
+ module Common
4
+ module Content
5
+ module ModelHelpers
6
+
7
+ private
8
+
9
+ # Offers multiple ways to compare two strings
10
+ def same_string?(value1, value2, exact: false)
11
+ case
12
+ when value1.is_a?(String) && value2.is_a?(String)
13
+ if exact
14
+ value1 == value2
15
+ else
16
+ value1.to_s.strip.downcase == value2.to_s.strip.downcase
17
+ end
18
+ when value1.is_a?(Regexp) && value2.is_a?(String)
19
+ value2 =~ value1
20
+ when value1.is_a?(String) && value2.is_a?(Regexp)
21
+ value1 =~ value2
22
+ else
23
+ value1 == value2
24
+ end
25
+ end
26
+
27
+ def hash_except(hash, *keys)
28
+ keys.each {|key| hash.delete(key)}
29
+ hash
30
+ end
31
+
32
+ end
33
+ end
34
+ end
35
+ end
36
+ 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
@@ -25,6 +35,7 @@ module Ecoportal
25
35
  hash["data"].select! do |key, value|
26
36
  ALLOWED_KEYS.include?(key)
27
37
  end
38
+ return nil if (hash["data"].keys - ["patch_ver"]).empty?
28
39
  end
29
40
  end
30
41
  end
@@ -34,6 +45,8 @@ module Ecoportal
34
45
  end
35
46
  end
36
47
 
48
+ require 'ecoportal/api/v2/page/permission_flags'
49
+ require 'ecoportal/api/v2/page/permit'
37
50
  require 'ecoportal/api/v2/page/component'
38
51
  require 'ecoportal/api/v2/page/components'
39
52
  require 'ecoportal/api/v2/page/section'
@@ -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)
@@ -59,7 +62,6 @@ module Ecoportal
59
62
  when "checklist"
60
63
  checklist_field_class
61
64
  when "page_action","checklist_task"
62
- #doc["type"] = "checklist_task"
63
65
  action_field_class
64
66
  when "file"
65
67
  files_field_class
@@ -83,10 +85,12 @@ module Ecoportal
83
85
  end
84
86
 
85
87
  passkey :id
86
- passthrough :patch_ver, :undeletable
88
+ passforced :patch_ver, default: 1
89
+ passboolean :undeletable
87
90
  passthrough :type, :label, :tooltip, :global_binding
88
- passthrough :hidden, :accent, :deindex, :required
89
- passthrough :hide_view, :hidden_on_reports, :hidden_on_mobile
91
+ passboolean :hidden, :deindex, :required
92
+ passthrough :accent
93
+ passboolean :hide_view, :hidden_on_reports, :hidden_on_mobile
90
94
  passarray :refs
91
95
 
92
96
  def ref_backend
@@ -107,6 +111,36 @@ module Ecoportal
107
111
  self.class.indexable_label(label)
108
112
  end
109
113
 
114
+ # Quick config helper
115
+ # @param conf [Symbol, Array<Symbol>]
116
+ # - `:required`
117
+ # - `:hide_view` to hide in view mode
118
+ # - `:hide_mobile` to hide in mobile app
119
+ # - `:hide_reports` to hide in reports
120
+ # - `:global` to define a global binding
121
+ def configure(*conf)
122
+ conf.each_with_object([]) do |cnf, unused|
123
+ case cnf
124
+ when :required
125
+ self.required = true
126
+ when :hide_view
127
+ self.hide_view = true
128
+ when :hide_mobile
129
+ self.hidden_on_mobile = true
130
+ when :hide_reports
131
+ self.hidden_on_reports = true
132
+ when Hash
133
+ if cnf.key?(:global)
134
+ self.global_binding = cnf[:global]
135
+ end
136
+ else
137
+ unused.push(cnf)
138
+ end
139
+ end.tap do |unused|
140
+ raise "Unsupported configuration options '#{unused}' for #{self.class}" unless unused.empty?
141
+ end
142
+ end
143
+
110
144
  end
111
145
  end
112
146
  end
@@ -7,19 +7,28 @@ 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" => 9999
12
12
  }
13
13
  end
14
14
  end
15
-
15
+
16
16
  passkey :id
17
- passthrough :patch_ver, :name
18
- passthrough :weight, :complete, :other_information
19
- passdate :due_date
20
- pass_reader :overdue
17
+ passforced :patch_ver, default: 1
18
+ passthrough :name
19
+ passthrough :weight, :other_information
20
+ passboolean :complete
21
+
21
22
  passdate :created_at, read_only: true #, :completed_at
22
- pass_reader :created_by, :assigned_person_member_id
23
+ passthrough :created_by, read_only: true
24
+ passthrough :assigned_person_member_id, :assigned_person_member
25
+
26
+ passdate :due_date, :reminder_date
27
+ passboolean :overdue, read_only: true
28
+
29
+ passthrough :duration_in_days, read_only: true
30
+ passarray :file_container_ids
31
+
23
32
  end
24
33
  end
25
34
  end
@@ -4,9 +4,9 @@ module Ecoportal
4
4
  class Page
5
5
  class Component
6
6
  class ActionField < Page::Component
7
- passthrough :create_actions
7
+ passboolean :create_actions
8
8
  passthrough :required_number_of_completed_actions
9
- passthrough :permits_and_rules_integration, :add_subscribed, :add_subscribed_to_tasks
9
+ passboolean :permits_and_rules_integration, :add_subscribed, :add_subscribed_to_tasks
10
10
 
11
11
  embeds_many :actions, klass: "Ecoportal::API::V2::Page::Component::Action", order_key: :weight
12
12
 
@@ -30,8 +30,43 @@ module Ecoportal
30
30
  end.map(&:first)
31
31
  end
32
32
 
33
+ # Quick config helper
34
+ # @param conf [Symbol, Array<Symbol>]
35
+ # - `:requires` required number of completed actions
36
+ # - `:all`
37
+ # - `#Number`
38
+ def configure(*conf)
39
+ self.create_actions = true
40
+ conf.each_with_object([]) do |cnf, unused|
41
+ case cnf
42
+ when Hash
43
+ supported = [:requires]
44
+ unless (rest = hash_except(cnf.dup, *supported)).empty?
45
+ unused.push(rest)
46
+ end
47
+ if cnf.key?(:requires) then configure_required(cnf[:requires]) end
48
+ else
49
+ unused.push(cnf)
50
+ end
51
+ end.yield_self do |unused|
52
+ super(*unused)
53
+ end
54
+ end
55
+
33
56
  private
34
57
 
58
+ def configure_required(req)
59
+ self.required = true
60
+ case req
61
+ when :all, NilClass
62
+ self.required_number_of_completed_actions = "all"
63
+ when Numeric
64
+ self.required_number_of_completed_actions = req
65
+ else
66
+ # Unsupported
67
+ end
68
+ end
69
+
35
70
  def fix_task_weights!
36
71
  ordered_tasks.each_with_index do |task, index|
37
72
  task.weight = index
@@ -5,10 +5,14 @@ module Ecoportal
5
5
  class Component
6
6
  class ChartField < Page::Component
7
7
  passthrough :mode
8
- passthrough :relative, :relstart, :relbound
9
- passthrough :bounded, :ubound, :lbound
8
+ passboolean :relative, :bounded
9
+ passthrough :relstart, :relbound
10
+ passthrough :ubound, :lbound
11
+
10
12
  passthrough :filter_date_input
11
- passthrough :user_id, :lock_chart_user
13
+
14
+ passthrough :user_id, :user_lookup
15
+ passboolean :lock_chart_user
12
16
 
13
17
  embeds_one :series_config, klass: "Ecoportal::API::V2::Page::Component::ChartField::SeriesConfig"
14
18
  embeds_one :frequency_config, klass: "Ecoportal::API::V2::Page::Component::ChartField::Frequency"
@@ -16,13 +20,22 @@ module Ecoportal
16
20
  embeds_one :sankey_config, klass: "Ecoportal::API::V2::Page::Component::ChartField::Sankey"
17
21
  embeds_one :indicator_config, klass: "Ecoportal::API::V2::Page::Component::ChartField::Indicator"
18
22
  embeds_one :faceted_series_config, klass: "Ecoportal::API::V2::Page::Component::ChartField::Multiseries"
23
+ embeds_one :benchmark_config, klass: "Ecoportal::API::V2::Page::Component::ChartField::Benchmark"
19
24
 
20
25
  embeds_many :series, klass: "Ecoportal::API::V2::Page::Component::ChartField::Serie"
21
26
 
22
- MODES = ["frequency", "series", "heatmap", "sankey", "indicator", "faceted_series"]
27
+ MODES = ["frequency", "series", "heatmap", "sankey", "indicator", "faceted_series", "benchmark"]
28
+
29
+ def mode=(value)
30
+ raise "Unsuported mode #{value}. Should be one of #{MODES}" unless MODES.include?(value)
31
+ config_doc(nil)
32
+ doc["mode"] = value
33
+ config_doc(config.class.new_doc)
34
+ self.mode
35
+ end
23
36
 
24
37
  def config
25
- case mode
38
+ case self.mode
26
39
  when "frequency"
27
40
  frequency_config
28
41
  when "series"
@@ -35,6 +48,29 @@ module Ecoportal
35
48
  indicator_config
36
49
  when "faceted_series"
37
50
  faceted_series_config
51
+ when "benchmark"
52
+ benchmark_config
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ def config_doc(value)
59
+ case self.mode
60
+ when "frequency"
61
+ doc["frequency_config"] = value
62
+ when "series"
63
+ doc["series_config"] = value
64
+ when "heatmap"
65
+ doc["heatmap_config"] = value
66
+ when "sankey"
67
+ doc["sankey_config"] = value
68
+ when "indicator"
69
+ doc["indicator_config"] = value
70
+ when "faceted_series"
71
+ doc["faceted_series_config"] = value
72
+ when "benchmark"
73
+ doc["benchmark_config"] = value
38
74
  end
39
75
  end
40
76
 
@@ -45,6 +81,7 @@ module Ecoportal
45
81
  end
46
82
  end
47
83
 
84
+ require 'ecoportal/api/v2/page/component/chart_field/config'
48
85
  require 'ecoportal/api/v2/page/component/chart_field/frequency'
49
86
  require 'ecoportal/api/v2/page/component/chart_field/series_config'
50
87
  require 'ecoportal/api/v2/page/component/chart_field/serie'
@@ -52,3 +89,4 @@ require 'ecoportal/api/v2/page/component/chart_field/heatmap'
52
89
  require 'ecoportal/api/v2/page/component/chart_field/sankey'
53
90
  require 'ecoportal/api/v2/page/component/chart_field/indicator'
54
91
  require 'ecoportal/api/v2/page/component/chart_field/multiseries'
92
+ require 'ecoportal/api/v2/page/component/chart_field/benchmark'
@@ -0,0 +1,30 @@
1
+ module Ecoportal
2
+ module API
3
+ class V2
4
+ class Page
5
+ class Component
6
+ class ChartField
7
+ class Benchmark < ChartField::Config
8
+ passthrough :register_id, :source_type
9
+
10
+ passthrough :benchmark_field, :benchmark_label
11
+
12
+ passboolean :across
13
+ passthrough :across_field
14
+
15
+ passboolean :grouped
16
+ passthrough :group_field
17
+
18
+ passthrough :against_field, :against_label
19
+
20
+ passthrough :calculation_mode
21
+ passthrough :min, :max
22
+
23
+ passthrough :filters
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end