gooddata 0.6.24 → 0.6.25
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/.rubocop.yml +54 -0
- data/CHANGELOG.md +3 -0
- data/DEPENDENCIES.md +155 -154
- data/README.md +15 -6
- data/Rakefile +5 -3
- data/dependency_decisions.yml +2 -0
- data/gooddata.gemspec +2 -3
- data/lib/gooddata/cli/cli.rb +1 -3
- data/lib/gooddata/cli/commands/auth_cmd.rb +16 -7
- data/lib/gooddata/cli/commands/project_cmd.rb +16 -178
- data/lib/gooddata/cli/shared.rb +46 -44
- data/lib/gooddata/commands/auth.rb +4 -0
- data/lib/gooddata/commands/project.rb +7 -24
- data/lib/gooddata/exceptions/object_migration.rb +4 -0
- data/lib/gooddata/exceptions/segment_not_empty.rb +18 -0
- data/lib/gooddata/extensions/object.rb +12 -0
- data/lib/gooddata/goodzilla/goodzilla.rb +56 -9
- data/lib/gooddata/helpers/global_helpers.rb +92 -0
- data/lib/gooddata/mixins/md_finders.rb +2 -8
- data/lib/gooddata/mixins/md_grantees.rb +42 -0
- data/lib/gooddata/mixins/md_id_to_uri.rb +1 -8
- data/lib/gooddata/mixins/md_object_id.rb +1 -1
- data/lib/gooddata/mixins/md_object_indexer.rb +5 -8
- data/lib/gooddata/mixins/md_object_query.rb +2 -2
- data/lib/gooddata/mixins/not_group.rb +17 -0
- data/lib/gooddata/mixins/rest_getters.rb +2 -2
- data/lib/gooddata/mixins/rest_resource.rb +1 -0
- data/lib/gooddata/mixins/to_json.rb +11 -0
- data/lib/gooddata/mixins/uri_getter.rb +9 -0
- data/lib/gooddata/models/blueprint/anchor_field.rb +14 -0
- data/lib/gooddata/models/blueprint/project_blueprint.rb +15 -1
- data/lib/gooddata/models/blueprint/to_wire.rb +10 -0
- data/lib/gooddata/models/client.rb +178 -0
- data/lib/gooddata/models/client_synchronization_result.rb +31 -0
- data/lib/gooddata/models/client_synchronization_result_details.rb +41 -0
- data/lib/gooddata/models/datawarehouse.rb +1 -5
- data/lib/gooddata/models/domain.rb +85 -1
- data/lib/gooddata/models/execution.rb +0 -2
- data/lib/gooddata/models/execution_detail.rb +0 -2
- data/lib/gooddata/models/from_wire.rb +10 -0
- data/lib/gooddata/models/invitation.rb +1 -1
- data/lib/gooddata/models/links.rb +1 -1
- data/lib/gooddata/models/membership.rb +10 -6
- data/lib/gooddata/models/metadata.rb +98 -11
- data/lib/gooddata/models/metadata/attribute.rb +6 -7
- data/lib/gooddata/models/metadata/dashboard.rb +41 -75
- data/lib/gooddata/models/metadata/dashboard/dashboard_item.rb +20 -4
- data/lib/gooddata/models/metadata/dashboard/filter_apply_item.rb +37 -0
- data/lib/gooddata/models/metadata/dashboard/filter_item.rb +49 -0
- data/lib/gooddata/models/metadata/dashboard/geo_chart_item.rb +56 -0
- data/lib/gooddata/models/metadata/dashboard/headline_item.rb +56 -0
- data/lib/gooddata/models/metadata/dashboard/iframe_item.rb +46 -0
- data/lib/gooddata/models/metadata/dashboard/report_item.rb +49 -8
- data/lib/gooddata/models/metadata/dashboard/text_item.rb +55 -0
- data/lib/gooddata/models/metadata/dashboard_tab.rb +83 -30
- data/lib/gooddata/models/metadata/dataset.rb +0 -2
- data/lib/gooddata/models/metadata/dimension.rb +1 -3
- data/lib/gooddata/models/metadata/fact.rb +1 -3
- data/lib/gooddata/models/metadata/label.rb +1 -3
- data/lib/gooddata/models/metadata/metric.rb +11 -42
- data/lib/gooddata/models/metadata/report.rb +7 -18
- data/lib/gooddata/models/metadata/report_definition.rb +21 -113
- data/lib/gooddata/models/metadata/scheduled_mail.rb +274 -0
- data/lib/gooddata/models/metadata/scheduled_mail/dashboard_attachment.rb +62 -0
- data/lib/gooddata/models/metadata/scheduled_mail/report_attachment.rb +64 -0
- data/lib/gooddata/models/metadata/variable.rb +8 -2
- data/lib/gooddata/models/model.rb +2 -9
- data/lib/gooddata/models/process.rb +7 -29
- data/lib/gooddata/models/profile.rb +1 -1
- data/lib/gooddata/models/project.rb +131 -167
- data/lib/gooddata/models/project_creator.rb +2 -7
- data/lib/gooddata/models/project_metadata.rb +2 -10
- data/lib/gooddata/models/project_role.rb +4 -10
- data/lib/gooddata/models/report_data_result.rb +3 -5
- data/lib/gooddata/models/schedule.rb +4 -31
- data/lib/gooddata/models/segment.rb +192 -0
- data/lib/gooddata/models/user_filters/mandatory_user_filter.rb +2 -2
- data/lib/gooddata/models/user_filters/user_filter_builder.rb +1 -1
- data/lib/gooddata/models/user_filters/variable_user_filter.rb +11 -0
- data/lib/gooddata/models/user_group.rb +241 -0
- data/lib/gooddata/rest/connection.rb +81 -16
- data/lib/gooddata/rest/object.rb +29 -0
- data/lib/gooddata/rest/object_factory.rb +6 -1
- data/lib/gooddata/rest/resource.rb +7 -1
- data/lib/gooddata/version.rb +1 -1
- data/spec/environment/default.rb +19 -16
- data/spec/environment/develop.rb +10 -10
- data/spec/environment/hotfix.rb +6 -6
- data/spec/environment/production.rb +14 -14
- data/spec/environment/release.rb +6 -6
- data/spec/environment/staging.rb +9 -9
- data/spec/environment/staging_3.rb +14 -15
- data/spec/integration/blueprint_with_grain_spec.rb +72 -0
- data/spec/integration/clients_spec.rb +135 -0
- data/spec/integration/date_dim_switch_spec.rb +142 -0
- data/spec/integration/full_project_spec.rb +3 -3
- data/spec/integration/project_spec.rb +20 -0
- data/spec/integration/segments_spec.rb +141 -0
- data/spec/integration/user_group_spec.rb +127 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/unit/models/domain_spec.rb +7 -1
- data/spec/unit/models/metric_spec.rb +0 -8
- data/spec/unit/models/profile_spec.rb +1 -1
- data/spec/unit/models/report_result_data_spec.rb +6 -0
- metadata +38 -38
- data/lib/gooddata/cli/commands/api_cmd.rb +0 -34
- data/lib/gooddata/cli/commands/console_cmd.rb +0 -40
- data/lib/gooddata/cli/commands/domain_cmd.rb +0 -46
- data/lib/gooddata/cli/commands/process_cmd.rb +0 -145
- data/lib/gooddata/cli/commands/projects_cmd.rb +0 -23
- data/lib/gooddata/cli/commands/run_ruby_cmd.rb +0 -77
- data/lib/gooddata/cli/commands/scaffold_cmd.rb +0 -35
- data/lib/gooddata/cli/commands/user_cmd.rb +0 -24
|
@@ -74,6 +74,16 @@ module GoodData
|
|
|
74
74
|
a[:title] = attribute['title']
|
|
75
75
|
a[:description] = attribute['description']
|
|
76
76
|
a[:folder] = attribute['folder']
|
|
77
|
+
if attribute['grain']
|
|
78
|
+
a[:grain] = attribute['grain'].map do |g|
|
|
79
|
+
case g.keys.first.to_sym
|
|
80
|
+
when :dateDimension
|
|
81
|
+
{ date: g.values.first }
|
|
82
|
+
else
|
|
83
|
+
Helpers.symbolize_keys(g)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
77
87
|
end
|
|
78
88
|
[attribute] + pl + rl
|
|
79
89
|
end
|
|
@@ -13,7 +13,7 @@ require_relative 'project_role'
|
|
|
13
13
|
require_relative '../rest/object'
|
|
14
14
|
|
|
15
15
|
module GoodData
|
|
16
|
-
class Membership <
|
|
16
|
+
class Membership < Rest::Resource
|
|
17
17
|
attr_reader :json
|
|
18
18
|
|
|
19
19
|
ASSIGNABLE_MEMBERS = [
|
|
@@ -109,7 +109,7 @@ module GoodData
|
|
|
109
109
|
def contributor
|
|
110
110
|
url = @json['user']['meta']['contributor']
|
|
111
111
|
data = client.get url
|
|
112
|
-
client.
|
|
112
|
+
client.create(GoodData::Membership, data)
|
|
113
113
|
end
|
|
114
114
|
|
|
115
115
|
# Gets date when created
|
|
@@ -242,7 +242,7 @@ module GoodData
|
|
|
242
242
|
# Gets profile of this membership
|
|
243
243
|
def profile
|
|
244
244
|
raw = client.get @json['user']['links']['self']
|
|
245
|
-
client.
|
|
245
|
+
client.create(GoodData::Profile, raw)
|
|
246
246
|
end
|
|
247
247
|
|
|
248
248
|
# Gets URL of profile membership
|
|
@@ -253,7 +253,7 @@ module GoodData
|
|
|
253
253
|
# # Gets project which this membership relates to
|
|
254
254
|
# def project
|
|
255
255
|
# raw = client.get project_url
|
|
256
|
-
# client.
|
|
256
|
+
# client.create(GoodData::Project, raw)
|
|
257
257
|
# end
|
|
258
258
|
|
|
259
259
|
# Gets project id
|
|
@@ -274,7 +274,7 @@ module GoodData
|
|
|
274
274
|
tmp['projects'].map do |project_meta|
|
|
275
275
|
project_uri = project_meta['project']['links']['self']
|
|
276
276
|
project = client.get project_uri
|
|
277
|
-
client.
|
|
277
|
+
client.create(GoodData::Project, project)
|
|
278
278
|
end
|
|
279
279
|
end
|
|
280
280
|
|
|
@@ -294,7 +294,7 @@ module GoodData
|
|
|
294
294
|
tmp = client.get roles_link
|
|
295
295
|
tmp['associatedRoles']['roles'].pmap do |role_uri|
|
|
296
296
|
role = client.get role_uri
|
|
297
|
-
client.
|
|
297
|
+
client.create(GoodData::ProjectRole, role)
|
|
298
298
|
end
|
|
299
299
|
end
|
|
300
300
|
|
|
@@ -401,6 +401,10 @@ module GoodData
|
|
|
401
401
|
tmp
|
|
402
402
|
end
|
|
403
403
|
|
|
404
|
+
def user_groups
|
|
405
|
+
project.user_groups(:all, user: obj_id)
|
|
406
|
+
end
|
|
407
|
+
|
|
404
408
|
private
|
|
405
409
|
|
|
406
410
|
# Sets status to 'ENABLED' or 'DISABLED'
|
|
@@ -4,34 +4,102 @@
|
|
|
4
4
|
# This source code is licensed under the BSD-style license found in the
|
|
5
5
|
# LICENSE file in the root directory of this source tree.
|
|
6
6
|
|
|
7
|
+
require 'multi_json'
|
|
8
|
+
|
|
7
9
|
require_relative '../core/project'
|
|
8
10
|
|
|
9
11
|
require_relative '../mixins/mixins'
|
|
10
12
|
require_relative '../rest/object'
|
|
11
13
|
|
|
12
14
|
module GoodData
|
|
13
|
-
class MdObject <
|
|
15
|
+
class MdObject < Rest::Resource
|
|
14
16
|
MD_OBJ_CTG = 'obj'
|
|
15
17
|
IDENTIFIERS_CFG = 'instance-identifiers'
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
extend Mixin::MdIdToUri
|
|
20
|
+
extend Mixin::MdObjectIndexer
|
|
21
|
+
extend Mixin::MdObjectQuery
|
|
18
22
|
|
|
19
|
-
|
|
20
|
-
|
|
23
|
+
extend Mixin::MdFinders
|
|
24
|
+
extend Mixin::MdObjId
|
|
21
25
|
|
|
22
|
-
include
|
|
26
|
+
include Mixin::Links
|
|
27
|
+
include Mixin::ObjId
|
|
28
|
+
include Mixin::MdRelations
|
|
29
|
+
include Mixin::MdGrantees
|
|
23
30
|
|
|
24
31
|
class << self
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
32
|
+
# Method used for replacing objects like Attribute, Fact or Metric. It takes the object. Scans its JSON
|
|
33
|
+
# representation and returns a new one with object references changed according to mapping. The references an be found either in the object structure or in the MAQL in bracketed form. This implementation takes care only of those in bracketed form.
|
|
34
|
+
#
|
|
35
|
+
# @param obj [GoodData::MdObject] what Object that should be replaced
|
|
36
|
+
# @param mapping [Array[Array]] Array of mapping pairs.
|
|
37
|
+
# @return [GoodData::MdObject]
|
|
38
|
+
def replace_bracketed(obj, mapping)
|
|
39
|
+
replace(obj, mapping) { |e, a, b| e.gsub("[#{a}]", "[#{b}]") }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Method used for replacing objects like Attribute, Fact or Metric. It takes the object. Scans its JSON
|
|
43
|
+
# representation and returns a new one with object references changed according to mapping. The references an be found either in the object structure or in the MAQL in bracketed form. This implementation takes care only of those in object structure where they are as a string in JSON.
|
|
44
|
+
#
|
|
45
|
+
# @param obj [GoodData::MdObject] Object that should be replaced
|
|
46
|
+
# @param mapping [Array[Array]] Array of mapping pairs.
|
|
47
|
+
# @return [GoodData::MdObject]
|
|
48
|
+
def replace_quoted(obj, mapping)
|
|
49
|
+
replace(obj, mapping) do |e, a, b|
|
|
50
|
+
e.gsub("\"#{a}\"", "\"#{b}\"")
|
|
28
51
|
end
|
|
29
52
|
end
|
|
30
53
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
54
|
+
# Helper method used for replacing objects like Attribute, Fact or Metric. It takes the object. Scans its JSON
|
|
55
|
+
# representation yields for a client to perform replacement for each mapping pair and returns a new one
|
|
56
|
+
# with object of the same type as obj.
|
|
57
|
+
#
|
|
58
|
+
# @param obj [GoodData::MdObject] Object that should be replaced
|
|
59
|
+
# @param mapping [Array[Array]] Array of mapping pairs.
|
|
60
|
+
# @param block [Proc] Block that receives the object state as a JSON string and mapping pair and expects a new object state as a JSON string back
|
|
61
|
+
# @return [GoodData::MdObject]
|
|
62
|
+
def replace(obj, mapping, &block)
|
|
63
|
+
json = mapping.reduce(obj.to_json) do |a, e|
|
|
64
|
+
obj_a, obj_b = e
|
|
65
|
+
uri_what = obj_a.respond_to?(:uri) ? obj_a.uri : obj_a
|
|
66
|
+
uri_for_what = obj_b.respond_to?(:uri) ? obj_b.uri : obj_b
|
|
67
|
+
block.call(a, uri_what, uri_for_what)
|
|
68
|
+
end
|
|
69
|
+
client = obj.client
|
|
70
|
+
client.create(obj.class, MultiJson.load(json), :project => obj.project)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Helper method used for finding attribute elements that are interesting becuase they can be possibly
|
|
74
|
+
# replaced according to mapping specification. This walks through all the attribute elemets. Picks only those
|
|
75
|
+
# whose attribute is mentioned in the mapping. Walks through all the labels of that particular attribute and
|
|
76
|
+
# tries to find a value from one to be translated into a label in second. Obviously this is not guaranteed to
|
|
77
|
+
# find any results or in some cases can yield to incorrect results.
|
|
78
|
+
#
|
|
79
|
+
# @param obj [GoodData::MdObject] Object that should be replaced
|
|
80
|
+
# @param mapping [Array[Array]] Array of mapping pairs.
|
|
81
|
+
# @param block [Proc] Block that receives the object state as a JSON string and mapping pair and expects a new object state as a JSON string back
|
|
82
|
+
# @return [GoodData::MdObject]
|
|
83
|
+
def find_replaceable_values(obj, mapping)
|
|
84
|
+
values_to_replace = GoodData::SmallGoodZilla.extract_element_uri_pairs(MultiJson.dump(obj.to_json))
|
|
85
|
+
values_from_mapping = values_to_replace.select { |i| mapping.map { |a, _| a.uri }.include?(i.first) }
|
|
86
|
+
replaceable_vals = values_from_mapping.map do |a_uri, id|
|
|
87
|
+
from_attribute, to_attribute = mapping.find { |k, _| k.uri == a_uri }
|
|
88
|
+
vals = from_attribute.values_for(id)
|
|
89
|
+
labels = to_attribute.labels
|
|
90
|
+
results = labels.to_enum.mapcat do |l|
|
|
91
|
+
vals.map do |v|
|
|
92
|
+
begin
|
|
93
|
+
l.find_value_uri(v)
|
|
94
|
+
rescue
|
|
95
|
+
nil
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
fail "Unable to find replacement for #{a_uri}" if results.compact.empty?
|
|
100
|
+
[a_uri, id, results.compact.first]
|
|
34
101
|
end
|
|
102
|
+
replaceable_vals.map { |a, id, r| ["#{a}/elements?id=#{id}", r] }
|
|
35
103
|
end
|
|
36
104
|
end
|
|
37
105
|
|
|
@@ -88,6 +156,25 @@ module GoodData
|
|
|
88
156
|
@project ||= Project[uri.gsub(%r{\/obj\/\d+$}, ''), :client => client]
|
|
89
157
|
end
|
|
90
158
|
|
|
159
|
+
# Method used for replacing objects like Attribute, Fact or Metric. Returns new object of the same type.
|
|
160
|
+
#
|
|
161
|
+
# @param [GoodData::MdObject] what Object that should be replaced
|
|
162
|
+
# @param [GoodData::MdObject] for_what Object it is replaced with
|
|
163
|
+
# @return [GoodData::Metric]
|
|
164
|
+
def replace(mapping)
|
|
165
|
+
GoodData::MdObject.replace_quoted(self, mapping)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# Method used for replacing objects like Attribute, Fact or Metric. Returns itself mutated.
|
|
169
|
+
# @param [GoodData::MdObject] what Object that should be replaced
|
|
170
|
+
# @param [GoodData::MdObject] for_what Object it is replaced with
|
|
171
|
+
# @return [GoodData::Metric]
|
|
172
|
+
def replace!(mapping)
|
|
173
|
+
x = replace(mapping)
|
|
174
|
+
@json = x.json
|
|
175
|
+
self
|
|
176
|
+
end
|
|
177
|
+
|
|
91
178
|
def remove_tag(a_tag)
|
|
92
179
|
self.tags = tag_set.delete(a_tag).to_a.join(' ')
|
|
93
180
|
self
|
|
@@ -12,9 +12,7 @@ require_relative '../../mixins/is_attribute'
|
|
|
12
12
|
|
|
13
13
|
module GoodData
|
|
14
14
|
class Attribute < MdObject
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
include GoodData::Mixin::IsAttribute
|
|
15
|
+
include Mixin::IsAttribute
|
|
18
16
|
|
|
19
17
|
ATTRIBUTE_BASE_AGGREGATIONS = [:count]
|
|
20
18
|
|
|
@@ -32,16 +30,17 @@ module GoodData
|
|
|
32
30
|
#
|
|
33
31
|
# @param uri [String] Uri of the element. in the form of /gdc/md/PID/obj/OBJ_ID/elements?id=21
|
|
34
32
|
# @return [String] Textual representation of a particular attribute element
|
|
35
|
-
def find_element_value(
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
def find_element_value(stuff, opts = { :project => GoodData.project })
|
|
34
|
+
stuff.scan(%r{([^\[\]]*)\/elements\?id=(\d+)}).pmap do |a, id|
|
|
35
|
+
opts[:project].attributes(a).primary_label.find_element_value(id.to_i)
|
|
36
|
+
end.first
|
|
38
37
|
end
|
|
39
38
|
end
|
|
40
39
|
|
|
41
40
|
# Returns the labels of an attribute
|
|
42
41
|
# @return [Array<GoodData::Label>]
|
|
43
42
|
def display_forms
|
|
44
|
-
content['displayForms'].
|
|
43
|
+
content['displayForms'].pmap { |df| project.labels(df['meta']['uri']) }
|
|
45
44
|
end
|
|
46
45
|
alias_method :labels, :display_forms
|
|
47
46
|
|
|
@@ -9,6 +9,7 @@ require_relative 'dashboard/filter_item'
|
|
|
9
9
|
require_relative 'dashboard/report_item'
|
|
10
10
|
|
|
11
11
|
require_relative '../../core/core'
|
|
12
|
+
require_relative '../../helpers/global_helpers'
|
|
12
13
|
require_relative '../metadata'
|
|
13
14
|
require_relative 'metadata'
|
|
14
15
|
require_relative 'report'
|
|
@@ -17,9 +18,29 @@ require 'multi_json'
|
|
|
17
18
|
|
|
18
19
|
module GoodData
|
|
19
20
|
class Dashboard < GoodData::MdObject
|
|
20
|
-
|
|
21
|
+
include Mixin::Lockable
|
|
22
|
+
|
|
23
|
+
EMPTY_OBJECT = {
|
|
24
|
+
'projectDashboard' => {
|
|
25
|
+
'content' => {
|
|
26
|
+
'tabs' => [],
|
|
27
|
+
'filters' => []
|
|
28
|
+
},
|
|
29
|
+
'meta' => {
|
|
30
|
+
'tags' => '',
|
|
31
|
+
'summary' => '',
|
|
32
|
+
'title' => ''
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
21
36
|
|
|
22
|
-
|
|
37
|
+
ASSIGNABLE_MEMBERS = [
|
|
38
|
+
:filters,
|
|
39
|
+
:tabs,
|
|
40
|
+
:tags,
|
|
41
|
+
:summary,
|
|
42
|
+
:title
|
|
43
|
+
]
|
|
23
44
|
|
|
24
45
|
class << self
|
|
25
46
|
# Method intended to get all objects of that type in a specified project
|
|
@@ -31,84 +52,19 @@ module GoodData
|
|
|
31
52
|
query('projectDashboard', Dashboard, options)
|
|
32
53
|
end
|
|
33
54
|
|
|
34
|
-
def
|
|
35
|
-
|
|
36
|
-
{
|
|
37
|
-
:title => title,
|
|
38
|
-
:items => tab[:items].map { |i| GoodData::Dashboard.create_report_tab_item(i, options) }
|
|
39
|
-
}
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def create_report_tab_item(item, options = { :client => GoodData.client, :project => GoodData.project })
|
|
43
|
-
title = item[:title]
|
|
44
|
-
|
|
45
|
-
report = GoodData::Report.find_first_by_title(title, options)
|
|
46
|
-
{
|
|
47
|
-
:reportItem => {
|
|
48
|
-
:obj => report.uri,
|
|
49
|
-
:sizeY => item[:size_y] || 200,
|
|
50
|
-
:sizeX => item[:size_x] || 300,
|
|
51
|
-
:style => {
|
|
52
|
-
:displayTitle => 1,
|
|
53
|
-
:background => {
|
|
54
|
-
:opacity => 0
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
:visualization => {
|
|
58
|
-
:grid => {
|
|
59
|
-
:columnWidths => []
|
|
60
|
-
},
|
|
61
|
-
:oneNumber => {
|
|
62
|
-
:labels => {}
|
|
63
|
-
}
|
|
64
|
-
},
|
|
65
|
-
:positionY => item[:position_y] || 0,
|
|
66
|
-
:filters => [],
|
|
67
|
-
:positionX => item[:position_x] || 0
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def create(dashboard = { :tabs => [] }, options = { :client => GoodData.client, :project => GoodData.project })
|
|
73
|
-
client = options[:client]
|
|
74
|
-
fail ArgumentError, 'No :client specified' if client.nil?
|
|
75
|
-
|
|
76
|
-
p = options[:project]
|
|
77
|
-
fail ArgumentError, 'No :project specified' if p.nil?
|
|
78
|
-
|
|
79
|
-
project = GoodData::Project[p, options]
|
|
80
|
-
fail ArgumentError, 'Wrong :project specified' if project.nil?
|
|
81
|
-
|
|
82
|
-
tabs = dashboard[:tabs] || []
|
|
83
|
-
|
|
84
|
-
stuff = {
|
|
85
|
-
'projectDashboard' => {
|
|
86
|
-
'content' => {
|
|
87
|
-
'tabs' => tabs.map { |t| GoodData::Dashboard.create_report_tab(t, options) },
|
|
88
|
-
'filters' => []
|
|
89
|
-
},
|
|
90
|
-
'meta' => {
|
|
91
|
-
'tags' => dashboard[:tags],
|
|
92
|
-
'summary' => dashboard[:summary],
|
|
93
|
-
'title' => dashboard[:title]
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
55
|
+
def create(dashboard = {}, options = { :client => GoodData.client, :project => GoodData.project })
|
|
56
|
+
client, project = GoodData.get_client_and_project(options)
|
|
97
57
|
|
|
98
|
-
client.create(Dashboard,
|
|
58
|
+
res = client.create(Dashboard, GoodData::Helpers.deep_dup(GoodData::Helpers.deep_stringify_keys(EMPTY_OBJECT)), :project => project)
|
|
59
|
+
dashboard.each do |k, v|
|
|
60
|
+
res.send("#{k}=", v) if ASSIGNABLE_MEMBERS.include? k
|
|
61
|
+
end
|
|
62
|
+
res
|
|
99
63
|
end
|
|
100
64
|
end
|
|
101
65
|
|
|
102
66
|
def add_tab(tab)
|
|
103
|
-
|
|
104
|
-
items = tab[:items] || []
|
|
105
|
-
|
|
106
|
-
new_tab_json = {
|
|
107
|
-
:title => title,
|
|
108
|
-
:items => items.map { |i| GoodData::Dashboard.create_report_tab_item(i, options) }
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
new_tab = GoodData::DashboardTab.new(self, GoodData::Helpers.deep_stringify_keys(new_tab_json))
|
|
67
|
+
new_tab = GoodData::DashboardTab.create(self, tab)
|
|
112
68
|
content['tabs'] << new_tab.json
|
|
113
69
|
new_tab
|
|
114
70
|
end
|
|
@@ -129,6 +85,16 @@ module GoodData
|
|
|
129
85
|
client.poll_on_code(x['asyncTask']['link']['poll'], options.merge(process: false))
|
|
130
86
|
end
|
|
131
87
|
|
|
88
|
+
# Method used for replacing values in their state according to mapping. Can be used to replace any values but it is typically used to replace the URIs. Returns a new object of the same type.
|
|
89
|
+
#
|
|
90
|
+
# @param [Array<Array>]Mapping specifying what should be exchanged for what. As mapping should be used output of GoodData::Helpers.prepare_mapping.
|
|
91
|
+
# @return [GoodData::Dashboard]
|
|
92
|
+
def replace(mapping)
|
|
93
|
+
x = GoodData::MdObject.replace_quoted(self, mapping)
|
|
94
|
+
vals = GoodData::MdObject.find_replaceable_values(self, mapping)
|
|
95
|
+
GoodData::MdObject.replace_quoted(x, vals)
|
|
96
|
+
end
|
|
97
|
+
|
|
132
98
|
def tabs
|
|
133
99
|
content['tabs'].map do |tab|
|
|
134
100
|
GoodData::DashboardTab.new(self, tab)
|
|
@@ -4,19 +4,35 @@
|
|
|
4
4
|
# This source code is licensed under the BSD-style license found in the
|
|
5
5
|
# LICENSE file in the root directory of this source tree.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
class DashboardItem
|
|
9
|
-
include GoodData::Mixin::RootKeyGetter
|
|
10
|
-
include GoodData::Mixin::DataGetter
|
|
7
|
+
require_relative '../../../rest/resource'
|
|
11
8
|
|
|
9
|
+
module GoodData
|
|
10
|
+
class DashboardItem < Rest::Resource
|
|
12
11
|
attr_reader :tab
|
|
13
12
|
attr_accessor :json
|
|
14
13
|
|
|
14
|
+
ASSIGNABLE_MEMBERS = [
|
|
15
|
+
:pos_x,
|
|
16
|
+
:pos_y,
|
|
17
|
+
:position_x,
|
|
18
|
+
:position_y,
|
|
19
|
+
:size_x,
|
|
20
|
+
:size_y
|
|
21
|
+
]
|
|
22
|
+
|
|
15
23
|
def initialize(tab, json)
|
|
16
24
|
@tab = tab
|
|
17
25
|
@json = json
|
|
18
26
|
end
|
|
19
27
|
|
|
28
|
+
def filters
|
|
29
|
+
data['filters']
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def filters=(new_filters)
|
|
33
|
+
data['filters'] = new_filters
|
|
34
|
+
end
|
|
35
|
+
|
|
20
36
|
def position_x
|
|
21
37
|
data['positionX']
|
|
22
38
|
end
|