yui_rest_client 0.5.0
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 +7 -0
- data/.github/workflows/publish.yml +33 -0
- data/.github/workflows/test.yml +26 -0
- data/.gitignore +15 -0
- data/.rspec +3 -0
- data/.rubocop.yml +41 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +21 -0
- data/README.md +216 -0
- data/Rakefile +20 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/lib/yui_rest_client.rb +42 -0
- data/lib/yui_rest_client/actions.rb +12 -0
- data/lib/yui_rest_client/app.rb +230 -0
- data/lib/yui_rest_client/error.rb +13 -0
- data/lib/yui_rest_client/filter_extractor.rb +28 -0
- data/lib/yui_rest_client/http/http_client.rb +36 -0
- data/lib/yui_rest_client/http/response.rb +21 -0
- data/lib/yui_rest_client/http/version_controller.rb +26 -0
- data/lib/yui_rest_client/http/widget_controller.rb +54 -0
- data/lib/yui_rest_client/local_process.rb +73 -0
- data/lib/yui_rest_client/logger.rb +32 -0
- data/lib/yui_rest_client/timer.rb +20 -0
- data/lib/yui_rest_client/version.rb +6 -0
- data/lib/yui_rest_client/wait.rb +21 -0
- data/lib/yui_rest_client/waitable.rb +39 -0
- data/lib/yui_rest_client/widgets.rb +30 -0
- data/lib/yui_rest_client/widgets/bargraph.rb +62 -0
- data/lib/yui_rest_client/widgets/base.rb +114 -0
- data/lib/yui_rest_client/widgets/button.rb +33 -0
- data/lib/yui_rest_client/widgets/checkbox.rb +53 -0
- data/lib/yui_rest_client/widgets/combobox.rb +95 -0
- data/lib/yui_rest_client/widgets/datefield.rb +47 -0
- data/lib/yui_rest_client/widgets/label.rb +41 -0
- data/lib/yui_rest_client/widgets/menubutton.rb +48 -0
- data/lib/yui_rest_client/widgets/multilinebox.rb +84 -0
- data/lib/yui_rest_client/widgets/numberbox.rb +76 -0
- data/lib/yui_rest_client/widgets/progressbar.rb +45 -0
- data/lib/yui_rest_client/widgets/radiobutton.rb +35 -0
- data/lib/yui_rest_client/widgets/richtext.rb +36 -0
- data/lib/yui_rest_client/widgets/selectionbox.rb +87 -0
- data/lib/yui_rest_client/widgets/tab.rb +81 -0
- data/lib/yui_rest_client/widgets/table.rb +154 -0
- data/lib/yui_rest_client/widgets/textbox.rb +94 -0
- data/lib/yui_rest_client/widgets/timefield.rb +45 -0
- data/lib/yui_rest_client/widgets/tree.rb +149 -0
- data/yui_rest_client.gemspec +38 -0
- metadata +222 -0
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module YuiRestClient
|
4
|
+
module Widgets
|
5
|
+
# Class representing a tab in the UI. It can be YDumbTab.
|
6
|
+
class Tab < Widgets::Base
|
7
|
+
# Returns the list of items available to select from tab.
|
8
|
+
# @return [Array] array of String objects.
|
9
|
+
# @example Get items from tab with id "test_id"
|
10
|
+
# {
|
11
|
+
# "class": "YDumbTab",
|
12
|
+
# "debug_label": "YDumbTab [tab1] [tab2] [tab3]",
|
13
|
+
# "hstretch": true,
|
14
|
+
# "icon_base_path": "",
|
15
|
+
# "id": "test_id",
|
16
|
+
# "items": [
|
17
|
+
# {
|
18
|
+
# "label": "tab1"
|
19
|
+
# },
|
20
|
+
# {
|
21
|
+
# "label": "tab2",
|
22
|
+
# "selected": true
|
23
|
+
# },
|
24
|
+
# {
|
25
|
+
# "label": "tab3"
|
26
|
+
# }
|
27
|
+
# ],
|
28
|
+
# "items_count": 3,
|
29
|
+
# "vstretch": true
|
30
|
+
# }
|
31
|
+
# @example
|
32
|
+
# app.tab(id: 'test').items
|
33
|
+
# # tab1
|
34
|
+
# # tab2
|
35
|
+
# # tab3
|
36
|
+
def items
|
37
|
+
property(:items).map { |x| x[:label] }
|
38
|
+
end
|
39
|
+
|
40
|
+
# Sends action to click the tab in UI.
|
41
|
+
# @param item [String] value to select from items.
|
42
|
+
# @return [Tab] in case action is successful
|
43
|
+
# @example Click tab with id 'test'
|
44
|
+
# app.button(id: 'test', value: test_item).select
|
45
|
+
def select(item)
|
46
|
+
action(action: Actions::SELECT, value: item)
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns the label of the selected tab.
|
51
|
+
# @return [String] label of the tab selected
|
52
|
+
# @example Get items from tab with id "test_id"
|
53
|
+
# {
|
54
|
+
# "class": "YDumbTab",
|
55
|
+
# "debug_label": "YDumbTab [tab1] [tab2] [tab3]",
|
56
|
+
# "hstretch": true,
|
57
|
+
# "icon_base_path": "",
|
58
|
+
# "id": "test_id",
|
59
|
+
# "items": [
|
60
|
+
# {
|
61
|
+
# "label": "tab1"
|
62
|
+
# },
|
63
|
+
# {
|
64
|
+
# "label": "tab2",
|
65
|
+
# "selected": true
|
66
|
+
# },
|
67
|
+
# {
|
68
|
+
# "label": "tab3"
|
69
|
+
# }
|
70
|
+
# ],
|
71
|
+
# "items_count": 3,
|
72
|
+
# "vstretch": true
|
73
|
+
# }
|
74
|
+
# @example
|
75
|
+
# app.tab(id: 'test').selected_item # tab2
|
76
|
+
def selected_item
|
77
|
+
property(:items).select { |x| x[:selected] }.first[:label]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module YuiRestClient
|
4
|
+
module Widgets
|
5
|
+
# Class representing a table in the UI. It can be YTable
|
6
|
+
class Table < Widgets::Base
|
7
|
+
# Returns whether the table contains any row or not
|
8
|
+
# @return [Boolean] true if table is empty, otherwise false
|
9
|
+
# @example Check if table with id "test_id" is empty
|
10
|
+
# {
|
11
|
+
# "class": "YTable",
|
12
|
+
# "columns": 4,
|
13
|
+
# "header": [
|
14
|
+
# "header1",
|
15
|
+
# "header2",
|
16
|
+
# "header3",
|
17
|
+
# "header4"
|
18
|
+
# ],
|
19
|
+
# "id": "test_id",
|
20
|
+
# "items": null,
|
21
|
+
# "items_count": 0
|
22
|
+
# }
|
23
|
+
# @example
|
24
|
+
# app.table(id: 'test_id').empty?
|
25
|
+
def empty?
|
26
|
+
property(:items).nil?
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns the list of items available to select from the table.
|
30
|
+
# @return [Array] array of [Array] objects containing values for each column
|
31
|
+
# @example Get items from the table with id "test_id"
|
32
|
+
# {
|
33
|
+
# "class": "YTable",
|
34
|
+
# "columns": 4,
|
35
|
+
# "header": [
|
36
|
+
# "header1",
|
37
|
+
# "header2",
|
38
|
+
# "header3",
|
39
|
+
# "header4"
|
40
|
+
# ],
|
41
|
+
# "id": "test_id",
|
42
|
+
# "items": [
|
43
|
+
# {
|
44
|
+
# "labels": [
|
45
|
+
# "test.item.1",
|
46
|
+
# "",
|
47
|
+
# "",
|
48
|
+
# ""
|
49
|
+
# ],
|
50
|
+
# "selected": true
|
51
|
+
# },
|
52
|
+
# {
|
53
|
+
# "labels": [
|
54
|
+
# "test.item.2",
|
55
|
+
# "",
|
56
|
+
# "",
|
57
|
+
# ""
|
58
|
+
# ]
|
59
|
+
# }
|
60
|
+
# ],
|
61
|
+
# "items_count": 2
|
62
|
+
# }
|
63
|
+
# @example
|
64
|
+
# app.table(id: 'test_id').items
|
65
|
+
# # [test.item.1, "", "", ""]
|
66
|
+
# # [test.item.2, "", "", ""]
|
67
|
+
def items
|
68
|
+
property(:items).map { |x| x[:labels] }
|
69
|
+
end
|
70
|
+
|
71
|
+
# Returns the list of column names.
|
72
|
+
# @return [Array] array of [String] objects containing names of the columns
|
73
|
+
# @example Get header column names from the table with id "test_id"
|
74
|
+
# app.table(id: 'test_id').header
|
75
|
+
def header
|
76
|
+
property(:header)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Sends action to select a row in a table. Row can be selected either by
|
80
|
+
# cell value in the column (first column will be used by default), or by
|
81
|
+
# row number directly. If both are provided, value will be used.
|
82
|
+
# NOTE: row number corresponds to the position of the
|
83
|
+
# item in the list of column values which might differ to the display order.
|
84
|
+
# @param value [String] value to select in the table.
|
85
|
+
# @param column [String] column name where value is present
|
86
|
+
# @param row [Numeric] row number to select in the table.
|
87
|
+
# @return [Table] in case action is successful
|
88
|
+
# @example Select row with value "test.item.2" for column "header1" in table with id 'test_id'
|
89
|
+
# app.table(id: 'test_id').select(value: 'test.item.2', column: 'header1')
|
90
|
+
# @example Select row number 3 in table with id 'test_id'
|
91
|
+
# app.table(id: 'test_id').select(row: 3)
|
92
|
+
def select(value: nil, column: nil, row: nil)
|
93
|
+
params = { action: Actions::SELECT }
|
94
|
+
if !value.nil?
|
95
|
+
params.merge!(value: value)
|
96
|
+
params.merge!(column: get_index(column)) unless column.nil?
|
97
|
+
elsif !row.nil?
|
98
|
+
params.merge!(row: row)
|
99
|
+
end
|
100
|
+
action(params)
|
101
|
+
self
|
102
|
+
end
|
103
|
+
|
104
|
+
# Returns the list of items currently selected from the table.
|
105
|
+
# @return [Array] array of [Array] objects containing values for each column
|
106
|
+
# @example Get items from the table with id "test_id"
|
107
|
+
# {
|
108
|
+
# "class": "YTable",
|
109
|
+
# "columns": 4,
|
110
|
+
# "header": [
|
111
|
+
# "header1",
|
112
|
+
# "header2",
|
113
|
+
# "header3",
|
114
|
+
# "header4"
|
115
|
+
# ],
|
116
|
+
# "id": "test_id",
|
117
|
+
# "items": [
|
118
|
+
# {
|
119
|
+
# "labels": [
|
120
|
+
# "test.item.1",
|
121
|
+
# "",
|
122
|
+
# "",
|
123
|
+
# ""
|
124
|
+
# ],
|
125
|
+
# "selected": true
|
126
|
+
# },
|
127
|
+
# {
|
128
|
+
# "labels": [
|
129
|
+
# "test.item.2",
|
130
|
+
# "",
|
131
|
+
# "",
|
132
|
+
# ""
|
133
|
+
# ],
|
134
|
+
# "selected": true
|
135
|
+
# }
|
136
|
+
# ],
|
137
|
+
# "items_count": 2
|
138
|
+
# }
|
139
|
+
# @example
|
140
|
+
# app.table(id: 'test_id').selected_items
|
141
|
+
# # [test.item.1, "", "", ""]
|
142
|
+
# # [test.item.2, "", "", ""]
|
143
|
+
def selected_items
|
144
|
+
property(:items).map { |x| x[:labels] if x[:selected] }.compact
|
145
|
+
end
|
146
|
+
|
147
|
+
private
|
148
|
+
|
149
|
+
def get_index(column)
|
150
|
+
header.index(column)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module YuiRestClient
|
4
|
+
module Widgets
|
5
|
+
# Class representing a textbox in the UI. It can be YInputField.
|
6
|
+
class Textbox < Widgets::Base
|
7
|
+
# Returns maximum string length to set in the textbox
|
8
|
+
# @return [Integer] maximum number of character to set in the textbox
|
9
|
+
# @example Check maximum string length in textbox with id 'test'
|
10
|
+
# {
|
11
|
+
# "class": "YInputField",
|
12
|
+
# "debug_label": "label_test",
|
13
|
+
# "hstretch": true,
|
14
|
+
# "id": "test",
|
15
|
+
# "input_max_length": 256,
|
16
|
+
# "label": "label_test",
|
17
|
+
# "password_mode": false,
|
18
|
+
# "valid_chars": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.",
|
19
|
+
# "value": ""
|
20
|
+
# }
|
21
|
+
# @example
|
22
|
+
# app.textbox(id: 'test').max_length
|
23
|
+
def max_length
|
24
|
+
property(:input_max_length)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Sends action to set the value of textbox.
|
28
|
+
# @param value [String] text to be set in textbox
|
29
|
+
# @return [Textbox] in case action is successful
|
30
|
+
# @example Set text in textbox with id 'test' to 'my value'
|
31
|
+
# app.textbox(id: 'test').set('my value')
|
32
|
+
def set(value)
|
33
|
+
action(action: Actions::ENTER_TEXT, value: value)
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
# Check if textbox has password mode
|
38
|
+
# @return [Boolean] true if has password mode, otherwise false
|
39
|
+
# @example Check password mode in textbox with id 'test'
|
40
|
+
# {
|
41
|
+
# "class": "YInputField",
|
42
|
+
# "debug_label": "label_test",
|
43
|
+
# "hstretch": true,
|
44
|
+
# "id": "test",
|
45
|
+
# "label": "label_test",
|
46
|
+
# "password_mode": false,
|
47
|
+
# "value": ""
|
48
|
+
# }
|
49
|
+
# @example
|
50
|
+
# app.textbox(id: 'test').password?
|
51
|
+
def password?
|
52
|
+
property(:password_mode)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns valid chars to set in the textbox
|
56
|
+
# @return [String] containing all valid chars
|
57
|
+
# @example Check password mode in textbox with id 'test'
|
58
|
+
# {
|
59
|
+
# "class": "YInputField",
|
60
|
+
# "debug_label": "label_test",
|
61
|
+
# "hstretch": true,
|
62
|
+
# "id": "test",
|
63
|
+
# "label": "label_test",
|
64
|
+
# "password_mode": false,
|
65
|
+
# "valid_chars": "0123456789",
|
66
|
+
# "value": ""
|
67
|
+
# }
|
68
|
+
# @example
|
69
|
+
# app.textbox(id: 'test').valid_chars
|
70
|
+
def valid_chars
|
71
|
+
property(:valid_chars)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Returns text that is currently set for textbox.
|
75
|
+
# Gets value from 'value' parameter in JSON representation of YInputField.
|
76
|
+
# @return [String] value
|
77
|
+
# @example Get value from textbox with id "address"
|
78
|
+
# {
|
79
|
+
# "class": "YInputField",
|
80
|
+
# "debug_label": "Address",
|
81
|
+
# "hstretch": true,
|
82
|
+
# "id": "address",
|
83
|
+
# "label": "A&ddress",
|
84
|
+
# "password_mode": false,
|
85
|
+
# "value": "Test Address"
|
86
|
+
# }
|
87
|
+
# @example
|
88
|
+
# app.textbox(id: 'address').value # Test Address
|
89
|
+
def value
|
90
|
+
property(:value)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module YuiRestClient
|
4
|
+
module Widgets
|
5
|
+
# Class representing a DateField in the UI, namely YTimeField.
|
6
|
+
class Timefield < Widgets::Base
|
7
|
+
# Sends action to set the value of time field. Accepts Time or DateTime
|
8
|
+
# object and sets value in ISO 8601 format HH:MM:SS.
|
9
|
+
# @param time [Time] time to be set in the time field
|
10
|
+
# @return [Timefield] in case action is successful
|
11
|
+
# @raise YuiRestClientError if parameter is not DateTime or Time
|
12
|
+
# @example Set current time in the time field with id 'test' using Time
|
13
|
+
# app.timefield(id: 'time').set(Time.now)
|
14
|
+
# @example Set custom time in the field with id 'test' to 04:05:06
|
15
|
+
# app.timefield(id: 'time').set(DateTime.new(2001,2,3,4,5,6))
|
16
|
+
def set(time)
|
17
|
+
unless [DateTime, Time].any? { |c| time.is_a? c }
|
18
|
+
raise Error::YuiRestClientError, 'Parameter is not Date, Time or DateTime'
|
19
|
+
end
|
20
|
+
|
21
|
+
action(action: Actions::ENTER_TEXT, value: time.strftime('%T'))
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns text that is currently set for timefield.
|
26
|
+
# Gets value from 'value' parameter in JSON representation of YTimeField.
|
27
|
+
# @return [String] value
|
28
|
+
# @example Get value from timefield with id "time"
|
29
|
+
# {
|
30
|
+
# "class" : "YTimeField",
|
31
|
+
# "debug_label" : "Time:",
|
32
|
+
# "hstretch" : true,
|
33
|
+
# "id" : "time",
|
34
|
+
# "label" : "&Time:",
|
35
|
+
# "notify" : true,
|
36
|
+
# "value" : "20:15:00"
|
37
|
+
# }
|
38
|
+
# @example
|
39
|
+
# app.timefield(id: 'time').value # '20:15:00'
|
40
|
+
def value
|
41
|
+
property(:value)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module YuiRestClient
|
4
|
+
module Widgets
|
5
|
+
# Class representing a tree in UI. It can be YTree.
|
6
|
+
class Tree < Widgets::Base
|
7
|
+
# Returns the list of items available to select from tree. Each item
|
8
|
+
# is represented by its path from root node to leaf in the tree,
|
9
|
+
# in other words, a list of nodes separated by special simbol '|'
|
10
|
+
# @return [Array<String>] array of strings
|
11
|
+
# @example Get items from tree with id "test_id"
|
12
|
+
# {
|
13
|
+
# "class": "YTree",
|
14
|
+
# "debug_label": "node_0",
|
15
|
+
# "hstretch": true,
|
16
|
+
# "hweight": 30,
|
17
|
+
# "icon_base_path": "",
|
18
|
+
# "id": "test_id",
|
19
|
+
# "items": [
|
20
|
+
# {
|
21
|
+
# "children": [
|
22
|
+
# {
|
23
|
+
# "icon_name": "icon",
|
24
|
+
# "label": "node1_1"
|
25
|
+
# },
|
26
|
+
# {
|
27
|
+
# "children": [
|
28
|
+
# {
|
29
|
+
# "label": "node1_2_1"
|
30
|
+
# },
|
31
|
+
# {
|
32
|
+
# "label": "node1_2_2",
|
33
|
+
# "selected": true
|
34
|
+
# }
|
35
|
+
# ],
|
36
|
+
# "icon_name": "icon",
|
37
|
+
# "label": "node1_2"
|
38
|
+
# }
|
39
|
+
# ],
|
40
|
+
# "icon_name": "icon",
|
41
|
+
# "label": "node1",
|
42
|
+
# },
|
43
|
+
# {
|
44
|
+
# "icon_name": "icon",
|
45
|
+
# "label": "node2"
|
46
|
+
# }
|
47
|
+
# ],
|
48
|
+
# "items_count": 2,
|
49
|
+
# "label": "node_0",
|
50
|
+
# "notify": true,
|
51
|
+
# "vstretch": true
|
52
|
+
# }
|
53
|
+
# @example
|
54
|
+
# app.tree(id: 'test_id').items
|
55
|
+
# # node1
|
56
|
+
# # node1|node1_1
|
57
|
+
# # node1|node1_2
|
58
|
+
# # node1|node1_2|node1_2_1
|
59
|
+
# # node1|node1_2|node1_2_2
|
60
|
+
# # node2
|
61
|
+
def items
|
62
|
+
get_nodes(property(:items))
|
63
|
+
end
|
64
|
+
|
65
|
+
# Sends action to select an item from the tree in UI.
|
66
|
+
# @param item [String] value to select from items.
|
67
|
+
# @example Select tree node 'test_node' from tree with id 'test_id'
|
68
|
+
# app.tree(id: 'test_id').select('test_node')
|
69
|
+
def select(item)
|
70
|
+
action(action: Actions::SELECT, value: item)
|
71
|
+
self
|
72
|
+
end
|
73
|
+
|
74
|
+
# Returns the item currently selected/highlighted in the tree. Item
|
75
|
+
# is represented by its path from root node to leaf in the tree,
|
76
|
+
# in other words, a list of nodes separated by special simbol '|'
|
77
|
+
# @return [String] item selected/highlighted in the tree
|
78
|
+
# @example Get selected item from tree with id "test_id"
|
79
|
+
# {
|
80
|
+
# "class": "YTree",
|
81
|
+
# "debug_label": "node_0",
|
82
|
+
# "hstretch": true,
|
83
|
+
# "hweight": 30,
|
84
|
+
# "icon_base_path": "",
|
85
|
+
# "id": "test_id",
|
86
|
+
# "items": [
|
87
|
+
# {
|
88
|
+
# "children": [
|
89
|
+
# {
|
90
|
+
# "icon_name": "icon",
|
91
|
+
# "label": "node1_1"
|
92
|
+
# },
|
93
|
+
# {
|
94
|
+
# "children": [
|
95
|
+
# {
|
96
|
+
# "label": "node_1_2_1"
|
97
|
+
# },
|
98
|
+
# {
|
99
|
+
# "label": "node_1_2_2",
|
100
|
+
# "selected": true
|
101
|
+
# }
|
102
|
+
# ],
|
103
|
+
# "icon_name": "icon",
|
104
|
+
# "label": "node1_2"
|
105
|
+
# }
|
106
|
+
# ],
|
107
|
+
# "icon_name": "icon",
|
108
|
+
# "label": "node1",
|
109
|
+
# },
|
110
|
+
# {
|
111
|
+
# "icon_name": "icon",
|
112
|
+
# "label": "node2"
|
113
|
+
# }
|
114
|
+
# ],
|
115
|
+
# "items_count": 2,
|
116
|
+
# "label": "node_0",
|
117
|
+
# "notify": true,
|
118
|
+
# "vstretch": true
|
119
|
+
# }
|
120
|
+
# @example
|
121
|
+
# app.tree(id: 'test_id').selected_item
|
122
|
+
# # node1|node1_2|node1_2_2
|
123
|
+
def selected_item
|
124
|
+
get_selected_node(property(:items))
|
125
|
+
end
|
126
|
+
|
127
|
+
private
|
128
|
+
|
129
|
+
def get_nodes(items, root = '')
|
130
|
+
items.map do |x|
|
131
|
+
current = root.empty? ? x[:label] : root + '|' + x[:label]
|
132
|
+
x.key?(:children) ? [current, get_nodes(x[:children], current)] : current
|
133
|
+
end.flatten
|
134
|
+
end
|
135
|
+
|
136
|
+
def get_selected_node(items, root = '')
|
137
|
+
selected = ''
|
138
|
+
items.each do |x|
|
139
|
+
current = root.empty? ? x[:label] : root + '|' + x[:label]
|
140
|
+
return current if x[:selected]
|
141
|
+
|
142
|
+
selected = get_selected_node(x[:children], current) if x.key?(:children)
|
143
|
+
break unless selected.empty?
|
144
|
+
end
|
145
|
+
selected
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|