ecoportal-api-v2 0.8.8 → 0.8.9

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +38 -3
  3. data/lib/ecoportal/api/common/content.rb +1 -0
  4. data/lib/ecoportal/api/common/content/array_model.rb +8 -6
  5. data/lib/ecoportal/api/common/content/collection_model.rb +10 -4
  6. data/lib/ecoportal/api/common/content/double_model.rb +11 -0
  7. data/lib/ecoportal/api/common/content/hash_diff_patch.rb +31 -19
  8. data/lib/ecoportal/api/common/content/model_helpers.rb +36 -0
  9. data/lib/ecoportal/api/v2/page.rb +1 -0
  10. data/lib/ecoportal/api/v2/page/component.rb +33 -3
  11. data/lib/ecoportal/api/v2/page/component/action.rb +13 -5
  12. data/lib/ecoportal/api/v2/page/component/action_field.rb +37 -2
  13. data/lib/ecoportal/api/v2/page/component/chart_field.rb +39 -5
  14. data/lib/ecoportal/api/v2/page/component/chart_field/benchmark.rb +9 -7
  15. data/lib/ecoportal/api/v2/page/component/chart_field/config.rb +23 -0
  16. data/lib/ecoportal/api/v2/page/component/chart_field/frequency.rb +3 -4
  17. data/lib/ecoportal/api/v2/page/component/chart_field/heatmap.rb +1 -3
  18. data/lib/ecoportal/api/v2/page/component/chart_field/indicator.rb +4 -5
  19. data/lib/ecoportal/api/v2/page/component/chart_field/multiseries.rb +3 -5
  20. data/lib/ecoportal/api/v2/page/component/chart_field/sankey.rb +1 -3
  21. data/lib/ecoportal/api/v2/page/component/chart_field/serie.rb +3 -4
  22. data/lib/ecoportal/api/v2/page/component/chart_field/series_config.rb +5 -7
  23. data/lib/ecoportal/api/v2/page/component/chart_fr_field.rb +7 -5
  24. data/lib/ecoportal/api/v2/page/component/checklist_field.rb +1 -1
  25. data/lib/ecoportal/api/v2/page/component/checklist_item.rb +3 -2
  26. data/lib/ecoportal/api/v2/page/component/date_field.rb +71 -4
  27. data/lib/ecoportal/api/v2/page/component/file.rb +3 -2
  28. data/lib/ecoportal/api/v2/page/component/gauge_field.rb +2 -2
  29. data/lib/ecoportal/api/v2/page/component/geo_coordinates.rb +13 -0
  30. data/lib/ecoportal/api/v2/page/component/geo_field.rb +4 -1
  31. data/lib/ecoportal/api/v2/page/component/images_field.rb +57 -1
  32. data/lib/ecoportal/api/v2/page/component/people_field.rb +102 -4
  33. data/lib/ecoportal/api/v2/page/component/plain_text_field.rb +34 -2
  34. data/lib/ecoportal/api/v2/page/component/reference_field.rb +32 -3
  35. data/lib/ecoportal/api/v2/page/component/selection_field.rb +59 -3
  36. data/lib/ecoportal/api/v2/page/component/selection_option.rb +2 -1
  37. data/lib/ecoportal/api/v2/page/component/tag_field.rb +31 -1
  38. data/lib/ecoportal/api/v2/page/components.rb +8 -3
  39. data/lib/ecoportal/api/v2/page/permission_flags.rb +67 -0
  40. data/lib/ecoportal/api/v2/page/section.rb +65 -5
  41. data/lib/ecoportal/api/v2/page/sections.rb +64 -6
  42. data/lib/ecoportal/api/v2/page/stage.rb +10 -6
  43. data/lib/ecoportal/api/v2/page/stages.rb +2 -2
  44. data/lib/ecoportal/api/v2/pages/page_stage.rb +0 -1
  45. data/lib/ecoportal/api/v2_version.rb +1 -1
  46. metadata +6 -2
@@ -4,19 +4,117 @@ module Ecoportal
4
4
  class Page
5
5
  class Component
6
6
  class PeopleField < Page::Component
7
- passthrough :is_me_button, :attach_mode
7
+ passboolean :is_me_button
8
+ passthrough :attach_mode
8
9
  passthrough :person_schema_id
9
10
  pass_reader :viewable_fields
10
- passthrough :singular, :requires_number
11
+
12
+ passboolean :singular
13
+ passthrough :requires_number
14
+
11
15
  passarray :people_ids
12
16
  pass_reader :cached_people
13
- passthrough :attached_people_permissions_enabled, :apply_attached_people_permissions_to
14
- passthrough :attached_people_permissions_editable, :attached_people_permissions_flags
15
17
 
18
+ passboolean :attached_people_permissions_enabled, :attached_people_permissions_editable
19
+ passthrough :apply_attached_people_permissions_to
20
+
21
+ embeds_one :attached_people_permissions_flags, klass: "Ecoportal::API::V2::Page::PermissionFlags"
22
+
23
+ # Attaches people
16
24
  def add(*ids)
17
25
  people_ids << ids
18
26
  end
19
27
 
28
+ # Deletes people
29
+ def delete(*ids)
30
+ people_ids.reject! {|id| ids.include?(id)}
31
+ end
32
+
33
+ # Quick config helper
34
+ # @param conf [Symbol, Array<Symbol>]
35
+ # - `:snapshot` to set mode to `snapshot`
36
+ # - `:live` to set mode to `live`
37
+ # - `:me_button` to display `ME` button
38
+ # - `:permits` to define the permissions
39
+ # - `:all` for _entire page/all stages_
40
+ # - `:stages` for _all stages containing this field_
41
+ # - `:page` for _page only_
42
+ # - `:stage` for _only the stage containing this field when attached_
43
+ # - `:restructure`
44
+ # - `:configure`
45
+ # - `:can_permission`
46
+ # - `:create_actions`
47
+ # - `:admin_actions`
48
+ # - `:subscribed`
49
+ # - `:subscribed_to_tasks`
50
+ # - `requires: number` to fine the number of required people to be attached
51
+ def configure(*conf)
52
+ conf.each_with_object([]) do |cnf, unused|
53
+ case cnf
54
+ when :snapshot
55
+ self.attach_mode = "snapshot"
56
+ when :live
57
+ self.attach_mode = "live"
58
+ when :me_button
59
+ self.is_me_button = true
60
+ when :singular
61
+ self.singular = true
62
+ when Hash
63
+ supported = [:singular, :permits, :requires]
64
+ unless (rest = hash_except(cnf.dup, *supported)).empty?
65
+ unused.push(rest)
66
+ end
67
+
68
+ if cnf.key?(:singular) then self.singular = !!cnf[:singular] end
69
+ if cnf.key?(:permits)
70
+ if permits = cnf[:permits]
71
+ self.attached_people_permissions_enabled = true
72
+ configure_permits(*[permits].flatten.compact)
73
+ else
74
+ self.attached_people_permissions_enabled = false
75
+ end
76
+ end
77
+ if cnf.key?(:requires)
78
+ self.singular = false
79
+ if requires = cnf[:requires]
80
+ self.required = true
81
+ self.requires_number = requires
82
+ else
83
+ self.required = false
84
+ self.requires_number = nil
85
+ end
86
+ end
87
+ else
88
+ unused.push(cnf)
89
+ end
90
+ end.yield_self do |unused|
91
+ super(*unused)
92
+ end
93
+ end
94
+
95
+ private
96
+
97
+ def configure_permits(*conf)
98
+ conf.each_with_object([]) do |cnf, flags|
99
+ case cnf
100
+ when :all
101
+ self.apply_attached_people_permissions_to = "page"
102
+ when :stages
103
+ self.apply_attached_people_permissions_to = "all_stages"
104
+ when :page
105
+ self.apply_attached_people_permissions_to = "page_only"
106
+ when :stage
107
+ self.apply_attached_people_permissions_to = "current_stage"
108
+ when :can_edit
109
+ self.attached_people_permissions_editable = true
110
+ else
111
+ flags.push(cnf)
112
+ end
113
+ end.yield_self do |flags|
114
+ self.attached_people_permissions_flags.configure *flags
115
+ end
116
+ end
117
+
20
118
  end
21
119
  end
22
120
  end
@@ -5,8 +5,40 @@ module Ecoportal
5
5
  class Component
6
6
  class PlainTextField < Page::Component
7
7
  passthrough :value
8
- passthrough :multiline, :max_length
9
- pass_reader :exact_index
8
+ passboolean :multiline
9
+ passthrough :max_length
10
+ passboolean :exact_index
11
+
12
+ # Quick config helper
13
+ # @param conf [Symbol, Array<Symbol>]
14
+ # - `:multiline` multi line mode
15
+ # - `:singleline` signle line mode
16
+ # - `:exact_index` to make the `value` indexed as a **whole** (as opposite to its parts or n-grams)
17
+ # - `:max_length` specify the maximum length of the `value`
18
+ def configure(*conf)
19
+ conf.each_with_object([]) do |cnf, unused|
20
+ case cnf
21
+ when :multiline
22
+ self.multiline = true
23
+ when :singleline
24
+ self.multiline = false
25
+ when :exact_index
26
+ self.exact_index = true
27
+ when Hash
28
+ supported = [:multiline, :max_length]
29
+ unless (rest = hash_except(cnf.dup, *supported)).empty?
30
+ unused.push(rest)
31
+ end
32
+ if cnf.key?(:multiline) then self.multiline = !!cnf[:multiline] end
33
+ if cnf.key?(:max_length) then self.max_length = cnf[:max_length] end
34
+ else
35
+ unused.push(cnf)
36
+ end
37
+ end.yield_self do |unused|
38
+ super(*unused)
39
+ end
40
+ end
41
+
10
42
  end
11
43
  end
12
44
  end
@@ -5,9 +5,38 @@ module Ecoportal
5
5
  class Component
6
6
  class ReferenceField < Page::Component
7
7
  passthrough :register_id
8
- passthrough :hide_create, :hide_attach
9
- passthrough :hide_metadata, :hide_dashboards
10
- passthrough :display_fields, :display_fields_in_lookup
8
+ passboolean :hide_create, :hide_attach
9
+ passboolean :hide_metadata, :hide_dashboards
10
+ passboolean :display_fields, :display_fields_in_lookup
11
+
12
+ # Quick config helper
13
+ # @param conf [Symbol, Array<Symbol>]
14
+ # - `:show_fields` specify if the public register fields should be shown (requires `register_id`)
15
+ # - `:create` specify if the `NEW` button should appear
16
+ # - `:attach` specify if the `ATTACH` button should appear
17
+ # - `:metadata` specify if `metadata` should be shown (i.e. status)
18
+ def configure(*conf)
19
+ conf.each_with_object([]) do |cnf, unused|
20
+ case cnf
21
+ when :show_fields
22
+ self.display_fields = true
23
+ self.display_fields_in_lookup = true
24
+ when Hash
25
+ supported = [:create, :attach, :metadata]
26
+ unless (rest = hash_except(cnf.dup, *supported)).empty?
27
+ unused.push(rest)
28
+ end
29
+ if cnf.key?(:create) then self.hide_create = !cnf[:create] end
30
+ if cnf.key?(:attach) then self.hide_attach = !cnf[:attach] end
31
+ if cnf.key?(:metadata) then self.hide_metadata = !cnf[:metadata] end
32
+ else
33
+ unused.push(cnf)
34
+ end
35
+ end.yield_self do |unused|
36
+ super(*unused)
37
+ end
38
+ end
39
+
11
40
  end
12
41
  end
13
42
  end
@@ -4,8 +4,8 @@ module Ecoportal
4
4
  class Page
5
5
  class Component
6
6
  class SelectionField < Page::Component
7
- passthrough :multiple, :flat
8
- passthrough :other, :other_desc
7
+ passboolean :multiple, :flat, :other
8
+ passthrough :other_desc
9
9
  passthrough :data_type
10
10
 
11
11
  embeds_many :options, klass: "Ecoportal::API::V2::Page::Component::SelectionOption", order_key: :weight
@@ -44,7 +44,7 @@ module Ecoportal
44
44
  end
45
45
  end
46
46
 
47
- def add_option(name:, value:, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
47
+ def add_option(value:, name: nil, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
48
48
  opt_doc = options.items_class.new_doc
49
49
  options.upsert!(opt_doc, pos: pos, before: before, after: after) do |option|
50
50
  option.name = name
@@ -63,8 +63,64 @@ module Ecoportal
63
63
  end.map(&:first)
64
64
  end
65
65
 
66
+ # Quick config helper
67
+ # @param conf [Symbol, Array<Symbol>]
68
+ # - `:flat` to display in flat mode
69
+ # - `:multiple` to allow multiple selection
70
+ # - `:single` to set to singular selection
71
+ # - `:other` to enable `other` button
72
+ # - `:options` to add options (`Hash<value, name>`)
73
+ # - `:type` to define the type
74
+ # - `:num`
75
+ # - `:str`
76
+ def configure(*conf)
77
+ conf.each_with_object([]) do |cnf, unused|
78
+ case cnf
79
+ when :flat
80
+ self.flat = true
81
+ when :multiple
82
+ self.multiple = true
83
+ when :single
84
+ self.multiple = false
85
+ when :other
86
+ self.other = true
87
+ when Hash
88
+ supported = [:flat, :options, :type]
89
+ unless (rest = hash_except(cnf.dup, *supported)).empty?
90
+ unused.push(rest)
91
+ end
92
+
93
+ if cnf.key?(:flat) then self.flat = cnf[:flat] end
94
+ if cnf.key?(:options)
95
+ if opts = cnf[:options]
96
+ configure_options opts
97
+ end
98
+ end
99
+ if cnf.key?(:type)
100
+ if cnf[:type] == :str
101
+ self.text!
102
+ elsif cnf[:type] == :num
103
+ self.numeric!
104
+ else
105
+ # Unknown type
106
+ end
107
+ end
108
+ else
109
+ unused.push(cnf)
110
+ end
111
+ end.yield_self do |unused|
112
+ super(*unused)
113
+ end
114
+ end
115
+
66
116
  private
67
117
 
118
+ def configure_options(opts)
119
+ opts.each do |val, nm|
120
+ add_option(value: val, name: nm)
121
+ end
122
+ end
123
+
68
124
  def fix_option_weights!
69
125
  ordered_options.each_with_index do |option, index|
70
126
  option.weight = index
@@ -16,7 +16,8 @@ module Ecoportal
16
16
 
17
17
  passkey :id
18
18
  passthrough :patch_ver, :name, :value
19
- passthrough :weight, :selected
19
+ passthrough :weight
20
+ passboolean :selected
20
21
 
21
22
  def numeric!
22
23
  self.value = block_given?? yield(value) : value.to_i
@@ -4,8 +4,38 @@ module Ecoportal
4
4
  class Page
5
5
  class Component
6
6
  class TagField < Page::Component
7
- passthrough :single_select, :use_defaults
7
+ passboolean :single_select, :use_defaults
8
8
  passthrough :tag_tree_id, :button_text
9
+
10
+ # Quick config helper
11
+ # @param conf [Symbol, Array<Symbol>]
12
+ # - `:multiple` to allow multiple selection
13
+ # - `:single` to set to singular selection
14
+ # - `:default_tag` to prepopulate using users's `default_tag`
15
+ # - `:button_text` to define the button description
16
+ def configure(*conf)
17
+ conf.each_with_object([]) do |cnf, unused|
18
+ case cnf
19
+ when :single
20
+ self.single_select = true
21
+ when :multiple
22
+ self.single_select = false
23
+ when :default_tag
24
+ self.use_defaults = true
25
+ when Hash
26
+ supported = [:button_text]
27
+ unless (rest = hash_except(cnf.dup, *supported)).empty?
28
+ unused.push(rest)
29
+ end
30
+ if cnf.key?(:button_text) then self.button_text = cnf[:button_text] end
31
+ else
32
+ unused.push(cnf)
33
+ end
34
+ end.yield_self do |unused|
35
+ super(*unused)
36
+ end
37
+ end
38
+
9
39
  end
10
40
  end
11
41
  end
@@ -13,6 +13,12 @@ module Ecoportal
13
13
 
14
14
  order_matters = true
15
15
 
16
+ def get_by_id(id)
17
+ self.find do |comp|
18
+ comp.id == id
19
+ end
20
+ end
21
+
16
22
  def get_by_type(type)
17
23
  self.select do |comp|
18
24
  comp.type.downcase == type.to_s.strip.downcase
@@ -21,10 +27,9 @@ module Ecoportal
21
27
 
22
28
  def get_by_name(name, type: nil)
23
29
  pool = type ? get_by_type(type) : self
24
-
25
30
  pool.select do |comp|
26
- comp.label.to_s.strip.downcase == name.to_s.strip.downcase
27
- end.first
31
+ same_string?(comp.label, name)
32
+ end
28
33
  end
29
34
 
30
35
  def add(label:, type:)
@@ -0,0 +1,67 @@
1
+ module Ecoportal
2
+ module API
3
+ class V2
4
+ class Page
5
+ class PermissionFlags < Common::Content::DoubleModel
6
+ class << self
7
+ def new_doc
8
+ {
9
+ "can_restructure" => false,
10
+ "can_configure" => false,
11
+ "can_permission" => false,
12
+ "can_create_actions" => false,
13
+ "can_administrate_actions" => false,
14
+ "subscribed" => false,
15
+ "subscribed_to_tasks" => false
16
+ }
17
+ end
18
+ end
19
+
20
+ passboolean :can_restructure, :can_configure
21
+ passboolean :can_permission, :can_create_actions, :can_administrate_actions
22
+ passboolean :subscribed, :subscribed_to_tasks
23
+
24
+ def reset!
25
+ doc.merge!(self.class.new_doc)
26
+ end
27
+
28
+ # Quick config helper
29
+ # @param conf [Symbol, Array<Symbol>]
30
+ # - `:restructure`
31
+ # - `:configure`
32
+ # - `:can_permission`
33
+ # - `:create_actions`
34
+ # - `:admin_actions`
35
+ # - `:subscribed`
36
+ # - `:subscribed_to_tasks`
37
+ def configure(*conf)
38
+ conf.each_with_object([]) do |cnf, unused|
39
+ case cnf
40
+ when :restructure
41
+ self.can_restructure = true
42
+ when :configure
43
+ self.can_configure = true
44
+ when :can_permission
45
+ self.can_permission = true
46
+ when :create_actions
47
+ self.can_create_actions = true
48
+ when :admin_actions
49
+ self.can_administrate_actions = true
50
+ when :subscribed
51
+ self.subscribed = true
52
+ when :subscribed_to_tasks
53
+ self.subscribed_to_tasks = true
54
+ else
55
+ unused.push(cnf)
56
+ end
57
+ end.yield_self do |unused|
58
+ raise "Unknown configuaration options #{unused}" unless unused.empty?
59
+ end
60
+
61
+ end
62
+
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -8,7 +8,7 @@ module Ecoportal
8
8
  {
9
9
  "id" => new_uuid,
10
10
  "type" => split ? "split" : "content",
11
- "weight" => 9999
11
+ "weight" => 800
12
12
  }.tap do |out|
13
13
  component_ids = if split
14
14
  {
@@ -44,10 +44,70 @@ module Ecoportal
44
44
  all_component_ids.include?(id)
45
45
  end
46
46
 
47
- def components
48
- fld_ids = all_component_ids
49
- root.components.values_at(*fld_ids).select.with_index do |fld, i|
50
- puts "Warning: field #{id} points to missing field #{fld_ids[i]}" if !fld
47
+ def components(side: nil)
48
+ case side
49
+ when :right
50
+ components_right
51
+ when :left
52
+ components_left
53
+ when NilClass
54
+ components_by_id(*all_component_ids)
55
+ else
56
+ raise "Side should be one of [nil, :right, :left]. Given: #{side}"
57
+ end
58
+ end
59
+
60
+ def components_left
61
+ raise "You are trying to retrieve side components in a Split Section" unless split?
62
+ components_by_id(*left_component_ids)
63
+ end
64
+
65
+ def components_right
66
+ raise "You are trying to retrieve side components in a Split Section" unless split?
67
+ components_by_id(*right_component_ids)
68
+ end
69
+
70
+ # Adds `field` to the section
71
+ # @note
72
+ # - To the specified `side`, when split section (default `:left`)
73
+ # - To the end if `after` is not specified
74
+ # - If `after` is specified, it searches field
75
+ # - On the specific `side`, if specified (and split section)
76
+ # - And adds the `field` after it, when found, or at the end if `after` is not found
77
+ # @param field [Ecoportal::API::V2::Page::Component] the field to be added.
78
+ def add_component(field, after: nil, side: nil)
79
+ raise "field should be a Ecoportal::API::V2::Page::Component. Given: #{field.class}" unless field.is_a?(Ecoportal::API::V2::Page::Component)
80
+ if field.section == self
81
+ raise "Field with id '#{field.id}' already belongs to this section"
82
+ elsif sec = field.section
83
+ # Field belongs to another section
84
+ raise "Field with id '#{field.id}' belongs to section '#{sec.heading || "Unnamed"}' (id: '#{sec.id}')"
85
+ end
86
+
87
+ if split?
88
+ ids_ary = side == :right ? right_component_ids : left_component_ids
89
+ fields = components(side: side || :left)
90
+ else
91
+ ids_ary = component_ids
92
+ fields = components
93
+ end
94
+ if after
95
+ after_fld = fields.find do |fld|
96
+ found = nil
97
+ found ||= !!after if after.is_a?(Ecoportal::API::V2::Page::Component)
98
+ found ||= fld.id == after
99
+ found ||= same_string?(fld.label, after)
100
+ end
101
+ end
102
+ ids_ary.insert_one(field.id, after: after_fld&.id)
103
+ self
104
+ end
105
+
106
+ private
107
+
108
+ def components_by_id(*ids)
109
+ root.components.values_at(*ids).select.with_index do |fld, i|
110
+ puts "Warning: field id #{ids[i]} points to missing field" if !fld
51
111
  fld && (!block_given? || yield(fld))
52
112
  end
53
113
  end