glib-web 4.8.1 → 4.8.2
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/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
|