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.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/concerns/glib/json/libs.rb +10 -4
  3. data/app/controllers/glib/home_controller.rb +20 -0
  4. data/app/helpers/glib/json_ui/action_builder/commands.rb +8 -0
  5. data/app/helpers/glib/json_ui/menu_builder.rb +1 -0
  6. data/app/helpers/glib/json_ui/page_helper.rb +4 -0
  7. data/app/helpers/glib/json_ui/view_builder/fields.rb +3 -1
  8. data/app/helpers/glib/json_ui/view_builder/panels.rb +4 -2
  9. data/app/helpers/glib/json_ui/view_builder.rb +7 -1
  10. data/app/models/concerns/glib/soft_deletable.rb +5 -0
  11. data/app/views/json_ui/garage/_nav_menu.json.jbuilder +10 -0
  12. data/app/views/json_ui/garage/lists/edit_actions.json.jbuilder +16 -6
  13. data/app/views/json_ui/garage/pages/custom_style_class.json.jbuilder +32 -0
  14. data/app/views/json_ui/garage/pages/index.json.jbuilder +4 -4
  15. data/app/views/json_ui/garage/panels/_hover_views_content.json.jbuilder +5 -4
  16. data/app/views/json_ui/garage/panels/hover.json.jbuilder +12 -13
  17. data/app/views/json_ui/garage/panels/responsive.json.jbuilder +30 -9
  18. data/app/views/json_ui/garage/panels/timeline.json.jbuilder +17 -7
  19. data/app/views/json_ui/garage/panels/ul.json.jbuilder +34 -2
  20. data/app/views/json_ui/garage/views/banners.json.jbuilder +1 -1
  21. data/app/views/json_ui/garage/views/controls.json.jbuilder +19 -2
  22. data/app/views/layouts/json_ui/renderer.html.erb +4 -0
  23. data/lib/glib/json_crawler/action_crawlers/dialogs_alert.rb +17 -0
  24. data/lib/glib/json_crawler/action_crawlers/forms_submit.rb +28 -7
  25. data/lib/glib/json_crawler/action_crawlers/windows_open.rb +2 -2
  26. data/lib/glib/json_crawler/router.rb +15 -5
  27. data/lib/glib/json_crawler.rb +1 -0
  28. metadata +3 -2
  29. 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: 7a1aa1166513349077001fdad47d5d2e0df83da63bc55297e7eb40354f56c9d1
4
- data.tar.gz: df6ba1dad3fd78b07e6e121c038609df563eabb56383f0e31ee6a1b5c379a4cb
3
+ metadata.gz: 416ab4888b4ca5e16220519fb9f1dc56999d91be403a2f14c464386f4b586604
4
+ data.tar.gz: b6e8f65a85f9542b9a3a8e865d52a36860d7acb95cdc930918e379b290ba0e66
5
5
  SHA512:
6
- metadata.gz: 0ceba57602f78f46ac76175ae5e449d3192ce91919ab600e242b9f6d7e314e29b65df369c69c289725df48481cdece02b6f6308c1f7267ef22450fa44776d40b
7
- data.tar.gz: ca87f3e87349e24ba0a6674148a13767ab6670d1df3525084932873564987a088543b2d8870b84650e2cea8723432185e4c88df1308cc5fb3a726fa549ec8eaa
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
@@ -4,5 +4,13 @@ class Glib::JsonUi::ActionBuilder
4
4
  string :text
5
5
  action :onCopy
6
6
  end
7
+
8
+ class Custom < Action
9
+ string :name
10
+ hash :properties
11
+ # action :onComplete
12
+ action :onSuccess
13
+ action :onFailure
14
+ end
7
15
  end
8
16
  end
@@ -45,6 +45,7 @@ module Glib
45
45
  icon :icon
46
46
  action :onClick
47
47
  bool :disabled
48
+ hash :tooltip
48
49
  singleton_array :styleClass, :styleClasses
49
50
 
50
51
  def childButtons(block)
@@ -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
- string :produce # `html` or `markdown`
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 styleClass: 'icon', icon: 'share', onClick: ->(subaction) do
21
- subaction.dialogs_alert message: 'Share'
22
- end
23
- menu.button styleClass: 'icon', icon: 'open_in_new', onClick: ->(subaction) do
24
- subaction.dialogs_alert message: 'Open'
25
- end
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
- i.times { value += text}
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: "Item #{i}"
17
- column.p text: "Hover view with #{i} sentence(s)"
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: 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: 48, right: 24, bottom: 48, left: 24 }, styleClasses: ['card'], childViews: ->(column) do
28
- column.h2 text: "Item #{i}"
29
- column.p text: "Hover view with #{i} sentence(s)"
30
- end, hoverViews: ->(hover) do
31
- render 'json_ui/garage/panels/hover_views_content', hover: hover, i: i
32
- end, onClick: ->(action) do
33
- action.windows_reload
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: { right: 20 } }, childViews: ->(column) do
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 backgroundColor: '#c3cad2', padding: { left: 20, right: 20, top: 10, bottom: 10 }, childViews: ->(responsive) do
109
- responsive.h4 text: 'Heading'
110
- responsive.label text: 'Label'
111
- end, onClick: ->(action) do
112
- action.windows_open url: json_ui_garage_url(path: 'home/blank')
113
- end
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', label: 'Pending' },
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', onClick: ->(action) do
29
- action.windows_open url: json_ui_garage_url(path: 'home/blank')
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 styleClass: 'success', text: 'Success'
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'
@@ -19,6 +19,10 @@
19
19
  <link href="//cdn.materialdesignicons.com/2.1.99/css/materialdesignicons.min.css" rel="stylesheet" />
20
20
 
21
21
  <%= yield :head %>
22
+
23
+ <% if @__glib_head_code %>
24
+ <%= @__glib_head_code.html_safe %>
25
+ <% end %>
22
26
  </head>
23
27
 
24
28
  <body>
@@ -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
- submit_update(form, action)
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 submit_update(view, action)
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
- json = @http.patch url, action, params
56
- perform(json['onResponse'])
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 = (args.fetch('onLoad', nil)))
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 = (args.fetch('onClick', nil)))
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', 'dialogs/oauth-v1',
80
- 'http/delete', 'dialogs/oauth'
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)
@@ -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.2.0
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/flat_centered.json.jbuilder
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