glib-web 0.5.12 → 0.5.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +5 -5
  2. data/app/controllers/concerns/glib/json/traversal.rb +2 -1
  3. data/app/helpers/glib/json_ui/action_builder.rb +10 -0
  4. data/app/helpers/glib/json_ui/list_builders.rb +18 -4
  5. data/app/helpers/glib/json_ui/page_helper.rb +6 -0
  6. data/app/helpers/glib/json_ui/response_helper.rb +0 -0
  7. data/app/helpers/glib/json_ui/view_builder/fields.rb +1 -0
  8. data/app/helpers/glib/json_ui/view_builder/panels.rb +13 -0
  9. data/app/views/json_ui/garage/_nav_menu.json.jbuilder +0 -1
  10. data/app/views/json_ui/garage/actions/_http.json.jbuilder +9 -3
  11. data/app/views/json_ui/garage/actions/_sheets.json.jbuilder +0 -1
  12. data/app/views/json_ui/garage/actions/index.json.jbuilder +0 -0
  13. data/app/views/json_ui/garage/forms/dynamic_group.json.jbuilder +31 -16
  14. data/app/views/json_ui/garage/lists/{_infinite_scroll_section.json.jbuilder → _autoload_section.json.jbuilder} +4 -2
  15. data/app/views/json_ui/garage/lists/autoload_all.json.jbuilder +32 -0
  16. data/app/views/json_ui/garage/lists/{infinite_scroll.json.jbuilder → autoload_as_needed.json.jbuilder} +9 -12
  17. data/app/views/json_ui/garage/lists/chat_ui.json.jbuilder +96 -0
  18. data/app/views/json_ui/garage/lists/edit_actions.json.jbuilder +25 -1
  19. data/app/views/json_ui/garage/lists/fab.json.jbuilder +6 -8
  20. data/app/views/json_ui/garage/lists/index.json.jbuilder +9 -3
  21. data/app/views/json_ui/garage/notifications/android_post.json.jbuilder +56 -0
  22. data/app/views/json_ui/garage/notifications/index.json.jbuilder +11 -0
  23. data/app/views/json_ui/garage/tables/_autoload_section.json.jbuilder +6 -2
  24. data/app/views/json_ui/garage/tables/autoload_all.json.jbuilder +15 -10
  25. data/app/views/json_ui/garage/tables/autoload_as_needed.json.jbuilder +13 -2
  26. data/app/views/json_ui/garage/tables/index.json.jbuilder +3 -3
  27. data/app/views/json_ui/garage/views/banners.json.jbuilder +3 -3
  28. data/app/views/json_ui/garage/views/icons.json.jbuilder +1439 -11
  29. data/app/views/json_ui/garage/views/index.json.jbuilder +6 -3
  30. data/app/views/layouts/json_ui/renderer.html.erb +7 -4
  31. data/lib/generators/templates/20191024063257_add_scope_to_texts.rb +1 -1
  32. data/lib/generators/templates/20191126071051_create_active_storage_tables.active_storage.rb +1 -1
  33. data/lib/generators/templates/dynamic_text.rb +1 -1
  34. data/lib/glib-web.rb +5 -5
  35. data/lib/glib/engine.rb +1 -1
  36. data/lib/glib/json_crawler/action_crawlers/forms_submit.rb +4 -4
  37. data/lib/glib/json_crawler/http.rb +1 -1
  38. data/lib/glib/test_helpers.rb +3 -3
  39. data/lib/glib/value.rb +1 -1
  40. data/lib/glib/version.rb +2 -2
  41. data/lib/tasks/db.rake +11 -11
  42. metadata +7 -5
  43. data/app/views/app/views/json_ui/vue/renderer.html.erb +0 -35
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 811686b2291bc31023b9d5980a6cb54cc2a97a26
4
- data.tar.gz: 8f6ed8e3d277ca3c29190bcfe07d99c687c9e90c
2
+ SHA256:
3
+ metadata.gz: 481c51fde9d25ee4f8b4470c126f26c957c04209acdb37b1a52db6faecba9f4e
4
+ data.tar.gz: d2258e2069c804b9ad232bb157c657260352bdf3eabab1342562040f165c1ffa
5
5
  SHA512:
6
- metadata.gz: 79af3fc3c2d8bb48ce3913735bcaac0722a515a588cba5373c80dd41f9cdef0963fcf64f58c28c84ccd81c0fe0e158d83c4476dec7b9b9bc7703952770b8cb26
7
- data.tar.gz: 9738ce65f40301d15622da0617cb94795fdf90ceacb1e32066cfaa372ba7f7b1b45eb1e7b1494c6a25d2d68b43637f28cc96e46c2621aab80cbea827930e889e
6
+ metadata.gz: cc9c9bb53e07b9ef3031167aa3f72d901e2b07098ee4a90f285969c2fc1ee548d966c2947a165fd3c519f8d0cbad13cebc3c7e70498d90cbdc4db220c3a4ad92
7
+ data.tar.gz: 9b5fc5e2d30f03fe433425f3d4594eb0acfb3bb48774a73e161feae7bca2ea87cae450a291a32a29fd1b4acfcfdf057752be9e0c04386b570bb59ea925a24fec
@@ -76,8 +76,9 @@ module Glib::Json::Traversal
76
76
  # Table/List
77
77
  if (sections = view['sections']).is_a? Array
78
78
  sections.each do |section|
79
- # Table
79
+ traverse_vertical_content section['header'], block
80
80
  traverse_multiple section['rows'], block
81
+ traverse_vertical_content section['footer'], block
81
82
  end
82
83
  end
83
84
  end
@@ -66,6 +66,16 @@ module Glib
66
66
  string :token
67
67
  action :onSave
68
68
  end
69
+
70
+ class Restart < Action
71
+ end
72
+ end
73
+
74
+ module Devices
75
+ class GetPushToken < Action
76
+ action :onGet
77
+ string :paramNameForToken
78
+ end
69
79
  end
70
80
 
71
81
  module Analytics
@@ -7,7 +7,11 @@ module Glib
7
7
  end
8
8
 
9
9
  class AbstractTemplate < JsonUiElement
10
- # hash :padding
10
+ # def contextButtons(block)
11
+ # json.contextButtons do
12
+ # block.call page.menu_builder
13
+ # end
14
+ # end
11
15
 
12
16
  def editButtons(block)
13
17
  json.editButtons do
@@ -22,12 +26,13 @@ module Glib
22
26
  end
23
27
  end
24
28
 
25
- class Thumbnail < AbstractTemplate
29
+ class Standard < AbstractTemplate
26
30
  string :title
27
31
  string :subtitle
28
32
  string :subsubtitle
29
33
  string :imageUrl
30
34
  action :onClick
35
+ action :onLongPress
31
36
  icon :icon
32
37
  bool :avatar
33
38
 
@@ -36,10 +41,19 @@ module Glib
36
41
  # views :accessoryViews
37
42
  end
38
43
 
39
- class Featured < Thumbnail
44
+ class Featured < Standard
40
45
  end
41
46
 
42
- class Custom < Thumbnail
47
+ class Thumbnail < Standard
48
+ end
49
+
50
+ class CommentOutgoing < Standard
51
+ end
52
+
53
+ class CommentIncoming < Standard
54
+ end
55
+
56
+ class Custom < Standard
43
57
  string :template
44
58
 
45
59
  # TODO: Experimental
@@ -45,6 +45,12 @@ module Glib
45
45
  @__json_ui_section.action_builder
46
46
  end
47
47
 
48
+ def json_ui_action_payload(&block)
49
+ dataJson = Jbuilder.new
50
+ block&.call Page.new(dataJson, self).action_builder
51
+ dataJson.attributes!
52
+ end
53
+
48
54
  class Page
49
55
  attr_reader :json, :context, :view_builder, :action_builder, :menu_builder
50
56
  attr_reader :list_section_builder, :table_section_builder, :drawer_content_builder, :split_content_builder
@@ -157,6 +157,7 @@ class Glib::JsonUi::ViewBuilder
157
157
  class DynamicGroup < AbstractField
158
158
  string :titlePrefix
159
159
  panels_builder :content, :template
160
+ hash :groupFieldProperties
160
161
 
161
162
  # NOTE: Consider using sub-panel instead (e.g. groupTemplate)
162
163
  # views :groupTemplateViews
@@ -164,6 +164,19 @@ class Glib::JsonUi::ViewBuilder
164
164
  hash :md
165
165
  hash :sm
166
166
  hash :xs
167
+
168
+ hash :xlOnly
169
+ hash :lgOnly
170
+ hash :mdOnly
171
+ hash :smOnly
172
+ hash :xsOnly
173
+
174
+ hash :xlAndDown
175
+ hash :lgAndDown
176
+ hash :mdAndDown
177
+ hash :smAndDown
178
+ hash :xsAndDown
179
+
167
180
  views :childViews
168
181
  end
169
182
 
@@ -1,6 +1,5 @@
1
1
 
2
2
  if local_assigns[:top_nav] || json_ui_app_is_web?
3
-
4
3
  page.leftDrawer content: ->(drawer) do
5
4
  drawer.header childViews: ->(header) do
6
5
  header.button text: 'App', styleClasses: ['link', 'logo'], onClick: ->(action) do
@@ -5,14 +5,20 @@ end
5
5
 
6
6
  section.rows builder: ->(template) do
7
7
  template.thumbnail title: 'http/post', onClick: ->(action) do
8
- action.http_post url: json_ui_garage_url(path: 'forms/basic_post'), formData: { 'user[name]' => 'New Joe' }
8
+ action.auth_saveCsrfToken token: form_authenticity_token, onSave: ->(subaction) do
9
+ subaction.http_post url: json_ui_garage_url(path: 'forms/basic_post'), formData: { 'user[name]' => 'New Joe' }
10
+ end
9
11
  end
10
12
 
11
13
  template.thumbnail title: 'http/patch', onClick: ->(action) do
12
- action.http_patch url: json_ui_garage_url(path: 'forms/basic_post'), formData: { 'user[name]' => 'Edit Joe' }
14
+ action.auth_saveCsrfToken token: form_authenticity_token, onSave: ->(subaction) do
15
+ subaction.http_patch url: json_ui_garage_url(path: 'forms/basic_post'), formData: { 'user[name]' => 'Edit Joe' }
16
+ end
13
17
  end
14
18
 
15
19
  template.thumbnail title: 'http/delete', onClick: ->(action) do
16
- action.http_delete url: json_ui_garage_url(path: 'forms/basic_post'), formData: { 'user[name]' => 'Delete Joe' }
20
+ action.auth_saveCsrfToken token: form_authenticity_token, onSave: ->(subaction) do
21
+ subaction.http_delete url: json_ui_garage_url(path: 'forms/basic_post'), formData: { 'user[name]' => 'Delete Joe' }
22
+ end
17
23
  end
18
24
  end
@@ -12,7 +12,6 @@ section.rows builder: ->(template) do
12
12
  menu.button text: 'Option2', onClick: ->(subaction) do
13
13
  subaction.dialogs_alert message: 'Option 2'
14
14
  end
15
- menu.button text: 'Cancel'
16
15
  end
17
16
  end
18
17
 
@@ -7,23 +7,38 @@ json_ui_page json do |page|
7
7
  form.h2 text: 'Dynamic Group'
8
8
  form.spacer height: 6
9
9
 
10
- value = [
11
- {
12
- 'question': 'Punctuality',
13
- 'type': 'rating',
14
- 'enabled': '1'
15
- },
16
- {
17
- 'question': 'Quality of work',
18
- 'type': 'rating'
19
- },
20
- {
21
- 'question': 'Satisfied?',
22
- 'type': 'yes_no'
23
- }
24
- ]
10
+ # value = [
11
+ # {
12
+ # 'question': 'Punctuality',
13
+ # 'type': 'rating'
14
+ # },
15
+ # {
16
+ # 'question': 'Quality of work',
17
+ # 'type': 'rating',
18
+ # 'enabled': '1'
19
+ # },
20
+ # {
21
+ # 'question': 'Satisfied?',
22
+ # 'type': 'yes_no'
23
+ # }
24
+ # ]
25
25
 
26
- form.fields_dynamicGroup width: 'matchParent', name: 'user[evaluation]', value: value, titlePrefix: 'Entry', content: ->(group) do
26
+ properties = [
27
+ [
28
+ { name: 'question', value: 'Punctuality' },
29
+ { name: 'type', value: 'rating' },
30
+ ],
31
+ [
32
+ { name: 'question', value: 'Quality of work' },
33
+ { name: 'type', value: 'rating' },
34
+ { name: 'enabled', value: '1', styleClasses: ['success'] },
35
+ ],
36
+ [
37
+ { name: 'question', value: 'Satisfied?' },
38
+ { name: 'type', value: 'yes_no' },
39
+ ]
40
+ ]
41
+ form.fields_dynamicGroup width: 'matchParent', name: 'user[evaluation]', groupFieldProperties: properties, titlePrefix: 'Entry', content: ->(group) do
27
42
  group.template padding: { left: 32 }, childViews: ->(template) do
28
43
  template.spacer height: 10
29
44
  template.fields_text width: 'matchParent', name: 'question', label: 'Question', placeholder: 'Question'
@@ -10,11 +10,13 @@
10
10
  # end
11
11
  # end
12
12
 
13
- section = json_ui_section json
13
+ # section = json_ui_section json
14
+
15
+ section = page.list_section_builder
14
16
  section.rows builder: ->(row) do
15
17
  batch_count = 30
16
18
  batch_count.times do |i|
17
- index = page * batch_count + i
19
+ index = page_index * batch_count + i
18
20
  row.thumbnail title: "Item #{index}"
19
21
  end
20
22
  end
@@ -0,0 +1,32 @@
1
+
2
+ page_index = params[:page].to_i
3
+ next_page = {
4
+ url: json_ui_garage_url(path: 'lists/autoload_all', page: page_index + 1, section_only: 'v1'),
5
+ autoload: 'all'
6
+ }
7
+
8
+ page = json_ui_page json
9
+
10
+ if params[:section_only].present?
11
+ sleep 1
12
+
13
+ json.nextPage next_page if page_index < 3
14
+ json.sections do
15
+ json.child! do
16
+ render 'json_ui/garage/lists/autoload_section', page: page, page_index: page_index
17
+ end
18
+ end
19
+ else
20
+ json.title 'Lists'
21
+
22
+ render "#{@path_prefix}/nav_menu", json: json, page: page
23
+
24
+ page.list nextPage: next_page, firstSection: ->(section) do
25
+ render 'json_ui/garage/lists/autoload_section', page: page, page_index: page_index
26
+ end, onScrollToBottom: ->(action) do
27
+ action.snackbars_alert message: 'Scrolled to Bottom'
28
+ end, onScrollToTop: ->(action) do
29
+ action.snackbars_alert message: 'Scrolled to Top'
30
+ end
31
+
32
+ end
@@ -1,34 +1,31 @@
1
1
 
2
2
  page_index = params[:page].to_i
3
3
  next_page = {
4
- url: json_ui_garage_url(path: 'lists/infinite_scroll', page: page_index + 1, section_only: 'v1'),
5
- # TODO: rename, e.g. autoloadAsNeeded vs autoloadAll
6
- autoLoad: true
4
+ url: json_ui_garage_url(path: 'lists/autoload_as_needed', page: page_index + 1, section_only: 'v1'),
5
+ autoload: 'asNeeded'
7
6
  }
8
7
 
8
+ page = json_ui_page json
9
+
9
10
  # TODO: Cater
10
11
  # - for SEO: one URL for a standalone page and one URL for pagination only
11
12
  # - for generic approach, e.g. excluding nav_menu when there is no change
12
13
  if params[:section_only].present?
13
- json.nextPage next_page
14
+ sleep 1
15
+
16
+ json.nextPage next_page if page_index < 3
14
17
  json.sections do
15
18
  json.child! do
16
- render 'json_ui/garage/lists/infinite_scroll_section', json: json, page: page_index
19
+ render 'json_ui/garage/lists/autoload_section', page: page, page_index: page_index
17
20
  end
18
21
  end
19
22
  else
20
23
  json.title 'Lists'
21
24
 
22
- # options = { nextPage: nextPage }
23
- # json_body_with_list json, nil, nil, options do
24
- # render 'json_ui/garage/lists/infinite_scroll_section', json: json, page: page
25
- # end
26
-
27
- page = json_ui_page json
28
25
  render "#{@path_prefix}/nav_menu", json: json, page: page
29
26
 
30
27
  page.list nextPage: next_page, firstSection: ->(section) do
31
- render 'json_ui/garage/lists/infinite_scroll_section', json: json, page: page_index
28
+ render 'json_ui/garage/lists/autoload_section', page: page, page_index: page_index
32
29
  end, onScrollToBottom: ->(action) do
33
30
  action.snackbars_alert message: 'Scrolled to Bottom'
34
31
  end, onScrollToTop: ->(action) do
@@ -0,0 +1,96 @@
1
+ json.title 'Lists'
2
+
3
+ liked = params[:liked] == 'true'
4
+
5
+ page = json_ui_page json
6
+ render "#{@path_prefix}/nav_menu", json: json, page: page
7
+
8
+ page.list firstSection: ->(section) do
9
+ section.header padding: { top: 12, left: 16, right: 16, bottom: 12 }, childViews: ->(header) do
10
+ header.h3 text: 'Chat with John Doe'
11
+ end
12
+
13
+ section.rows builder: ->(template) do
14
+ # template.thumbnail title: "windows/reload (timestamp: #{DateTime.current.to_i}) -- #{liked}", onClick: ->(action) do
15
+ # action.windows_reload
16
+ # end, onLongPress: ->(action) do
17
+ # action.sheets_select message: "Context Menu (#{DateTime.current.to_i})", buttons: ->(menu) do
18
+ # if liked
19
+ # menu.button text: 'Cancel 👍', onClick: ->(subaction) do
20
+ # subaction.windows_reload url: json_ui_garage_url(path: 'lists/chat', liked: false)
21
+ # end
22
+ # else
23
+ # menu.button text: 'Give 👍', onClick: ->(subaction) do
24
+ # subaction.windows_reload url: json_ui_garage_url(path: 'lists/chat', liked: true)
25
+ # end
26
+ # end
27
+ # end
28
+ # end
29
+
30
+ template.commentOutgoing subtitle: 'Hey!', subsubtitle: l(10.minutes.ago, format: :short), imageUrl: glib_json_image_standard_url, chips: ->(menu) do
31
+ menu.button text: '😊 2', styleClass: 'info'
32
+ end
33
+
34
+ template.commentOutgoing subtitle: 'How are you?', subsubtitle: l(DateTime.current, format: :short)
35
+
36
+ template.commentIncoming title: 'John Doe', subtitle: 'Very well', subsubtitle: l(7.minutes.ago, format: :short), imageUrl: glib_json_image_standard_url, chips: ->(menu) do
37
+ menu.button text: "👍 #{liked ? 2 : 1}"
38
+ end, onLongPress: ->(action) do
39
+ action.sheets_select message: 'Context Menu', buttons: ->(menu) do
40
+ if liked
41
+ menu.button text: 'Cancel 👍', onClick: ->(subaction) do
42
+ subaction.windows_reload url: json_ui_garage_url(path: 'lists/chat_ui', liked: false)
43
+ end
44
+ else
45
+ menu.button text: 'Give 👍', onClick: ->(subaction) do
46
+ subaction.windows_reload url: json_ui_garage_url(path: 'lists/chat_ui', liked: true)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ page.footer padding: { top: 12, left: 16, right: 16, bottom: 12 }, childViews: ->(footer) do
55
+ # json.ws({
56
+ # "socket" => {
57
+ # "endpoint" => "/socket/websocket",
58
+ # "params" => {
59
+ # vsn: '2.0.0',
60
+ # token: 'TOKEN'
61
+ # }
62
+ # },
63
+ # # "topic" => "room:30",
64
+ # # "event" => "comments_updated",
65
+ # "topic" => "links",
66
+ # "events" => ["new_link_added"],
67
+ # "header" => {
68
+ # "user_id" => 2,
69
+ # "prev_item_id" => nil,
70
+ # "last_item_id" => nil
71
+ # }
72
+ # })
73
+
74
+ footer.panels_form width: 'matchParent', url: json_ui_garage_url(path: 'forms/basic_post'), method: 'post', padding: glib_json_padding_body, paramNameForFormData: 'formData', onSubmit: ->(action) do
75
+ json.action "ws/push"
76
+ json.topic "links"
77
+ json.event "new_link"
78
+ json.payload({
79
+ "club_id": "2",
80
+ "room_id": "30",
81
+ "user_id": "2"
82
+ # title: "TITLE",
83
+ # url: "URL"
84
+ })
85
+
86
+ end, childViews: ->(form) do
87
+ form.fields_text name: 'message[body]', width: 'matchParent', label: 'Message'
88
+
89
+ form.panels_split width: 'matchParent', content: ->(split) do
90
+ split.right childViews: ->(right) do
91
+ right.button text: 'Submit', onClick: ->(action) { action.forms_submit }
92
+ end
93
+ end
94
+ end
95
+
96
+ end
@@ -2,7 +2,7 @@ json.title 'Lists'
2
2
 
3
3
  json_ui_page json do |page|
4
4
  render "#{@path_prefix}/nav_menu", json: json, page: page
5
-
5
+
6
6
  page.list firstSection: ->(section) do
7
7
  section.rows builder: ->(template) do
8
8
  template.thumbnail title: 'Click menu (web) or swipe left (Android/iOS)', editButtons: ->(menu) do
@@ -13,6 +13,30 @@ json_ui_page json do |page|
13
13
  action.dialogs_alert message: 'Perform action'
14
14
  end
15
15
  end
16
+
17
+ template.thumbnail title: 'Long press to get an alert', onLongPress: ->(action) do
18
+ action.dialogs_alert message: 'This is an alert'
19
+ end
20
+
21
+ template.thumbnail title: 'Long press to see menu', onLongPress: ->(action) do
22
+ action.sheets_select message: 'Context Menu', buttons: ->(menu) do
23
+ menu.button icon: 'edit', text: 'Edit', onClick: ->(subaction) do
24
+ subaction.dialogs_alert message: 'Perform action'
25
+ end
26
+ menu.button icon: 'delete', text: 'Delete', onClick: ->(subaction) do
27
+ subaction.dialogs_alert message: 'Perform action'
28
+ end
29
+ end
30
+ end
31
+
32
+ # template.thumbnail title: 'Long press to see menu', contextButtons: ->(menu) do
33
+ # menu.button text: 'Edit', onClick: ->(action) do
34
+ # action.dialogs_alert message: 'Perform action'
35
+ # end
36
+ # menu.button text: 'Delete', onClick: ->(action) do
37
+ # action.dialogs_alert message: 'Perform action'
38
+ # end
39
+ # end
16
40
  end
17
41
 
18
42
  end