glib-web 4.8.1 → 4.8.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/concerns/glib/json/traversal.rb +45 -2
- data/app/helpers/glib/json_ui/abstract_builder.rb +2 -0
- data/app/helpers/glib/json_ui/action_builder/browsers.rb +1 -1
- data/app/helpers/glib/json_ui/action_builder/storage_items.rb +2 -0
- data/app/helpers/glib/json_ui/action_builder/windows.rb +2 -1
- data/app/helpers/glib/json_ui/action_builder.rb +8 -4
- data/app/helpers/glib/json_ui/builder/mouse_events.rb +22 -22
- data/app/helpers/glib/json_ui/menu_builder.rb +1 -0
- data/app/helpers/glib/json_ui/view_builder/panels.rb +99 -0
- data/app/helpers/glib/json_ui/view_builder.rb +2 -0
- data/app/views/json_ui/garage/actions/_cookies.json.jbuilder +10 -0
- data/app/views/json_ui/garage/actions/_detects.json.jbuilder +16 -0
- data/app/views/json_ui/garage/actions/_list.json.jbuilder +4 -0
- data/app/views/json_ui/garage/actions/_storage_item.jbuilder +27 -0
- data/app/views/json_ui/garage/actions/_windows.json.jbuilder +4 -0
- data/app/views/json_ui/garage/forms/bulk_edit_post.json.jbuilder +17 -0
- data/app/views/json_ui/garage/forms/bulk_edit_post2.json.jbuilder +16 -0
- data/app/views/json_ui/garage/forms/dynamic_group.json.jbuilder +37 -14
- data/app/views/json_ui/garage/lists/edit_actions.json.jbuilder +1 -1
- data/app/views/json_ui/garage/panels/vertical.json.jbuilder +1 -1
- data/app/views/json_ui/garage/tables/bulk_edit.json.jbuilder +101 -0
- data/app/views/json_ui/garage/tables/index.json.jbuilder +6 -3
- data/app/views/json_ui/garage/views/components_replace.json.jbuilder +9 -1
- data/app/views/json_ui/garage/views/controls.json.jbuilder +1 -1
- data/lib/glib/json_crawler/action_crawlers/forms_submit.rb +26 -10
- data/lib/glib/json_crawler/router.rb +39 -8
- metadata +6 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bd7cc62da4019492821f41a143535746725e97014c265ee5d887271bc8350f92
|
4
|
+
data.tar.gz: 6cb94c5b31c3ee5a21f3bb7de0dadf622144a4986a68e82820103d9194145973
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 404991efb9cc61da56f2c886beeeb5a4779e0731dc03dcd30d70d143568e2cc0934dd2a9999b566f71a3fe30f76e17e323b210735606c5627c28f4db8a7105b3
|
7
|
+
data.tar.gz: b50e1fc04dab26be8c9bed1ac410cac570b556146fde3397987aaab6c09bd1283169cec978ebb317c2cd2517c223c7d3d81227e6e99e3508e80c15b471b1e695
|
@@ -33,10 +33,13 @@ module Glib::Json::Traversal
|
|
33
33
|
|
34
34
|
class Visitor
|
35
35
|
# Used in test crawler
|
36
|
-
attr_reader :forms
|
36
|
+
attr_reader :forms, :component_registries, :deferred_actions
|
37
37
|
|
38
|
-
def initialize
|
38
|
+
def initialize(crawler_test: false)
|
39
|
+
@crawler_test = crawler_test
|
40
|
+
@component_registries = []
|
39
41
|
@forms = []
|
42
|
+
@deferred_actions = []
|
40
43
|
end
|
41
44
|
|
42
45
|
def fullPageForm(spec)
|
@@ -44,15 +47,36 @@ module Glib::Json::Traversal
|
|
44
47
|
end
|
45
48
|
|
46
49
|
def begin_page(spec)
|
50
|
+
return unless @crawler_test
|
51
|
+
|
47
52
|
if (form = fullPageForm(spec))
|
48
53
|
@forms << form
|
49
54
|
end
|
55
|
+
|
56
|
+
@component_registries << {}
|
57
|
+
@deferred_actions << []
|
50
58
|
end
|
51
59
|
|
52
60
|
def end_page(spec)
|
61
|
+
return unless @crawler_test
|
62
|
+
|
53
63
|
if fullPageForm(spec)
|
54
64
|
@forms.pop
|
55
65
|
end
|
66
|
+
|
67
|
+
current_actions = @deferred_actions.pop
|
68
|
+
|
69
|
+
# Execute actions with target IDs to ensure the target components have been loade.
|
70
|
+
current_actions.each do |action|
|
71
|
+
action, target_id = action.values
|
72
|
+
if (view_spec = current_component_registry[target_id])
|
73
|
+
action.execute(view_spec) if action
|
74
|
+
else
|
75
|
+
raise "View not found for ID: #{target_id}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
@component_registries.pop
|
56
80
|
end
|
57
81
|
|
58
82
|
def traverse_multiple(views, block)
|
@@ -74,7 +98,26 @@ module Glib::Json::Traversal
|
|
74
98
|
traverse_multiple view['childViews'], block if view
|
75
99
|
end
|
76
100
|
|
101
|
+
def current_deferred_actions
|
102
|
+
@deferred_actions.last
|
103
|
+
end
|
104
|
+
|
105
|
+
def current_component_registry
|
106
|
+
@component_registries.last
|
107
|
+
end
|
108
|
+
|
109
|
+
def defer_action(action_crawler, target_id)
|
110
|
+
current_deferred_actions << {
|
111
|
+
action: action_crawler,
|
112
|
+
target_id: target_id
|
113
|
+
}
|
114
|
+
end
|
115
|
+
|
77
116
|
def traverse_single(view, block)
|
117
|
+
if @crawler_test && (view_id = view['id'])
|
118
|
+
current_component_registry[view_id] = view
|
119
|
+
end
|
120
|
+
|
78
121
|
block.call view
|
79
122
|
|
80
123
|
# Generic view children
|
@@ -11,6 +11,7 @@ class Glib::JsonUi::ActionBuilder
|
|
11
11
|
|
12
12
|
class Open < Action
|
13
13
|
string :url, cache: true
|
14
|
+
bool :updateExisting
|
14
15
|
action :onOpen
|
15
16
|
end
|
16
17
|
|
@@ -19,7 +20,7 @@ class Glib::JsonUi::ActionBuilder
|
|
19
20
|
end
|
20
21
|
|
21
22
|
class Reload < Action
|
22
|
-
string :url, cache: true
|
23
|
+
string :url, cache: true # deprecated
|
23
24
|
bool :disableDirtyCheck
|
24
25
|
action :onReload
|
25
26
|
end
|
@@ -150,12 +150,16 @@ module Glib
|
|
150
150
|
end
|
151
151
|
|
152
152
|
# FUTURE
|
153
|
-
|
154
|
-
|
153
|
+
class Remove < Action
|
154
|
+
string :key
|
155
|
+
action :onRemove
|
156
|
+
end
|
155
157
|
|
156
158
|
# FUTURE
|
157
|
-
|
158
|
-
|
159
|
+
class Clear < Action
|
160
|
+
string :key
|
161
|
+
action :onClear
|
162
|
+
end
|
159
163
|
end
|
160
164
|
end
|
161
165
|
end
|
@@ -8,31 +8,31 @@ module Glib
|
|
8
8
|
action :onMouseLeave
|
9
9
|
end
|
10
10
|
|
11
|
-
def tooltip(options)
|
12
|
-
|
11
|
+
# def tooltip(options)
|
12
|
+
# return unless options
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
# if !Rails.env.test?
|
15
|
+
# key = "tooltip_#{SecureRandom.uuid}"
|
16
|
+
# else
|
17
|
+
# key = 'tooltip_test'
|
18
|
+
# end
|
19
|
+
# onMouseEnter ->(action) do
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
21
|
+
# action.popovers_show(
|
22
|
+
# key: key,
|
23
|
+
# placement: options[:placement] || 'top',
|
24
|
+
# content: ->(popover) do
|
25
|
+
# popover.body childViews: ->(view) {
|
26
|
+
# view.p styleClass: 'tooltip', text: options[:text]
|
27
|
+
# }
|
28
|
+
# end
|
29
|
+
# )
|
30
|
+
# end
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end
|
32
|
+
# onMouseLeave ->(action) do
|
33
|
+
# action.popovers_close key: key
|
34
|
+
# end
|
35
|
+
# end
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
@@ -301,6 +301,7 @@ class Glib::JsonUi::ViewBuilder
|
|
301
301
|
string :truncateLine
|
302
302
|
end
|
303
303
|
|
304
|
+
# deprecated
|
304
305
|
class Table < View
|
305
306
|
hash :nextPage
|
306
307
|
hash :export, required: [:label, :fileName]
|
@@ -325,6 +326,104 @@ class Glib::JsonUi::ViewBuilder
|
|
325
326
|
end
|
326
327
|
end
|
327
328
|
|
329
|
+
class BulkEdit2 < View
|
330
|
+
attr_reader :template
|
331
|
+
|
332
|
+
hash :export, required: [:label, :fileName]
|
333
|
+
hash :import, required: [:submitUrl, :paramName]
|
334
|
+
|
335
|
+
action :onLoadRows
|
336
|
+
action :onCellChange
|
337
|
+
|
338
|
+
string :paramNameForFormData
|
339
|
+
|
340
|
+
array :viewHeaders
|
341
|
+
action :onRowSelected
|
342
|
+
|
343
|
+
def initialize(json, page)
|
344
|
+
super
|
345
|
+
@template = Glib::JsonUi::TableBuilders::Template.new(json, self)
|
346
|
+
end
|
347
|
+
|
348
|
+
# Experimental
|
349
|
+
panels_builder :accessory, :header, :footer
|
350
|
+
|
351
|
+
def viewCells(values)
|
352
|
+
json.set! 'viewCells' do
|
353
|
+
values.each do |value|
|
354
|
+
value.call(page.view_builder)
|
355
|
+
end
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
def header(options = {})
|
360
|
+
json.header do
|
361
|
+
json.backgroundColor options.delete(:backgroundColor)
|
362
|
+
json.cellViews do
|
363
|
+
options.delete(:cellViews)&.call page.view_builder
|
364
|
+
end
|
365
|
+
|
366
|
+
json.colSpans options.delete(:colSpans)
|
367
|
+
end
|
368
|
+
|
369
|
+
raise "Invalid properties: #{options.keys}" if options.size > 0
|
370
|
+
end
|
371
|
+
|
372
|
+
def rows(options = {})
|
373
|
+
block = options.delete(:builder)
|
374
|
+
json.rows do
|
375
|
+
if (objects = options.delete(:objects))
|
376
|
+
objects.each_with_index do |object, index|
|
377
|
+
block&.call template, object, index
|
378
|
+
end
|
379
|
+
else
|
380
|
+
block&.call template
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
raise "Invalid properties: #{options.keys}" if options.size > 0
|
385
|
+
end
|
386
|
+
|
387
|
+
def dataRows(value)
|
388
|
+
json.dataRows value
|
389
|
+
end
|
390
|
+
|
391
|
+
def viewRows(value)
|
392
|
+
json.viewRows value
|
393
|
+
end
|
394
|
+
|
395
|
+
end
|
396
|
+
|
397
|
+
# deprecated
|
398
|
+
class BulkEdit < View
|
399
|
+
hash :nextPage
|
400
|
+
hash :export, required: [:label, :fileName]
|
401
|
+
hash :import, required: [:submitUrl, :paramName]
|
402
|
+
action :onScrollToTop
|
403
|
+
action :onScrollToBottom
|
404
|
+
string :statusViewIdPrefix
|
405
|
+
action :onLoadRows
|
406
|
+
|
407
|
+
# Experimental
|
408
|
+
panels_builder :accessory, :header, :footer
|
409
|
+
|
410
|
+
def firstSection(block)
|
411
|
+
json.sections [1] do
|
412
|
+
block.call page.table_section_builder
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
416
|
+
def sections(blocks)
|
417
|
+
json.sections do
|
418
|
+
blocks.each do |block|
|
419
|
+
json.child! do
|
420
|
+
block.call page.table_section_builder
|
421
|
+
end
|
422
|
+
end
|
423
|
+
end
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
328
427
|
class Scroll < View
|
329
428
|
views :childViews
|
330
429
|
end
|
@@ -68,6 +68,8 @@ module Glib
|
|
68
68
|
hash :analytics, optional: [:featured, :disabled]
|
69
69
|
hash :dragData
|
70
70
|
|
71
|
+
hash :tooltip, required: [:text], optional: [:placement, :position]
|
72
|
+
|
71
73
|
def self.component_name
|
72
74
|
@component_name ||= self.name.sub('Glib::JsonUi::ViewBuilder::', '')
|
73
75
|
end
|
@@ -9,4 +9,14 @@ section.rows builder: ->(template) do
|
|
9
9
|
subaction.snackbars_alert message: 'Saved'
|
10
10
|
end
|
11
11
|
end
|
12
|
+
template.thumbnail title: 'cookies/remove', onClick: ->(action) do
|
13
|
+
action.cookies_remove key: 'glib_cookie', onRemove: ->(subaction) do
|
14
|
+
subaction.snackbars_alert message: 'Saved'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
template.thumbnail title: 'cookies/clear', onClick: ->(action) do
|
18
|
+
action.cookies_clear key: 'glib_cookie', onClear: ->(subaction) do
|
19
|
+
subaction.snackbars_alert message: 'Saved'
|
20
|
+
end
|
21
|
+
end
|
12
22
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
section.header padding: glib_json_padding_list, childViews: ->(header) do
|
2
|
+
header.h3 text: 'Detects'
|
3
|
+
end
|
4
|
+
|
5
|
+
section.rows builder: ->(template) do
|
6
|
+
template.thumbnail title: 'Detect Timezone', onClick: ->(action) do
|
7
|
+
action.browsers_detectTimezone onDetect: ->(detect) do
|
8
|
+
detect.http_post url: json_ui_garage_url(path: 'forms/generic_post_all')
|
9
|
+
end
|
10
|
+
end
|
11
|
+
template.thumbnail title: 'Detect Country', onClick: ->(action) do
|
12
|
+
action.browsers_detectCountry onDetect: ->(detect) do
|
13
|
+
detect.http_post url: json_ui_garage_url(path: 'forms/generic_post_all')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -25,5 +25,9 @@ panel.panels_list id: 'action_list', sections: [
|
|
25
25
|
render "#{@path_prefix}/actions/fields", section: section
|
26
26
|
end, ->(section) do
|
27
27
|
render "#{@path_prefix}/actions/cookies", section: section
|
28
|
+
end, ->(section) do
|
29
|
+
render "#{@path_prefix}/actions/detects", section: section
|
30
|
+
end, ->(section) do
|
31
|
+
render "#{@path_prefix}/actions/storage_item", section: section
|
28
32
|
end
|
29
33
|
]
|
@@ -0,0 +1,27 @@
|
|
1
|
+
|
2
|
+
section.header padding: glib_json_padding_list, childViews: ->(header) do
|
3
|
+
header.h3 id: 'storage_items', text: 'Storage Items'
|
4
|
+
end
|
5
|
+
|
6
|
+
section.rows builder: ->(template) do
|
7
|
+
template.thumbnail title: 'storage/Set', onClick: ->(action) do
|
8
|
+
action.storageItems_set key: 'glib_storage', value: "test_storage_#{DateTime.current.to_i}", onSet: ->(subaction) do
|
9
|
+
subaction.snackbars_alert message: 'Saved'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
template.thumbnail title: 'storage/Get', onClick: ->(action) do
|
13
|
+
action.storageItems_get key: 'glib_storage', onGet: ->(subaction) do
|
14
|
+
subaction.http_post url: json_ui_garage_url(path: 'forms/generic_post_all')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
template.thumbnail title: 'storage/remove', onClick: ->(action) do
|
18
|
+
action.storageItems_remove key: 'glib_storage', onRemove: ->(subaction) do
|
19
|
+
subaction.snackbars_alert message: 'Saved'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
template.thumbnail title: 'storage/clear', onClick: ->(action) do
|
23
|
+
action.storageItems_clear key: 'glib_storage', onClear: ->(subaction) do
|
24
|
+
subaction.snackbars_alert message: 'Saved'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -14,6 +14,10 @@ section.rows builder: ->(template) do
|
|
14
14
|
action.windows_open url: json_ui_garage_url(path: 'home/blank')
|
15
15
|
end
|
16
16
|
|
17
|
+
template.thumbnail title: 'windows/open (updateExisting: true)', onClick: ->(action) do
|
18
|
+
action.windows_open updateExisting: true, url: json_ui_garage_url(path: 'home/blank')
|
19
|
+
end
|
20
|
+
|
17
21
|
template.thumbnail title: 'windows/closeAllWithOpen', onClick: ->(action) do
|
18
22
|
action.windows_closeAllWithOpen url: json_ui_garage_url(path: 'home/index')
|
19
23
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
json_ui_response json do |action|
|
2
|
+
action.runMultiple childActions: ->(multiple) do
|
3
|
+
render "#{@path_prefix}/forms/alert_post_data", action: multiple
|
4
|
+
|
5
|
+
status_view_id = "row_status_#{params[:_index]}"
|
6
|
+
# TODO: This doesn't work. It should update the status icon to indicate that the
|
7
|
+
# import is successful.
|
8
|
+
multiple.components_set \
|
9
|
+
targetId: status_view_id,
|
10
|
+
data: {
|
11
|
+
color: 'success',
|
12
|
+
material: {
|
13
|
+
name: 'check'
|
14
|
+
}
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
json_ui_response json do |action|
|
2
|
+
action.runMultiple childActions: ->(multiple) do
|
3
|
+
# render "#{@path_prefix}/forms/alert_post_data", action: multiple
|
4
|
+
|
5
|
+
status_cell = params[:user]['columns'][0]['compId']
|
6
|
+
|
7
|
+
multiple.components_set \
|
8
|
+
targetId: status_cell,
|
9
|
+
data: {
|
10
|
+
styleClasses: ['success'],
|
11
|
+
material: {
|
12
|
+
name: 'verified'
|
13
|
+
}
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end
|
@@ -27,7 +27,7 @@ page.form url: json_ui_garage_url(path: 'forms/generic_post'), method: 'post', p
|
|
27
27
|
template.spacer height: 10
|
28
28
|
template.fields_text width: 'matchParent', name: 'question', label: 'Question', placeholder: 'Question'
|
29
29
|
|
30
|
-
form.panels_responsive childViews: ->(column) do
|
30
|
+
form.panels_responsive id: 'responsive_{{entry_index}}', childViews: ->(column) do
|
31
31
|
options = [:rating, :yes_no]
|
32
32
|
template.fields_select \
|
33
33
|
width: 'matchParent',
|
@@ -35,22 +35,45 @@ page.form url: json_ui_garage_url(path: 'forms/generic_post'), method: 'post', p
|
|
35
35
|
label: 'Answer Type',
|
36
36
|
placeholder: 'Answer Type',
|
37
37
|
options: options.map { |o| { text: o.to_s.humanize, value: o } },
|
38
|
-
|
39
|
-
action.
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
end
|
38
|
+
onChangeAndLoad: ->(action) do
|
39
|
+
action.logics_set targetId: 'responsive_{{entry_index}}', dataBuilder: ->(set) do
|
40
|
+
set.panels_responsive accessory: ->(accessory) do
|
41
|
+
accessory.footer childViews: ->(footer) do
|
42
|
+
# TODO: Is there a way to only show this if the selected option is "rating".
|
43
|
+
# I.e. `showIf: { "==": [{ "var": 'user[evaluation][{{index}}][type]' }, 'rating'] }`
|
44
|
+
footer.fields_check \
|
45
|
+
width: 'matchParent',
|
46
|
+
id: 'check_{{entry_index}}',
|
47
|
+
name: 'enabled',
|
48
|
+
label: 'Enable',
|
49
|
+
checkValue: true
|
51
50
|
end
|
52
51
|
end
|
52
|
+
end, onSet: ->(subaction) do
|
53
|
+
subaction.logics_set \
|
54
|
+
targetId: 'check_{{entry_index}}',
|
55
|
+
conditionalData: {
|
56
|
+
value: {
|
57
|
+
"==": [{ "var": 'user[evaluation][{{entry_index}}][type]' }, 'rating']
|
58
|
+
}
|
59
|
+
}
|
53
60
|
end
|
61
|
+
|
62
|
+
# action.components_findClosest view: 'panels/responsive', onFind: ->(find) do
|
63
|
+
# find.logics_set dataBuilder: ->(set) do
|
64
|
+
# set.panels_responsive accessory: ->(accessory) do
|
65
|
+
# accessory.footer childViews: ->(footer) do
|
66
|
+
# # TODO: Is there a way to only show this if the selected option is "rating".
|
67
|
+
# # I.e. `showIf: { "==": [{ "var": 'user[evaluation][{{index}}][type]' }, 'rating'] }`
|
68
|
+
# footer.fields_check \
|
69
|
+
# width: 'matchParent',
|
70
|
+
# name: 'enabled',
|
71
|
+
# label: 'Enable',
|
72
|
+
# checkValue: '1'
|
73
|
+
# end
|
74
|
+
# end
|
75
|
+
# end
|
76
|
+
# end
|
54
77
|
end
|
55
78
|
end, accessory: ->(accessory) do
|
56
79
|
accessory.footer childViews: ->(footer) do
|
@@ -23,7 +23,7 @@ page.list firstSection: ->(section) do
|
|
23
23
|
menu.button \
|
24
24
|
styleClasses: ['icon', 'text', 'x-small'],
|
25
25
|
icon: 'share',
|
26
|
-
tooltip: { text: 'Share',
|
26
|
+
tooltip: { text: 'Share', placement: 'left' }
|
27
27
|
|
28
28
|
# TODO: Use popoever
|
29
29
|
# childButtons: ->(submenu) do
|
@@ -61,7 +61,7 @@ json_ui_page json do |page|
|
|
61
61
|
|
62
62
|
scroll.label text: "\n"
|
63
63
|
scroll.h1 text: 'Click action'
|
64
|
-
scroll.panels_vertical width: 100, height: 100, backgroundColor: '#b3bac2', align: 'center', onClick: ->(action) do
|
64
|
+
scroll.panels_vertical styleClasses: ['rounded-corner'], width: 100, height: 100, backgroundColor: '#b3bac2', align: 'center', onClick: ->(action) do
|
65
65
|
action.windows_open url: json_ui_garage_url(path: 'home/blank')
|
66
66
|
end, childViews: ->(panel) do
|
67
67
|
panel.label text: 'Click me'
|
@@ -0,0 +1,101 @@
|
|
1
|
+
json.title 'Tables'
|
2
|
+
|
3
|
+
page = json_ui_page json
|
4
|
+
render "#{@path_prefix}/nav_menu", json: json, page: page
|
5
|
+
|
6
|
+
# submit_button_id = 'save_button_top'
|
7
|
+
|
8
|
+
page.scroll childViews: ->(scroll) do
|
9
|
+
# scroll.panels_bulkEdit \
|
10
|
+
# import: { submitUrl: json_ui_garage_url(path: 'forms/bulk_edit_post'), paramName: 'user' },
|
11
|
+
# statusViewIdPrefix: 'row_status_',
|
12
|
+
# firstSection: ->(section) do
|
13
|
+
# section.header cellViews: ->(header) do
|
14
|
+
# header.label text: 'month'
|
15
|
+
# header.label text: 'electricity_usage'
|
16
|
+
# header.label text: 'gas_usage'
|
17
|
+
# end
|
18
|
+
# end,
|
19
|
+
# accessory: ->(accessory) do
|
20
|
+
# accessory.header childViews: ->(header) do
|
21
|
+
# header.button \
|
22
|
+
# text: 'Save',
|
23
|
+
# id: submit_button_id,
|
24
|
+
# displayed: false,
|
25
|
+
# onClick: ->(action) do
|
26
|
+
# action.forms_submit
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
# end,
|
30
|
+
# onLoadRows: ->(action) do
|
31
|
+
# action.components_set targetId: submit_button_id, data: { displayed: true }
|
32
|
+
# end
|
33
|
+
|
34
|
+
options = [{ text: 'yes', value: 'yes' }, { text: 'no', value: 'no' }]
|
35
|
+
# scroll.button id: 'btn-action', text: 'verify', onClick: ->(action) do
|
36
|
+
# action.windows_reload url: json_ui_garage_current_url(icon: 'verified')
|
37
|
+
# end
|
38
|
+
scroll.button displayed: false, id: 'submit_top', text: 'submit', onClick: ->(action) do
|
39
|
+
action.forms_submit targetId: 'bulkEdit'
|
40
|
+
end
|
41
|
+
scroll.panels_responsive styleClass: 'overflow-y-auto', width: 'matchParent', height: 500, childViews: ->(wres) do
|
42
|
+
scroll.panels_bulkEdit2 \
|
43
|
+
id: 'bulkEdit',
|
44
|
+
width: 'matchParent',
|
45
|
+
backgroundColor: '#e2e2e2',
|
46
|
+
import: { submitUrl: json_ui_garage_url(path: 'forms/bulk_edit_post2'), paramName: 'user' },
|
47
|
+
viewHeaders: [
|
48
|
+
{ text: '', id: 'status', minWidth: 24 },
|
49
|
+
{ text: 'Month', id: 'month', importable: true },
|
50
|
+
{ text: 'Electricity usage', id: 'electricity_usage', importable: true },
|
51
|
+
{ text: 'Gas usage', id: 'gas_usage', importable: true },
|
52
|
+
{ text: 'Compliant', id: 'compliant', importable: true }
|
53
|
+
],
|
54
|
+
viewCells: [
|
55
|
+
->(view) do
|
56
|
+
view.icon name: params[:icon] || 'preview', styleClasses: ['warning'], tooltip: { text: params[:icon] || 'preview' }
|
57
|
+
end,
|
58
|
+
->(view) do
|
59
|
+
view.fields_number width: 100
|
60
|
+
end,
|
61
|
+
->(view) do
|
62
|
+
view.fields_number width: 150
|
63
|
+
end,
|
64
|
+
->(view) do
|
65
|
+
view.fields_number width: 100
|
66
|
+
end,
|
67
|
+
->(view) do
|
68
|
+
view.fields_select options: options
|
69
|
+
end
|
70
|
+
],
|
71
|
+
paramNameForFormData: 'message',
|
72
|
+
onCellChange: ->(action) do
|
73
|
+
action.snackbars_alert
|
74
|
+
end,
|
75
|
+
onLoadRows: ->(action) do
|
76
|
+
action.runMultiple childActions: ->(multiple) do
|
77
|
+
multiple.snackbars_alert message: 'rows loaded'
|
78
|
+
multiple.components_set targetId: 'submit_top', data: { displayed: true }
|
79
|
+
multiple.components_set targetId: 'submit_bottom', data: { displayed: true }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
# onRowSelected: ->(action) do
|
83
|
+
# action.snackbars_alert
|
84
|
+
# end
|
85
|
+
# dataRows: [
|
86
|
+
# { rowId: 1, columns: [{ material: { name: params[:icon] || 'preview' }, value: 'preview' }, { value: 1 }, { value: 30 }, { value: 33 }, { value: 'yes' }] },
|
87
|
+
# { rowId: 2, columns: [{ material: { name: params[:icon] || 'preview' }, value: 'preview' }, { value: 2 }, { value: 34 }, { value: 35 }, { value: 'no' }] },
|
88
|
+
# { rowId: 3, columns: [{ material: { name: params[:icon] || 'preview' }, value: 'preview' }, { value: 1 }, { value: 30 }, { value: 33 }, { value: 'yes' }] },
|
89
|
+
# { rowId: 4, columns: [{ material: { name: params[:icon] || 'preview' }, value: 'preview' }, { value: 2 }, { value: 34 }, { value: 35 }, { value: 'no' }] },
|
90
|
+
# { rowId: 5, columns: [{ material: { name: params[:icon] || 'preview' }, value: 'preview' }, { value: 1 }, { value: 30 }, { value: 33 }, { value: 'yes' }] },
|
91
|
+
# { rowId: 6, columns: [{ material: { name: params[:icon] || 'preview' }, value: 'preview' }, { value: 2 }, { value: 34 }, { value: 35 }, { value: 'no' }] },
|
92
|
+
# { rowId: 7, columns: [{ material: { name: params[:icon] || 'preview' }, value: 'preview' }, { value: 1 }, { value: 30 }, { value: 33 }, { value: 'yes' }] },
|
93
|
+
# { rowId: 8, columns: [{ material: { name: params[:icon] || 'preview' }, value: 'preview' }, { value: 2 }, { value: 34 }, { value: 35 }, { value: 'no' }] },
|
94
|
+
# { rowId: 9, columns: [{ material: { name: params[:icon] || 'preview' }, value: 'preview' }, { value: 1 }, { value: 30 }, { value: 33 }, { value: 'yes' }] },
|
95
|
+
# { rowId: 10, columns: [{ material: { name: params[:icon] || 'preview' }, value: 'preview' }, { value: 2 }, { value: 34 }, { value: 35 }, { value: 'no' }] }
|
96
|
+
# ]
|
97
|
+
end
|
98
|
+
scroll.button displayed: false, id: 'submit_bottom', text: 'submit', onClick: ->(action) do
|
99
|
+
action.forms_submit targetId: 'bulkEdit'
|
100
|
+
end
|
101
|
+
end
|
@@ -11,9 +11,6 @@ page.list firstSection: ->(section) do
|
|
11
11
|
template.thumbnail title: 'Horizontal Scroll', onClick: ->(action) do
|
12
12
|
action.windows_open url: json_ui_garage_url(path: 'tables/horizontal_scroll')
|
13
13
|
end
|
14
|
-
template.thumbnail title: 'Export/Import', onClick: ->(action) do
|
15
|
-
action.windows_open url: json_ui_garage_url(path: 'tables/export_import')
|
16
|
-
end
|
17
14
|
template.thumbnail title: 'Autoload as Needed', onClick: ->(action) do
|
18
15
|
action.windows_open url: json_ui_garage_url(path: 'tables/autoload_as_needed')
|
19
16
|
end
|
@@ -23,6 +20,12 @@ page.list firstSection: ->(section) do
|
|
23
20
|
template.thumbnail title: 'Panel Content', onClick: ->(action) do
|
24
21
|
action.windows_open url: json_ui_garage_url(path: 'tables/panel_content')
|
25
22
|
end
|
23
|
+
template.thumbnail title: 'Export/Import (Maybe deprecated in the future)', onClick: ->(action) do
|
24
|
+
action.windows_open url: json_ui_garage_url(path: 'tables/export_import')
|
25
|
+
end
|
26
|
+
template.thumbnail title: 'Bulk edit and import', onClick: ->(action) do
|
27
|
+
action.windows_open url: json_ui_garage_url(path: 'tables/bulk_edit')
|
28
|
+
end
|
26
29
|
end
|
27
30
|
|
28
31
|
end
|
@@ -63,6 +63,12 @@ page.body padding: glib_json_padding_body, childViews: ->(body) do
|
|
63
63
|
view.fields_select options: cities + [{ text: 'Taipei', value: 'taipei' }]
|
64
64
|
end
|
65
65
|
end
|
66
|
+
|
67
|
+
hori.button text: 'Change icon', onClick: ->(action) do
|
68
|
+
action.components_replace targetId: 'icon', newView: ->(view) do
|
69
|
+
view.icon name: 'verified', styleClasses: ['success']
|
70
|
+
end
|
71
|
+
end
|
66
72
|
end
|
67
73
|
res.spacer height: 16
|
68
74
|
res.h3 text: 'Childviews changes'
|
@@ -103,7 +109,7 @@ page.body padding: glib_json_padding_body, childViews: ->(body) do
|
|
103
109
|
|
104
110
|
res.panels_column lg: { cols: 9 }, childViews: ->(col) do
|
105
111
|
col.panels_responsive id: 'pres', width: 200, childViews: ->(cview) do
|
106
|
-
cview.label text: 'Panels responsive'
|
112
|
+
cview.label text: 'Panels responsive', id: 'text-responsive'
|
107
113
|
end
|
108
114
|
col.spacer height: 4
|
109
115
|
col.panels_column id: 'pcol', lg: { cols: 6 }, childViews: ->(cview) do
|
@@ -143,6 +149,8 @@ page.body padding: glib_json_padding_body, childViews: ->(body) do
|
|
143
149
|
col.spacer height: 4
|
144
150
|
col.fields_submit text: 'Submit'
|
145
151
|
end
|
152
|
+
col.spacer height: 8
|
153
|
+
col.icon id: 'icon', name: 'pending', size: 32, styleClasses: ['warning']
|
146
154
|
end
|
147
155
|
end
|
148
156
|
end
|
@@ -81,7 +81,7 @@ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
|
|
81
81
|
scroll.button \
|
82
82
|
icon: 'info',
|
83
83
|
styleClasses: ['icon', 'plain'],
|
84
|
-
tooltip: { text: 'Disabled Icon button with tooltip text and custom tooltip position',
|
84
|
+
tooltip: { text: 'Disabled Icon button with tooltip text and custom tooltip position', placement: 'right' },
|
85
85
|
disabled: true
|
86
86
|
|
87
87
|
scroll.spacer height: 20
|
@@ -1,22 +1,38 @@
|
|
1
1
|
module Glib
|
2
2
|
module JsonCrawler
|
3
3
|
class FormsSubmit < ActionCrawler
|
4
|
-
def initialize(http,
|
4
|
+
def initialize(http, args)
|
5
5
|
super(http)
|
6
6
|
|
7
|
-
|
7
|
+
return if http.router.should_defer_crawl?(self, args)
|
8
8
|
|
9
|
-
|
9
|
+
form = http.router.last_form
|
10
|
+
execute(form)
|
11
|
+
end
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
+
def execute(form)
|
14
|
+
http = @http
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
|
16
|
+
raise "Submit action needs to be inside a form: #{http.router.last_log}" unless form
|
17
|
+
|
18
|
+
case form['view']
|
19
|
+
when 'panels/bulkEdit2-v1'
|
20
|
+
method = 'post'
|
21
|
+
action = "forms/#{method}"
|
22
|
+
url = form['import']['submitUrl']
|
23
|
+
# TODO: Simulate data submission and check response
|
24
|
+
@http.router.log action, url
|
17
25
|
else
|
18
|
-
|
19
|
-
|
26
|
+
method = form['method']
|
27
|
+
action = "forms/#{method}"
|
28
|
+
|
29
|
+
case method
|
30
|
+
when 'patch', 'put', 'post'
|
31
|
+
submit_form(form, action, method.to_sym)
|
32
|
+
else
|
33
|
+
url = form['url']
|
34
|
+
http.router.log action, url
|
35
|
+
end
|
20
36
|
end
|
21
37
|
end
|
22
38
|
|
@@ -1,25 +1,48 @@
|
|
1
1
|
module Glib
|
2
2
|
module JsonCrawler
|
3
3
|
class Router
|
4
|
-
attr_reader :read_only_actions, :logger
|
4
|
+
attr_reader :read_only_actions, :logger, :last_log, :deferred_actions
|
5
5
|
attr_accessor :host
|
6
6
|
|
7
7
|
def log(action, url, response = nil)
|
8
|
-
@
|
8
|
+
@last_log = [
|
9
9
|
action,
|
10
10
|
response.present? ? response.code : nil,
|
11
11
|
url
|
12
|
-
].compact.join(' :: ')
|
12
|
+
].compact.join(' :: ')
|
13
|
+
|
14
|
+
# puts @last_log
|
15
|
+
|
16
|
+
@logger += ' ' * @depth + @last_log + "\n"
|
13
17
|
end
|
14
18
|
|
15
19
|
def _puts(text)
|
16
20
|
puts ' ' * @depth + text
|
17
21
|
end
|
18
22
|
|
23
|
+
def assert_target_ids_exist(args)
|
24
|
+
if (target_ids = args['targetIds'])
|
25
|
+
target_ids.each do |target_id|
|
26
|
+
@visitor.defer_action(nil, target_id)
|
27
|
+
end
|
28
|
+
elsif (target_id = args['targetId'])
|
29
|
+
@visitor.defer_action(nil, target_id)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def should_defer_crawl?(action_crawler, args)
|
34
|
+
if (target_id = args['targetId'])
|
35
|
+
@visitor.defer_action(action_crawler, target_id)
|
36
|
+
return true
|
37
|
+
end
|
38
|
+
|
39
|
+
false
|
40
|
+
end
|
41
|
+
|
19
42
|
def initialize
|
20
43
|
@depth = -1
|
21
44
|
@logger = ''
|
22
|
-
@visitor = Glib::Json::Traversal::Visitor.new
|
45
|
+
@visitor = Glib::Json::Traversal::Visitor.new(crawler_test: true)
|
23
46
|
@read_only_actions = Set.new
|
24
47
|
# default rails's development host
|
25
48
|
@host ||= 'localhost:3000'
|
@@ -32,8 +55,9 @@ module Glib
|
|
32
55
|
case args['view']
|
33
56
|
when 'fields/submit-v1', 'fields/submit'
|
34
57
|
@depth += 1
|
35
|
-
forms = @visitor.forms
|
36
|
-
JsonCrawler::FormsSubmit.new(http, forms.last)
|
58
|
+
# forms = @visitor.forms
|
59
|
+
# JsonCrawler::FormsSubmit.new(http, args, forms.last)
|
60
|
+
JsonCrawler::FormsSubmit.new(http, args)
|
37
61
|
@depth -= 1
|
38
62
|
return
|
39
63
|
end
|
@@ -51,6 +75,8 @@ module Glib
|
|
51
75
|
action = spec&.fetch('action')
|
52
76
|
params = spec
|
53
77
|
|
78
|
+
assert_target_ids_exist(params)
|
79
|
+
|
54
80
|
if action.present?
|
55
81
|
@depth += 1
|
56
82
|
case action
|
@@ -74,8 +100,9 @@ module Glib
|
|
74
100
|
when 'http/post-v1', 'http/post'
|
75
101
|
JsonCrawler::ActionHttp.new(:post, http, params, action)
|
76
102
|
when 'forms/submit-v1', 'forms/submit'
|
77
|
-
forms = @visitor.forms
|
78
|
-
JsonCrawler::FormsSubmit.new(http, forms.last)
|
103
|
+
# forms = @visitor.forms
|
104
|
+
# JsonCrawler::FormsSubmit.new(http, params, forms.last)
|
105
|
+
JsonCrawler::FormsSubmit.new(http, params)
|
79
106
|
when 'dialogs/alert-v1', 'dialogs/alert'
|
80
107
|
JsonCrawler::DialogsAlert.new(http, params, action)
|
81
108
|
else
|
@@ -93,6 +120,10 @@ module Glib
|
|
93
120
|
end
|
94
121
|
end
|
95
122
|
|
123
|
+
def last_form
|
124
|
+
@visitor.forms.last
|
125
|
+
end
|
126
|
+
|
96
127
|
def follow(http, target_routers)
|
97
128
|
if !target_routers.is_a?(Array)
|
98
129
|
target_routers = [target_routers]
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glib-web
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.8.
|
4
|
+
version: 4.8.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ''
|
@@ -163,6 +163,7 @@ files:
|
|
163
163
|
- app/views/json_ui/garage/actions/_commands.json.jbuilder
|
164
164
|
- app/views/json_ui/garage/actions/_components.json.jbuilder
|
165
165
|
- app/views/json_ui/garage/actions/_cookies.json.jbuilder
|
166
|
+
- app/views/json_ui/garage/actions/_detects.json.jbuilder
|
166
167
|
- app/views/json_ui/garage/actions/_dialogs.json.jbuilder
|
167
168
|
- app/views/json_ui/garage/actions/_dialogs_show.json.jbuilder
|
168
169
|
- app/views/json_ui/garage/actions/_fields.json.jbuilder
|
@@ -172,6 +173,7 @@ files:
|
|
172
173
|
- app/views/json_ui/garage/actions/_reload.json.jbuilder
|
173
174
|
- app/views/json_ui/garage/actions/_sheets.json.jbuilder
|
174
175
|
- app/views/json_ui/garage/actions/_snackbars.json.jbuilder
|
176
|
+
- app/views/json_ui/garage/actions/_storage_item.jbuilder
|
175
177
|
- app/views/json_ui/garage/actions/_timeouts.json.jbuilder
|
176
178
|
- app/views/json_ui/garage/actions/_tours.json.jbuilder
|
177
179
|
- app/views/json_ui/garage/actions/_windows.json.jbuilder
|
@@ -186,6 +188,8 @@ files:
|
|
186
188
|
- app/views/json_ui/garage/forms/_read_more_text.json.jbuilder
|
187
189
|
- app/views/json_ui/garage/forms/basic.json.jbuilder
|
188
190
|
- app/views/json_ui/garage/forms/basic_post.json.jbuilder
|
191
|
+
- app/views/json_ui/garage/forms/bulk_edit_post.json.jbuilder
|
192
|
+
- app/views/json_ui/garage/forms/bulk_edit_post2.json.jbuilder
|
189
193
|
- app/views/json_ui/garage/forms/checkboxes.json.jbuilder
|
190
194
|
- app/views/json_ui/garage/forms/chip_group.json.jbuilder
|
191
195
|
- app/views/json_ui/garage/forms/conditional_value.json.jbuilder
|
@@ -288,6 +292,7 @@ files:
|
|
288
292
|
- app/views/json_ui/garage/tables/_autoload_section.json.jbuilder
|
289
293
|
- app/views/json_ui/garage/tables/autoload_all.json.jbuilder
|
290
294
|
- app/views/json_ui/garage/tables/autoload_as_needed.json.jbuilder
|
295
|
+
- app/views/json_ui/garage/tables/bulk_edit.json.jbuilder
|
291
296
|
- app/views/json_ui/garage/tables/export_import.json.jbuilder
|
292
297
|
- app/views/json_ui/garage/tables/horizontal_scroll.json.jbuilder
|
293
298
|
- app/views/json_ui/garage/tables/index.json.jbuilder
|