glib-web 2.2.0 → 2.4.0
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/libs.rb +10 -4
- data/app/controllers/glib/home_controller.rb +20 -0
- data/app/helpers/glib/json_ui/action_builder/commands.rb +8 -0
- data/app/helpers/glib/json_ui/menu_builder.rb +1 -0
- data/app/helpers/glib/json_ui/page_helper.rb +4 -0
- data/app/helpers/glib/json_ui/view_builder/fields.rb +3 -1
- data/app/helpers/glib/json_ui/view_builder/panels.rb +4 -2
- data/app/helpers/glib/json_ui/view_builder.rb +7 -1
- data/app/models/concerns/glib/soft_deletable.rb +5 -0
- data/app/views/json_ui/garage/_nav_menu.json.jbuilder +10 -0
- data/app/views/json_ui/garage/lists/edit_actions.json.jbuilder +16 -6
- data/app/views/json_ui/garage/pages/custom_style_class.json.jbuilder +32 -0
- data/app/views/json_ui/garage/pages/index.json.jbuilder +4 -4
- data/app/views/json_ui/garage/panels/_hover_views_content.json.jbuilder +5 -4
- data/app/views/json_ui/garage/panels/hover.json.jbuilder +12 -13
- data/app/views/json_ui/garage/panels/responsive.json.jbuilder +30 -9
- data/app/views/json_ui/garage/panels/timeline.json.jbuilder +17 -7
- data/app/views/json_ui/garage/panels/ul.json.jbuilder +34 -2
- data/app/views/json_ui/garage/views/banners.json.jbuilder +1 -1
- data/app/views/json_ui/garage/views/controls.json.jbuilder +19 -2
- data/app/views/layouts/json_ui/renderer.html.erb +4 -0
- data/lib/glib/json_crawler/action_crawlers/dialogs_alert.rb +17 -0
- data/lib/glib/json_crawler/action_crawlers/forms_submit.rb +28 -7
- data/lib/glib/json_crawler/action_crawlers/windows_open.rb +2 -2
- data/lib/glib/json_crawler/router.rb +15 -5
- data/lib/glib/json_crawler.rb +1 -0
- metadata +3 -2
- data/app/views/json_ui/garage/pages/flat_centered.json.jbuilder +0 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 416ab4888b4ca5e16220519fb9f1dc56999d91be403a2f14c464386f4b586604
|
4
|
+
data.tar.gz: b6e8f65a85f9542b9a3a8e865d52a36860d7acb95cdc930918e379b290ba0e66
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d2705c8939f81dcd503c8d7c77c5f70d157df9645123b4ca1f56fefe351bbafdeee4485cfaa31838a2e001f18cd05ae8776c44a7569b8c1c892838f17eace3ed
|
7
|
+
data.tar.gz: 1dcb659e7c9587137eef9aebfa1743e62edf6c427855a653fd6b12d71c827d5a32fb2e6131011cd80914f505bd6d140c07f61aaa9c4b60d301cb7f729772a1f5
|
@@ -100,6 +100,16 @@ module Glib::Json::Libs
|
|
100
100
|
after_action :__json_traversal_register_dynamic_text
|
101
101
|
end
|
102
102
|
|
103
|
+
def json_libs_skip_json_ui(options)
|
104
|
+
prepend_before_action options do
|
105
|
+
params[:_skip_render] = 'true'
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def json_libs_force_json_ui
|
110
|
+
before_action :glib_force_json_ui
|
111
|
+
end
|
112
|
+
|
103
113
|
def json_libs_set_locale
|
104
114
|
before_action do
|
105
115
|
# Need to explicitly fallback to EN
|
@@ -109,10 +119,6 @@ module Glib::Json::Libs
|
|
109
119
|
end
|
110
120
|
end
|
111
121
|
|
112
|
-
def json_libs_force_json_ui
|
113
|
-
before_action :glib_force_json_ui
|
114
|
-
end
|
115
|
-
|
116
122
|
def json_libs_rescue_csrf
|
117
123
|
rescue_from ActionController::InvalidAuthenticityToken do |exception|
|
118
124
|
sign_out(:user)
|
@@ -10,6 +10,26 @@ module Glib
|
|
10
10
|
|
11
11
|
@path_prefix = 'json_ui/garage'
|
12
12
|
|
13
|
+
@__glib_head_code =<<-eos
|
14
|
+
<style>
|
15
|
+
.custom-container .pages-body > div > .panels-responsive {
|
16
|
+
max-width: 800px;
|
17
|
+
width: 100%;
|
18
|
+
margin-right: auto;
|
19
|
+
margin-left: auto;
|
20
|
+
}
|
21
|
+
|
22
|
+
.rounded-corner {
|
23
|
+
border-radius: 16px;
|
24
|
+
}
|
25
|
+
|
26
|
+
/* Make sure the hover highlight effect also has rounded corners */
|
27
|
+
.rounded-corner:hover:after {
|
28
|
+
border-radius: 16px;
|
29
|
+
}
|
30
|
+
</style>
|
31
|
+
eos
|
32
|
+
|
13
33
|
# We can't use prepend_view_path because it affects the app, not the gem
|
14
34
|
path = "#{@path_prefix}/#{params[:path] || 'home/index'}"
|
15
35
|
render path
|
@@ -106,6 +106,10 @@ module Glib
|
|
106
106
|
json.template template
|
107
107
|
end
|
108
108
|
|
109
|
+
def containerStyleClasses(styleClasses)
|
110
|
+
json.containerStyleClasses styleClasses
|
111
|
+
end
|
112
|
+
|
109
113
|
def leftDrawer(options = {})
|
110
114
|
json.leftDrawer do
|
111
115
|
[:styleClasses, :backgroundColor].each do |name|
|
@@ -143,7 +143,9 @@ class Glib::JsonUi::ViewBuilder
|
|
143
143
|
class RichText < Text
|
144
144
|
array :images
|
145
145
|
hash :imageUploader
|
146
|
-
|
146
|
+
# `html` or `markdown`
|
147
|
+
string :produce
|
148
|
+
string :accept
|
147
149
|
end
|
148
150
|
|
149
151
|
class Country < AbstractField
|
@@ -5,6 +5,10 @@ class Glib::JsonUi::ViewBuilder
|
|
5
5
|
string :paramNameForFormData
|
6
6
|
bool :local
|
7
7
|
|
8
|
+
# TODO: Enable this when we know it won't break existing apps.
|
9
|
+
# Even for pure client-side apps, this is required because form.validate() requires a URL to construct form data.
|
10
|
+
# required :url
|
11
|
+
|
8
12
|
def is_array_association?(prop)
|
9
13
|
# # Not all model is ActiveRecord
|
10
14
|
# if @model.class.respond_to?(:reflect_on_association)
|
@@ -224,8 +228,6 @@ class Glib::JsonUi::ViewBuilder
|
|
224
228
|
|
225
229
|
views :childViews
|
226
230
|
action :onClick
|
227
|
-
|
228
|
-
views :hoverViews
|
229
231
|
end
|
230
232
|
|
231
233
|
class Vertical < View
|
@@ -192,6 +192,12 @@ module Glib
|
|
192
192
|
action :onClick
|
193
193
|
color :color
|
194
194
|
bool :disabled
|
195
|
+
|
196
|
+
def childButtons(block)
|
197
|
+
json.childButtons do
|
198
|
+
block.call page.menu_builder
|
199
|
+
end
|
200
|
+
end
|
195
201
|
end
|
196
202
|
|
197
203
|
class Fab < View
|
@@ -279,7 +285,7 @@ module Glib
|
|
279
285
|
|
280
286
|
class ProgressCircle < View
|
281
287
|
int :rotate # from 0 to 360
|
282
|
-
int :size
|
288
|
+
int :size
|
283
289
|
int :value # from 0 to 100
|
284
290
|
color :color
|
285
291
|
string :text
|
@@ -22,6 +22,11 @@ module Glib
|
|
22
22
|
soft_destroy_record
|
23
23
|
end
|
24
24
|
|
25
|
+
# More explicit naming which is sometimes useful for readability.
|
26
|
+
def soft_destroy
|
27
|
+
soft_destroy_record
|
28
|
+
end
|
29
|
+
|
25
30
|
# Revive a soft-deleted record and associated records if soft-deleted,
|
26
31
|
# otherwise return self
|
27
32
|
def revive
|
@@ -1,4 +1,14 @@
|
|
1
1
|
|
2
|
+
page.navBar height: 44, backgroundColor: '#a8c4e3', color: '#ffffff', showTitle: true, rightButtons: ->(menu) do
|
3
|
+
menu.button icon: { name: 'refresh' }, onClick: ->(action) do
|
4
|
+
action.windows_reload
|
5
|
+
end
|
6
|
+
menu.button icon: { name: 'open_in_new' }, onClick: ->(action) do
|
7
|
+
action.windows_open url: json_ui_garage_current_url(step: params[:step].to_i + 1)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
|
2
12
|
if local_assigns[:top_nav] || json_ui_app_is_web?
|
3
13
|
page.leftDrawer styleClasses:['maxi'], content: ->(drawer) do
|
4
14
|
drawer.header childViews: ->(header) do
|
@@ -17,12 +17,22 @@ page.list firstSection: ->(section) do
|
|
17
17
|
subaction.dialogs_alert message: 'Tick/untick'
|
18
18
|
end
|
19
19
|
end, rightButtons: ->(menu) do
|
20
|
-
menu.button
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
menu.button \
|
21
|
+
styleClass: 'icon',
|
22
|
+
icon: 'share',
|
23
|
+
tooltip: { text: 'Share' },
|
24
|
+
childButtons: ->(submenu) do
|
25
|
+
submenu.button text: 'Dropdown item 1'
|
26
|
+
submenu.button text: 'Dropdown item 2'
|
27
|
+
submenu.button text: 'Dropdown item 3'
|
28
|
+
end
|
29
|
+
menu.button \
|
30
|
+
styleClass: 'icon',
|
31
|
+
icon: 'open_in_new',
|
32
|
+
tooltip: { text: 'Open in new window' },
|
33
|
+
onClick: ->(subaction) do
|
34
|
+
subaction.dialogs_alert message: 'Open'
|
35
|
+
end
|
26
36
|
end, editButtons: ->(menu) do
|
27
37
|
menu.button text: "Edit (ID: #{page_index})", onClick: ->(action) do
|
28
38
|
action.dialogs_alert message: 'Perform Edit action'
|
@@ -0,0 +1,32 @@
|
|
1
|
+
json.title 'Pages'
|
2
|
+
|
3
|
+
page = json_ui_page json
|
4
|
+
|
5
|
+
page.template 'fullWidth'
|
6
|
+
page.containerStyleClasses ['custom-container']
|
7
|
+
|
8
|
+
render "#{@path_prefix}/nav_menu", json: json, page: page
|
9
|
+
|
10
|
+
page.header padding: glib_json_padding_body, childViews: ->(header) do
|
11
|
+
header.panels_vertical width: 'matchParent', styleClass: 'card', padding: glib_json_padding_body, childViews: ->(vertical) do
|
12
|
+
vertical.h1 text: 'Header'
|
13
|
+
vertical.spacer height: 4
|
14
|
+
vertical.label text: 'Here we set the `body` panel\'s max-width using containerStyleClasses.'
|
15
|
+
end
|
16
|
+
header.spacer height: 20
|
17
|
+
end
|
18
|
+
|
19
|
+
page.footer padding: glib_json_padding_body, childViews: ->(footer) do
|
20
|
+
footer.spacer height: 20
|
21
|
+
footer.panels_vertical width: 'matchParent', styleClass: 'card', padding: glib_json_padding_body, childViews: ->(vertical) do
|
22
|
+
vertical.h1 text: 'Footer'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
page.body padding: glib_json_padding_body, childViews: ->(scroll) do
|
27
|
+
scroll.panels_vertical width: 'matchParent', styleClass: 'card', padding: glib_json_padding_body, childViews: ->(vertical) do
|
28
|
+
(1..100).each do |index|
|
29
|
+
scroll.label text: 'Content'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -33,6 +33,10 @@ json_ui_page json do |page|
|
|
33
33
|
template.thumbnail title: 'Redirect onLoad', onClick: ->(action) do
|
34
34
|
action.windows_open url: json_ui_garage_url(path: 'pages/redirect_onload')
|
35
35
|
end
|
36
|
+
|
37
|
+
template.thumbnail title: 'Custom Style Class', onClick: ->(action) do
|
38
|
+
action.windows_open url: json_ui_garage_url(path: 'pages/custom_style_class')
|
39
|
+
end
|
36
40
|
end
|
37
41
|
end,
|
38
42
|
->(section) do
|
@@ -41,10 +45,6 @@ json_ui_page json do |page|
|
|
41
45
|
end
|
42
46
|
|
43
47
|
section.rows builder: ->(template) do
|
44
|
-
template.thumbnail title: 'Flat Centered', onClick: ->(action) do
|
45
|
-
action.windows_open url: json_ui_garage_url(path: 'pages/flat_centered')
|
46
|
-
end
|
47
|
-
|
48
48
|
template.thumbnail title: 'Full Width', onClick: ->(action) do
|
49
49
|
action.windows_open url: json_ui_garage_url(path: 'pages/full_width')
|
50
50
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'
|
2
|
-
value =''
|
3
|
-
|
2
|
+
value = ''
|
3
|
+
i.times { value += text }
|
4
|
+
|
4
5
|
hover.panels_responsive padding: {top: 24, right: 24, bottom: 24, left: 24 }, childViews: ->(responsive) do
|
5
6
|
responsive.avatar url: glib_json_image_avatar_url
|
6
7
|
|
@@ -11,7 +12,7 @@ hover.panels_responsive padding: {top: 24, right: 24, bottom: 24, left: 24 }, ch
|
|
11
12
|
responsive.h2 text: 'Hover View'
|
12
13
|
responsive.p text:value
|
13
14
|
responsive.spacer height: 24
|
14
|
-
responsive.button text:'Button', onClick:->(action) do
|
15
|
+
responsive.button text: 'Button', onClick:->(action) do
|
15
16
|
action.dialogs_alert message: 'Clicked'
|
16
17
|
end
|
17
|
-
end
|
18
|
+
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
bucket = 'itinerarybuilder-demo'
|
2
|
-
|
3
1
|
json.title 'Hover'
|
4
2
|
|
5
3
|
page = json_ui_page json
|
@@ -10,13 +8,12 @@ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
|
|
10
8
|
scroll.p text: 'A popover made with panels_responsive that will be triggered when hovering on its parent'
|
11
9
|
scroll.spacer height: 48
|
12
10
|
|
13
|
-
i = 1
|
14
11
|
scroll.h2 text: 'Responsive'
|
15
12
|
scroll.panels_responsive padding: { top: 48, right: 24, bottom: 48, left: 24 }, styleClasses: ['card'], childViews: ->(column) do
|
16
|
-
column.h2 text:
|
17
|
-
column.p text:
|
13
|
+
column.h2 text: 'Item'
|
14
|
+
column.p text: 'Single responsive view with hover views'
|
18
15
|
end, hoverViews: ->(hover) do
|
19
|
-
render 'json_ui/garage/panels/hover_views_content', hover: hover, i:
|
16
|
+
render 'json_ui/garage/panels/hover_views_content', hover: hover, i: 1
|
20
17
|
end, onClick: ->(action) do
|
21
18
|
action.windows_reload
|
22
19
|
end
|
@@ -24,13 +21,15 @@ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
|
|
24
21
|
|
25
22
|
scroll.h2 text: 'Columns'
|
26
23
|
9.times do |i|
|
27
|
-
scroll.panels_column lg: { cols: 4 }, padding: { top:
|
28
|
-
column.
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
action
|
24
|
+
scroll.panels_column lg: { cols: 4 }, padding: { top: 18, right: 14, bottom: 18, left: 14 }, childViews: ->(column) do
|
25
|
+
column.panels_responsive styleClasses: ['card'], padding: { top: 48, right: 24, bottom: 48, left: 24 }, childViews: ->(responsive) do
|
26
|
+
column.h2 text: "Item #{i}"
|
27
|
+
column.p text: "Hover view with #{i} sentence(s)"
|
28
|
+
end, hoverViews: ->(hover) do
|
29
|
+
render 'json_ui/garage/panels/hover_views_content', hover: hover, i: i
|
30
|
+
end, onClick: ->(action) do
|
31
|
+
action.windows_reload
|
32
|
+
end
|
34
33
|
end
|
35
34
|
end
|
36
35
|
end
|
@@ -33,7 +33,7 @@ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
scroll.spacer height: 32
|
38
38
|
scroll.hr color: '#F5F5F5', width: 'matchParent'
|
39
39
|
scroll.spacer height: 32
|
@@ -59,7 +59,7 @@ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
|
64
64
|
scroll.spacer height: 32
|
65
65
|
scroll.h4 text: 'With more than 12 columns'
|
@@ -74,9 +74,11 @@ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
|
|
74
74
|
|
75
75
|
scroll.spacer height: 32
|
76
76
|
scroll.h4 text: 'With responsive paddings'
|
77
|
+
scroll.spacer height: 4
|
78
|
+
scroll.p text: 'The vertical padding separating these buttons only appears in XS screens.'
|
77
79
|
scroll.spacer height: 8
|
78
80
|
scroll.panels_responsive width: 'matchParent', childViews: ->(res) do
|
79
|
-
res.panels_column lg: { cols: 8, padding: {
|
81
|
+
res.panels_column backgroundColor: '#c3cad2', lg: { cols: 8, padding: { bottom: 0 } }, padding: { bottom: 20 }, childViews: ->(column) do
|
80
82
|
column.button width: 'matchParent', text: '1'
|
81
83
|
end
|
82
84
|
res.panels_column lg: { cols: 4 }, childViews: ->(column) do
|
@@ -84,6 +86,20 @@ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
|
|
84
86
|
end
|
85
87
|
end
|
86
88
|
|
89
|
+
scroll.spacer height: 32
|
90
|
+
scroll.h4 text: 'With responsive ordering'
|
91
|
+
scroll.spacer height: 4
|
92
|
+
scroll.p text: 'In XS screens, button number 2 will be displayed above button 1.'
|
93
|
+
scroll.spacer height: 8
|
94
|
+
scroll.panels_responsive width: 'matchParent', childViews: ->(res) do
|
95
|
+
res.panels_column lg: { cols: 8, order: 0 }, xs: { order: 1 }, childViews: ->(column) do
|
96
|
+
column.button width: 'matchParent', text: '1'
|
97
|
+
end
|
98
|
+
res.panels_column lg: { cols: 4, order: 1 }, xs: { order: 0 }, childViews: ->(column) do
|
99
|
+
column.button width: 'matchParent', text: '2'
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
87
103
|
scroll.spacer height: 32
|
88
104
|
scroll.h4 text: 'With mixed components'
|
89
105
|
scroll.spacer height: 8
|
@@ -105,12 +121,17 @@ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
|
|
105
121
|
scroll.spacer height: 32
|
106
122
|
scroll.h4 text: 'With onClick'
|
107
123
|
scroll.spacer height: 8
|
108
|
-
scroll.panels_responsive
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
124
|
+
scroll.panels_responsive \
|
125
|
+
backgroundColor: '#c3cad2',
|
126
|
+
styleClasses: ['rounded-corner'],
|
127
|
+
padding: { left: 20, right: 20, top: 10, bottom: 10 },
|
128
|
+
tooltip: { text: 'Tooltip text' },
|
129
|
+
childViews: ->(responsive) do
|
130
|
+
responsive.h4 text: 'Heading'
|
131
|
+
responsive.label text: 'Label'
|
132
|
+
end, onClick: ->(action) do
|
133
|
+
action.windows_open url: json_ui_garage_url(path: 'home/blank')
|
134
|
+
end
|
114
135
|
|
115
136
|
scroll.spacer height: 16
|
116
137
|
scroll.h4 text: 'With grid-like functionality'
|
@@ -7,7 +7,7 @@ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
|
|
7
7
|
timeline_items = [
|
8
8
|
{ icon: 'place', color: '#4BB543' },
|
9
9
|
{ icon: 'check_circle', color: 'blue' },
|
10
|
-
{ icon: 'hourglass_empty', color: 'blue',
|
10
|
+
{ icon: 'hourglass_empty', color: 'blue', text: 'Pending' },
|
11
11
|
{ icon: 'radio_button_unchecked' },
|
12
12
|
{ icon: 'radio_button_unchecked' },
|
13
13
|
]
|
@@ -32,16 +32,15 @@ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
|
|
32
32
|
end
|
33
33
|
|
34
34
|
timeline_items = [
|
35
|
-
{ icon: 'place', color: '#4BB543' },
|
36
|
-
{ icon: 'check_circle', color: 'blue' },
|
37
|
-
{ icon: 'check_circle', color: 'blue' },
|
38
|
-
{ icon: 'check_circle', color: 'blue' },
|
39
|
-
{ icon: 'flag', color: '#FFA500' },
|
35
|
+
{ icon: 'place', color: '#4BB543', styleClasses: ['outlined'] },
|
36
|
+
{ icon: 'check_circle', color: 'blue', styleClasses: ['outlined'] },
|
37
|
+
{ icon: 'check_circle', color: 'blue', styleClasses: ['outlined'] },
|
38
|
+
{ icon: 'check_circle', color: 'blue', styleClasses: ['outlined'] },
|
39
|
+
{ icon: 'flag', color: '#FFA500', styleClasses: ['outlined'] },
|
40
40
|
]
|
41
41
|
|
42
42
|
scroll.h2 text: 'Timeline with outlined dots'
|
43
43
|
scroll.panels_timeline \
|
44
|
-
styleClasses: ['outlined'],
|
45
44
|
events: timeline_items,
|
46
45
|
childViews: ->(timeline) do
|
47
46
|
timeline.panels_vertical childViews: ->(vertical) do
|
@@ -74,4 +73,15 @@ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
|
|
74
73
|
timeline.label text: '1 minute ago'
|
75
74
|
end
|
76
75
|
end
|
76
|
+
|
77
|
+
timeline_items = [
|
78
|
+
{ backgroundColor: 'blue', styleClasses: ['small'] },
|
79
|
+
{ backgroundColor: 'blue', styleClasses: ['small'] },
|
80
|
+
{ backgroundColor: 'blue', color: 'white', text: '3' },
|
81
|
+
{ backgroundColor: 'white', icon: 'radio_button_unchecked', styleClasses: ['small'] },
|
82
|
+
{ backgroundColor: 'white', icon: 'radio_button_unchecked', styleClasses: ['small'] },
|
83
|
+
]
|
84
|
+
|
85
|
+
scroll.h2 text: 'Timeline without content'
|
86
|
+
scroll.panels_timeline events: timeline_items
|
77
87
|
end
|
@@ -11,6 +11,18 @@ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
|
|
11
11
|
action.windows_open url: json_ui_garage_url(path: 'home/blank')
|
12
12
|
end
|
13
13
|
ul.label text: 'Label'
|
14
|
+
ul.p text: 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.'
|
15
|
+
|
16
|
+
ul.panels_vertical childViews: ->(vertical) do
|
17
|
+
vertical.p text: 'Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32.'
|
18
|
+
vertical.spacer height: 6
|
19
|
+
vertical.p text: 'The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham.'
|
20
|
+
vertical.spacer height: 6
|
21
|
+
ul.panels_ul childViews: ->(inner_ul) do
|
22
|
+
inner_ul.label text: 'Sub item 1'
|
23
|
+
inner_ul.label text: 'Sub item 2'
|
24
|
+
end
|
25
|
+
end
|
14
26
|
end
|
15
27
|
|
16
28
|
scroll.spacer height: 14
|
@@ -25,9 +37,29 @@ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
|
|
25
37
|
ul.button text: 'Level 1', styleClass: 'link', onClick: ->(action) do
|
26
38
|
action.windows_open url: json_ui_garage_url(path: 'home/blank')
|
27
39
|
end
|
28
|
-
ul.button text: 'Level 2', styleClass: 'link',
|
29
|
-
|
40
|
+
# ul.button text: 'Level 2', styleClass: 'link', childButtons: ->(menu) do
|
41
|
+
# menu.button text: 'Dropdown item 1'
|
42
|
+
# menu.button text: 'Dropdown item 2'
|
43
|
+
# menu.button text: 'Dropdown item 3'
|
44
|
+
# end
|
45
|
+
|
46
|
+
ul.button icon: 'keyboard_arrow_down', text: 'Level 2', styleClass: 'link', childButtons: ->(menu) do
|
47
|
+
menu.button text: 'Dropdown item 1'
|
48
|
+
menu.button text: 'Dropdown item 2'
|
49
|
+
menu.button text: 'Dropdown item 3'
|
30
50
|
end
|
51
|
+
# , onClick: ->(action) do
|
52
|
+
# action.windows_open url: json_ui_garage_url(path: 'home/blank')
|
53
|
+
# end
|
31
54
|
ul.label text: 'Level 3'
|
32
55
|
end
|
56
|
+
|
57
|
+
scroll.button icon: 'keyboard_arrow_down', text: 'Sign in', styleClasses: ['link'], onClick: ->(action) do
|
58
|
+
action.windows_open url: json_ui_garage_url(path: 'home/blank')
|
59
|
+
end
|
60
|
+
scroll.button icon: 'keyboard_arrow_down', text: 'Sign in', styleClass: 'link', childButtons: ->(menu) do
|
61
|
+
menu.button text: 'Dropdown item 1'
|
62
|
+
menu.button text: 'Dropdown item 2'
|
63
|
+
menu.button text: 'Dropdown item 3'
|
64
|
+
end
|
33
65
|
end
|
@@ -40,7 +40,7 @@ json_ui_page json do |page|
|
|
40
40
|
submenu.button icon: 'edit', text: 'Option2', onClick: ->(action) do
|
41
41
|
action.windows_open url: json_ui_garage_url(path: 'home/slow')
|
42
42
|
end
|
43
|
-
submenu.button icon: 'delete', text: 'Option3', onClick: ->(action) do
|
43
|
+
submenu.button icon: 'delete', text: 'Long Option3', onClick: ->(action) do
|
44
44
|
action.dialogs_alert message: 'Alert'
|
45
45
|
end
|
46
46
|
end
|
@@ -25,8 +25,22 @@ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
|
|
25
25
|
onClick: ->(action) do
|
26
26
|
action.dialogs_alert message: 'Perform action'
|
27
27
|
end
|
28
|
-
scroll.spacer height: 20
|
29
28
|
|
29
|
+
scroll.spacer height: 10
|
30
|
+
scroll.button text: 'Button with dropdown', childButtons: ->(menu) do
|
31
|
+
menu.button text: 'Dropdown item 1'
|
32
|
+
menu.button text: 'Dropdown item 2'
|
33
|
+
menu.button text: 'Dropdown item 3'
|
34
|
+
end
|
35
|
+
|
36
|
+
scroll.spacer height: 10
|
37
|
+
scroll.button text: 'Button with tooltip and dropdown', tooltip: { text: 'Tooltip text' }, childButtons: ->(menu) do
|
38
|
+
menu.button text: 'Dropdown item 1'
|
39
|
+
menu.button text: 'Dropdown item 2'
|
40
|
+
menu.button text: 'Dropdown item 3'
|
41
|
+
end
|
42
|
+
|
43
|
+
scroll.spacer height: 20
|
30
44
|
scroll.button \
|
31
45
|
icon: 'info',
|
32
46
|
styleClass: 'icon',
|
@@ -39,7 +53,10 @@ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
|
|
39
53
|
scroll.spacer height: 20
|
40
54
|
scroll.h2 text: 'Chip'
|
41
55
|
scroll.spacer height: 10
|
42
|
-
scroll.chip
|
56
|
+
scroll.chip \
|
57
|
+
styleClass: 'success',
|
58
|
+
text: 'Success',
|
59
|
+
tooltip: { text: 'Tooltip text' }
|
43
60
|
scroll.spacer height: 10
|
44
61
|
scroll.chip text: 'With Action', onClick: ->(action) do
|
45
62
|
action.dialogs_alert message: 'Perform action'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Glib
|
2
|
+
module JsonCrawler
|
3
|
+
class DialogsAlert < ActionCrawler
|
4
|
+
def initialize(http, args, action)
|
5
|
+
super(http)
|
6
|
+
|
7
|
+
if (message = args['message'])
|
8
|
+
http.router.log action, message
|
9
|
+
|
10
|
+
if (on_close = args.fetch('onClose', nil))
|
11
|
+
perform(on_close)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
module Glib
|
3
2
|
module JsonCrawler
|
4
3
|
class FormsSubmit < ActionCrawler
|
@@ -13,15 +12,15 @@ module Glib
|
|
13
12
|
action = "forms/#{method}"
|
14
13
|
|
15
14
|
case method
|
16
|
-
when 'patch', 'put'
|
17
|
-
|
15
|
+
when 'patch', 'put', 'post'
|
16
|
+
submit_form(form, action, method.to_sym)
|
18
17
|
else
|
19
18
|
url = form['url']
|
20
19
|
http.router.log action, url
|
21
20
|
end
|
22
21
|
end
|
23
22
|
|
24
|
-
def
|
23
|
+
def submit_form(view, action, method)
|
25
24
|
url = view['url']
|
26
25
|
fields = []
|
27
26
|
params = {}
|
@@ -37,7 +36,7 @@ module Glib
|
|
37
36
|
@http.router.crawl_multiple child_views, ->(child) do
|
38
37
|
next if child['template'].present?
|
39
38
|
|
40
|
-
name = child['view']
|
39
|
+
name = child['view'] || ''
|
41
40
|
if name.start_with?('fields/')
|
42
41
|
fields << child
|
43
42
|
|
@@ -52,8 +51,30 @@ module Glib
|
|
52
51
|
end
|
53
52
|
end
|
54
53
|
|
55
|
-
|
56
|
-
|
54
|
+
case method
|
55
|
+
when :patch, :put
|
56
|
+
json = @http.patch url, action, params
|
57
|
+
perform(json['onResponse'])
|
58
|
+
when :post
|
59
|
+
if (params = form_post_params)
|
60
|
+
json = @http.post url, action, params
|
61
|
+
perform(json['onResponse'])
|
62
|
+
else
|
63
|
+
@http.router.log action, url
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def form_post_params
|
69
|
+
route = Rails.application.routes.recognize_path(@http.router.page_url)
|
70
|
+
action_path = "#{route[:controller]}##{route[:action]}"
|
71
|
+
|
72
|
+
post_data[action_path]
|
73
|
+
end
|
74
|
+
|
75
|
+
# Redeclare this class and implement this method.
|
76
|
+
def post_data
|
77
|
+
{}
|
57
78
|
end
|
58
79
|
end
|
59
80
|
end
|
@@ -8,7 +8,7 @@ module Glib
|
|
8
8
|
json = @http.get(url, action, args.except('url'))
|
9
9
|
|
10
10
|
unless json.nil?
|
11
|
-
@http.router.begin_page(json)
|
11
|
+
@http.router.begin_page(json, url)
|
12
12
|
|
13
13
|
crawl json['header']&.[]('childViews')
|
14
14
|
crawl json['body']&.[]('childViews')
|
@@ -24,7 +24,7 @@ module Glib
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
if (on_load =
|
27
|
+
if (on_load = args.fetch('onLoad', nil))
|
28
28
|
perform(on_load)
|
29
29
|
end
|
30
30
|
|
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
module Glib
|
3
2
|
module JsonCrawler
|
4
3
|
class Router
|
@@ -25,6 +24,7 @@ module Glib
|
|
25
24
|
# default rails's development host
|
26
25
|
@host ||= 'localhost:3000'
|
27
26
|
@page_specs = []
|
27
|
+
@page_urls = []
|
28
28
|
end
|
29
29
|
|
30
30
|
def step(http, args)
|
@@ -39,7 +39,7 @@ module Glib
|
|
39
39
|
end
|
40
40
|
|
41
41
|
if args.is_a?(Hash) && args['rel'] != 'nofollow'
|
42
|
-
if (on_click =
|
42
|
+
if (on_click = args.fetch('onClick', nil))
|
43
43
|
process_action(http, on_click)
|
44
44
|
end
|
45
45
|
end
|
@@ -74,10 +74,14 @@ module Glib
|
|
74
74
|
when 'forms/submit-v1', 'forms/submit'
|
75
75
|
forms = @visitor.forms
|
76
76
|
JsonCrawler::FormsSubmit.new(http, forms.last)
|
77
|
+
when 'dialogs/alert-v1', 'dialogs/alert'
|
78
|
+
JsonCrawler::DialogsAlert.new(http, params, action)
|
77
79
|
else
|
78
80
|
unless [
|
79
|
-
'http/delete-v1',
|
80
|
-
'
|
81
|
+
'http/delete-v1',
|
82
|
+
'dialogs/oauth-v1',
|
83
|
+
'http/delete',
|
84
|
+
'dialogs/oauth'
|
81
85
|
].include?(action)
|
82
86
|
@read_only_actions.add([action, params['url']])
|
83
87
|
end
|
@@ -99,13 +103,15 @@ module Glib
|
|
99
103
|
@visitor.traverse_multiple views, block
|
100
104
|
end
|
101
105
|
|
102
|
-
def begin_page(spec)
|
106
|
+
def begin_page(spec, url)
|
103
107
|
@page_specs << spec
|
108
|
+
@page_urls << url
|
104
109
|
@visitor.begin_page(spec)
|
105
110
|
end
|
106
111
|
|
107
112
|
def end_page(spec)
|
108
113
|
@page_specs.pop
|
114
|
+
@page_urls.pop
|
109
115
|
@visitor.end_page(spec)
|
110
116
|
end
|
111
117
|
|
@@ -113,6 +119,10 @@ module Glib
|
|
113
119
|
@page_specs.last
|
114
120
|
end
|
115
121
|
|
122
|
+
def page_url
|
123
|
+
@page_urls.last
|
124
|
+
end
|
125
|
+
|
116
126
|
def allowed?(url)
|
117
127
|
regex = Regexp.new("#{host}.+(?<!\.pdf)$")
|
118
128
|
regex.match(url)
|
data/lib/glib/json_crawler.rb
CHANGED
@@ -7,5 +7,6 @@ require_relative './json_crawler/action_crawlers/nav_initiate'
|
|
7
7
|
require_relative './json_crawler/action_crawlers/windows_open'
|
8
8
|
require_relative './json_crawler/action_crawlers/action_http'
|
9
9
|
require_relative './json_crawler/action_crawlers/forms_submit'
|
10
|
+
require_relative './json_crawler/action_crawlers/dialogs_alert'
|
10
11
|
require_relative './json_crawler/action_crawlers/menu'
|
11
12
|
require_relative './json_crawler/action_crawlers/run_multiple'
|
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: 2.
|
4
|
+
version: 2.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ''
|
@@ -202,7 +202,7 @@ files:
|
|
202
202
|
- app/views/json_ui/garage/notifications/android_post.json.jbuilder
|
203
203
|
- app/views/json_ui/garage/notifications/index.json.jbuilder
|
204
204
|
- app/views/json_ui/garage/notifications/web_socket.json.jbuilder
|
205
|
-
- app/views/json_ui/garage/pages/
|
205
|
+
- app/views/json_ui/garage/pages/custom_style_class.json.jbuilder
|
206
206
|
- app/views/json_ui/garage/pages/full_width.json.jbuilder
|
207
207
|
- app/views/json_ui/garage/pages/full_width_height.json.jbuilder
|
208
208
|
- app/views/json_ui/garage/pages/index.json.jbuilder
|
@@ -279,6 +279,7 @@ files:
|
|
279
279
|
- lib/glib/json_crawler.rb
|
280
280
|
- lib/glib/json_crawler/action_crawler.rb
|
281
281
|
- lib/glib/json_crawler/action_crawlers/action_http.rb
|
282
|
+
- lib/glib/json_crawler/action_crawlers/dialogs_alert.rb
|
282
283
|
- lib/glib/json_crawler/action_crawlers/forms_submit.rb
|
283
284
|
- lib/glib/json_crawler/action_crawlers/menu.rb
|
284
285
|
- lib/glib/json_crawler/action_crawlers/nav_initiate.rb
|
@@ -1,29 +0,0 @@
|
|
1
|
-
json.title 'Pages'
|
2
|
-
|
3
|
-
json_ui_page json do |page|
|
4
|
-
render "#{@path_prefix}/nav_menu", json: json, page: page
|
5
|
-
|
6
|
-
page.template 'flatCentered'
|
7
|
-
|
8
|
-
page.header childViews: ->(header) do
|
9
|
-
header.panels_vertical width: 'matchParent', styleClass: 'card', padding: glib_json_padding_body, childViews: ->(vertical) do
|
10
|
-
vertical.h1 text: 'Header'
|
11
|
-
end
|
12
|
-
header.spacer height: 20
|
13
|
-
end
|
14
|
-
|
15
|
-
page.footer childViews: ->(footer) do
|
16
|
-
footer.spacer height: 20
|
17
|
-
footer.panels_vertical width: 'matchParent', styleClass: 'card', padding: glib_json_padding_body, childViews: ->(vertical) do
|
18
|
-
vertical.h1 text: 'Footer'
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
page.body childViews: ->(scroll) do
|
23
|
-
scroll.panels_vertical width: 'matchParent', styleClass: 'card', padding: glib_json_padding_body, childViews: ->(vertical) do
|
24
|
-
(1..100).each do |index|
|
25
|
-
scroll.label text: 'Content'
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|