glib-web 4.4.1 → 4.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 324be9293b997d23666ea14d20515bb5e8aef6e7fa962f4cf1ccba6ade3d6d1e
4
- data.tar.gz: 0b4a0e7f36dfb0e6cbac8f83dbc904451d1c59e02d212b5a6c2af4bda8e8c092
3
+ metadata.gz: df493fd28bb7b0ab3a3e2c7ae79e407b6f5b0b5b349366c75729f351e4b36553
4
+ data.tar.gz: 1bbc544c5ba2c4cd077c92bbe527ef4e82685dcf82b276860484ec4691cc9640
5
5
  SHA512:
6
- metadata.gz: 752f7e4b42626d97625f169b933a9e44eb6d968a54c3adfc0945434e785a2d0ef03daf7708cd63f36cb28c6f6e235d3eb5e0cc491abd9ad10da3e377fcdeabd4
7
- data.tar.gz: 7b9d408aeff03b974f026a26c96128569d0976f2d5bd4745cebaa0c3877a652fc335dc03e62b2ab3949c7dbff53a922b8462243b2f4a1bcc83df19b29409c515
6
+ metadata.gz: 6a9f5f652188581b59f5639bbcad5fe805a03c1094c9818d39c57dbfeb64cd9db8c0909df7006c81ca5e3815223a9141a462190d683761b57d95cd424a0b64bc
7
+ data.tar.gz: ad14b2561f8f8948430168cfd1551f0db4b8fbda6111dbc9b14db696eb05bf2f46d50c5460521267888109cb8cf9c0b0ebbf90e2779e6424318d171fe59b5a53
@@ -84,9 +84,10 @@ module Glib
84
84
  class Standard < JsonUiElement
85
85
  string :id
86
86
  string :title
87
+ string :subtitle
87
88
  action :onClick
88
89
  hash :dropData
89
- hash :icon, required: [:name], optional: [:color]
90
+ hash :icon, required: [:name], optional: [:color, :size]
90
91
  array :rows
91
92
  end
92
93
  end
@@ -21,6 +21,7 @@ module Glib
21
21
  action :onClick
22
22
  array :colSpans
23
23
  array :colStyles
24
+ hash :dragData
24
25
  end
25
26
  end
26
27
 
@@ -117,6 +117,7 @@ class Glib::JsonUi::ViewBuilder
117
117
  string :rightText
118
118
  action :onTypeStart
119
119
  action :onTypeEnd
120
+ bool :clearable
120
121
  end
121
122
 
122
123
  class Number < Text
@@ -197,6 +198,18 @@ class Glib::JsonUi::ViewBuilder
197
198
  hash :append, optional: [:icon]
198
199
 
199
200
  panels_builder :accessory, :header, :footer
201
+ bool :clearable
202
+
203
+ def searchable(value)
204
+ @searchable = value
205
+ end
206
+
207
+ def created
208
+ super
209
+
210
+ @searchable = @searchable.nil? ? true : @searchable
211
+ json.set! 'searchable', @searchable
212
+ end
200
213
  end
201
214
 
202
215
  class ChipGroup < AbstractField
@@ -207,7 +220,7 @@ class Glib::JsonUi::ViewBuilder
207
220
 
208
221
  class TimeZone < AbstractField
209
222
  include Glib::EnumHelper
210
-
223
+ bool :clearable
211
224
  # Override
212
225
  def created
213
226
  super
@@ -273,13 +286,6 @@ class Glib::JsonUi::ViewBuilder
273
286
  string :onIcon
274
287
  hash :image, required: [:url, :template], optional: [:width, :height]
275
288
  hash :icon, required: [:name, :template], optional: [:color, :size]
276
- # bool :featured
277
- # bool :thumbnail
278
- # hash :image
279
- # string :imageUrl
280
- # string :icon
281
- # string :iconColor
282
- # string :iconSize
283
289
 
284
290
  views :childViews
285
291
  end
@@ -411,6 +417,7 @@ class Glib::JsonUi::ViewBuilder
411
417
  date :min
412
418
  date :max
413
419
  string :type
420
+ bool :clearable
414
421
 
415
422
  # Override
416
423
  def value(value)
@@ -423,6 +430,7 @@ class Glib::JsonUi::ViewBuilder
423
430
  class Datetime < AbstractField
424
431
  date_time :min
425
432
  date_time :max
433
+ bool :clearable
426
434
  end
427
435
 
428
436
  class Location < AbstractField
@@ -448,6 +456,7 @@ class Glib::JsonUi::ViewBuilder
448
456
  class Phone < AbstractField
449
457
  string :defaultCountry
450
458
  bool :disableAutoDetect
459
+ bool :clearable
451
460
  end
452
461
 
453
462
  class CreditCard < AbstractField
@@ -428,7 +428,8 @@ class Glib::JsonUi::ViewBuilder
428
428
  include Glib::JsonUi::Upload
429
429
 
430
430
  string :selected
431
- action :onDrop
431
+ action :onDropFile
432
+ action :onDropView
432
433
 
433
434
  def sections(blocks)
434
435
  json.sections do
@@ -175,6 +175,8 @@ module Glib
175
175
  string :url
176
176
  string :base64Data
177
177
  action :onClick
178
+ color :backgroundColor
179
+ hash :initials, required: [:text], optional: [:color]
178
180
  end
179
181
 
180
182
  class Icon < View
@@ -20,6 +20,7 @@ page.form url: json_ui_garage_url(path: 'forms/generic_post'), method: 'post', p
20
20
  form.fields_select \
21
21
  name: 'user[city]',
22
22
  width: 'matchParent',
23
+ clearable: true,
23
24
  label: 'City1',
24
25
  placeholder: 'This is a placeholder',
25
26
  options: languages.map { |k, v| { value: k, text: v } },
@@ -147,7 +148,7 @@ page.form url: json_ui_garage_url(path: 'forms/generic_post'), method: 'post', p
147
148
  form.spacer height: 6
148
149
  form.label text: 'The select field defaults to the device\'s time zone.'
149
150
  form.spacer height: 6
150
- form.fields_timeZone name: 'user[time_zone]', width: 'matchParent', label: 'Time Zone'
151
+ form.fields_timeZone name: 'user[time_zone]', width: 'matchParent', label: 'Time Zone', clearable: true
151
152
 
152
153
 
153
154
  form.button text: 'Submit', onClick: ->(action) { action.forms_submit }
@@ -20,26 +20,30 @@ page.form \
20
20
  form.fields_email \
21
21
  name: 'user[email]',
22
22
  width: 'matchParent',
23
- label: 'Email'
23
+ label: 'Email',
24
+ clearable: true
24
25
  form.spacer height: 8
25
26
 
26
27
  form.fields_url \
27
28
  name: 'user[url]',
28
29
  width: 'matchParent',
29
- label: 'URL'
30
+ label: 'URL',
31
+ clearable: true
30
32
  form.spacer height: 8
31
33
 
32
34
  form.fields_number \
33
35
  prop: :age,
34
36
  name: 'user[age]',
35
37
  width: 'matchParent',
36
- label: 'Age'
38
+ label: 'Age',
39
+ clearable: true
37
40
  form.spacer height: 8
38
41
 
39
42
  form.fields_phone \
40
43
  name: 'user[phone1]',
41
44
  width: 'matchParent',
42
- label: 'Phone field'
45
+ label: 'Phone field',
46
+ clearable: true
43
47
  form.spacer height: 8
44
48
 
45
49
  form.fields_phone \
@@ -55,7 +59,8 @@ page.form \
55
59
  width: 'matchParent',
56
60
  label: 'Password',
57
61
  hint: 'Should contain at least 6 characters',
58
- leftIcon: 'lock'
62
+ leftIcon: 'lock',
63
+ clearable: true
59
64
  form.spacer height: 8
60
65
 
61
66
  form.fields_textarea \
@@ -63,7 +68,8 @@ page.form \
63
68
  name: 'user[words]',
64
69
  width: 'matchParent',
65
70
  label: 'Textarea with maxLength',
66
- maxLength: 1000
71
+ maxLength: 1000,
72
+ clearable: true
67
73
  form.spacer height: 8
68
74
 
69
75
 
@@ -73,7 +79,8 @@ page.form \
73
79
  name: 'user[position]',
74
80
  width: 'matchParent',
75
81
  label: 'Position',
76
- options: options
82
+ options: options,
83
+ clearable: true
77
84
  form.spacer height: 8
78
85
 
79
86
 
@@ -1,5 +1,14 @@
1
1
  json.title 'Panels'
2
2
 
3
+ onDropFile = ->(action) do
4
+ action.files_upload directUploadUrl: glib_direct_uploads_url, onFinished: ->(saction) do
5
+ saction.http_post url: json_ui_garage_url(path: 'forms/generic_post_all')
6
+ end
7
+ end
8
+ onDropView = ->(action) do
9
+ action.http_post url: json_ui_garage_url(path: 'forms/generic_post_all')
10
+ end
11
+
3
12
  json_ui_page json do |page|
4
13
  render "#{@path_prefix}/nav_menu", json: json, page: page
5
14
 
@@ -7,64 +16,91 @@ json_ui_page json do |page|
7
16
  scroll.h2 text: 'Standard'
8
17
  scroll.spacer height: 4
9
18
 
10
- scroll.panels_tree selected: params[:selected] || 'arabian-1.mp3', width: 300, sections: [
11
- ->(section) do
12
- section.header childViews: ->(header) do
13
- header.h2 text: 'Music 🎶'
14
- end
19
+ scroll.panels_column md: { cols: 4 }, childViews: ->(col) do
20
+ scroll.panels_tree \
21
+ onDropFile: onDropFile,
22
+ onDropView: onDropView,
23
+ selected: params[:selected] || 'arabian-1.mp3',
24
+ width: 300,
25
+ sections: [
26
+ ->(section) do
27
+ section.header childViews: ->(header) do
28
+ header.h2 text: 'Music 🎶'
29
+ end
15
30
 
16
- section.rows builder: ->(template) do
17
- template.standard id: 'pop', title: 'Pop', rows: ['pop-1.mp3', 'pop-2.mp3', 'pop-3.mp3']
18
- template.standard id: 'arab', title: 'Arabian', rows: ['arabian-1.mp3', 'arabian-2.mp3', 'arabian-3.mp3']
19
- template.standard id: 'phonk', title: 'Phonk', rows: ['phonk1.mp3', 'phonk-2.mp3', { id: 'hard-phonk', title: 'Hard Phonk', rows: ['hard-phonk-1.mp3', 'hard-phonk-2.mp3'] }]
20
- end
21
- end,
22
- ->(section) do
23
- section.header childViews: ->(header) do
24
- header.h2 text: 'onClick windows/reload'
25
- end
31
+ section.rows builder: ->(template) do
32
+ template.standard \
33
+ id: 'pop',
34
+ title: 'Pop',
35
+ icon: { name: 'folder', size: 24, color: '#6e6e6e' },
36
+ onClick: ->(action) { action.windows_reload url: json_ui_garage_current_url(selected: 'pop') },
37
+ subtitle: params['selected'] == 'pop' ? 'Pop music is a genre of popular music that originated in its modern' : nil,
38
+ rows: ['pop-1.mp3', 'pop-2.mp3', 'pop-3.mp3']
39
+ template.standard \
40
+ id: 'arab',
41
+ title: 'Arabian',
42
+ icon: { name: 'folder', size: 24, color: '#6e6e6e' },
43
+ onClick: ->(action) { action.windows_reload url: json_ui_garage_current_url(selected: 'arab') },
44
+ subtitle: params['selected'] == 'arab' ? 'Arabic music is the music of the Arab world' : nil,
45
+ rows: ['arabian-1.mp3', 'arabian-2.mp3', 'arabian-3.mp3']
46
+ template.standard \
47
+ id: 'phonk',
48
+ title: 'Phonk',
49
+ onClick: ->(action) { action.windows_reload url: json_ui_garage_current_url(selected: 'phonk') },
50
+ icon: { name: 'folder', size: 24, color: '#6e6e6e' },
51
+ subtitle: params['selected'] == 'phonk' ? 'Phonk is a subgenre of hip hop and trap music' : nil,
52
+ rows: ['phonk1.mp3', 'phonk-2.mp3', { id: 'hard-phonk', title: 'Hard Phonk', rows: ['hard-phonk-1.mp3', 'hard-phonk-2.mp3'] }]
53
+ end
54
+ end,
55
+ ->(section) do
56
+ section.header childViews: ->(header) do
57
+ header.h2 text: 'Video 📹'
58
+ end
26
59
 
27
- section.rows builder: ->(template) do
28
- template.standard title: 'funny-video.mp4', id: 'fun', onClick: ->(action) { action.windows_reload url: json_ui_garage_current_url(selected: 'fun') }
29
- template.standard title: 'animal-planet.mp4', id: 'animal', onClick: ->(action) { action.windows_reload url: json_ui_garage_current_url(selected: 'animal') }
30
- template.standard title: 'wedding.mp4', id: 'wedding', onClick: ->(action) { action.windows_reload url: json_ui_garage_current_url(selected: 'wedding') }
60
+ section.rows builder: ->(template) do
61
+ template.standard title: 'funny-video.mp4', id: 'fun', onClick: ->(action) { action.windows_reload url: json_ui_garage_current_url(selected: 'fun') }
62
+ template.standard title: 'animal-planet.mp4', id: 'animal', onClick: ->(action) { action.windows_reload url: json_ui_garage_current_url(selected: 'animal') }
63
+ template.standard title: 'wedding.mp4', id: 'wedding', onClick: ->(action) { action.windows_reload url: json_ui_garage_current_url(selected: 'wedding') }
64
+ end
31
65
  end
32
- end
33
- ]
34
-
35
- scroll.spacer height: 8
36
- scroll.h2 text: 'Standard with drop functionality'
37
- scroll.spacer height: 4
38
-
39
- objects = [
40
- { id: 'folder', name: 'folder', icon: { name: 'folder', color: '#6e6e6e' }, rows: ['subfolder1', 'subfolder2'], dropData: { key: 'folder' } },
41
- { id: 'folder1', name: 'folder1', icon: { name: 'folder', color: '#6e6e6e' }, rows: ['subfolder1', 'subfolder2'] },
42
- { id: 'folder2', name: 'folder2', icon: { name: 'folder', color: '#6e6e6e' }, rows: ['subfolder1', 'subfolder2'] },
43
- ]
66
+ ]
67
+ end
44
68
 
45
69
  scroll.panels_column md: { cols: 6 }, childViews: ->(col) do
46
- col.panels_tree \
47
- selected: 'folder2',
48
- width: 300,
49
- onDrop: ->(action) do
50
- action.files_upload directUploadUrl: glib_direct_uploads_url, onFinished: ->(saction) do
51
- saction.http_post url: json_ui_garage_url(path: 'forms/generic_post_all')
70
+ col.h2 text: 'Drag me to folder!'
71
+ col.spacer height: 16
72
+ col.panels_table width: 'matchParent', sections: [
73
+ ->(section) do
74
+ section.header cellViews: ->(header) do
75
+ header.label text: 'Name'
76
+ header.label text: 'Size'
77
+ header.label text: 'Last modified'
52
78
  end
53
- end,
54
- sections: [
55
- ->(section) do
56
- section.header childViews: ->(header) do
57
- header.h2 text: 'Folder'
79
+
80
+ section.rows builder: ->(row) do
81
+ row.default dragData: { music: 'dads-fav-song.mp3' }, cellViews: ->(cell) do
82
+ cell.label text: 'dads-fav-song.mp3'
83
+ cell.label text: '3mb'
84
+ cell.label text: '2024/06/22'
58
85
  end
59
86
 
60
- section.rows objects: objects, builder: ->(row, item, index) do
61
- row.standard id: item[:id], title: item[:name], rows: item[:rows], dropData: item[:dropData], icon: item[:icon]
87
+ row.default dragData: { music: '1-hours-sound-of-rain-asmr.mp3' }, cellViews: ->(cell) do
88
+ cell.label text: '1-hours-sound-of-rain-asmr.mp3'
89
+ cell.label text: '15mb'
90
+ cell.label text: '2024/02/12'
62
91
  end
92
+
93
+ row.default dragData: { music: 'i-dont-know-the-name.mp3' }, cellViews: ->(cell) do
94
+ cell.label text: 'i-dont-know-the-name.mp3'
95
+ cell.label text: '10mb'
96
+ cell.label text: '2024/01/4'
97
+ end
98
+
63
99
  end
64
- ]
65
- end
100
+ end
101
+ ]
66
102
 
67
- scroll.panels_column md: { cols: 4 }, childViews: ->(col) do
103
+ col.spacer height: 8
68
104
  col.panels_ul childViews: ->(li) do
69
105
  li.label text: '🍌 Banana', dragData: { item: 'banana' }
70
106
  li.label text: '💣 Bomb', dragData: { item: 'bomb' }
@@ -88,7 +88,7 @@ page.body childViews: ->(body) do
88
88
  end
89
89
  end
90
90
  form.hr width: 'matchParent'
91
- form.panels_vertical width: 'matchParent', id: 'ver', childViews: ->(ver) do
91
+ form.panels_responsive width: 'matchParent', id: 'ver', childViews: ->(ver) do
92
92
  form.fields_text width: 'matchParent', name: 'user[text]', id: 'text', value: 'John Doe', validation: validation.merge(format: { regex: /Doe\z/, message: 'Must end with Doe' })
93
93
  end
94
94
  form.panels_vertical width: 'matchParent', id: 'ver1', displayed: false, childViews: ->(ver) do
@@ -7,6 +7,14 @@ render "#{@path_prefix}/nav_menu", json: json, page: page
7
7
  small_image_url = 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSGQpSWjtELISLBlmugOZ6wzl1JamYXQvbFeYywpfg3E8b8DrO0Kg&s'
8
8
 
9
9
  page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
10
+ scroll.h2 text: 'Avatar Text'
11
+ scroll.spacer height: 6
12
+ scroll.avatar \
13
+ url: glib_json_image_avatar_url,
14
+ tooltip: { text: 'This is a tooltip' },
15
+ backgroundColor: '#ddd',
16
+ initials: { text: 'JD', color: '#AAB396' }
17
+
10
18
  scroll.h2 text: 'Avatar'
11
19
  scroll.spacer height: 6
12
20
  scroll.avatar \
@@ -0,0 +1,9 @@
1
+ module Glib
2
+ class IntegrationTest < ActionDispatch::IntegrationTest
3
+ HOST = 'www.localhost:3000'.freeze
4
+
5
+ setup do
6
+ host! HOST
7
+ end
8
+ end
9
+ end
@@ -21,7 +21,10 @@ module Glib
21
21
  end
22
22
 
23
23
  # See https://stackoverflow.com/questions/51583321/it-is-safe-to-use-lvh-me-instead-of-localhost-for-testing
24
- HOST = 'www.lvh.me:3000'
24
+ # HOST = 'www.lvh.me:3000'
25
+
26
+ # The best practice is to avoid using lvh.me due to security and performance concerns.
27
+ HOST = 'www.localhost:3000'
25
28
 
26
29
  # LOG_DIR = File.expand_path(
27
30
  # File.join(File.dirname(__FILE__), 'integration/json_ui_crawler_test_results')
data/lib/glib-web.rb CHANGED
@@ -5,6 +5,7 @@ require 'glib/json_crawler'
5
5
 
6
6
  require 'glib/dynamic_text'
7
7
  require 'glib/test_helpers'
8
+ require 'glib/integration_test'
8
9
 
9
10
  require 'glib/time_freezable_mailer'
10
11
  require 'glib/time_returning_mailer'
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.4.1
4
+ version: 4.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ''
@@ -342,6 +342,7 @@ files:
342
342
  - lib/glib/dynamic_text.rb
343
343
  - lib/glib/dynamic_text/config.rb
344
344
  - lib/glib/engine.rb
345
+ - lib/glib/integration_test.rb
345
346
  - lib/glib/json_crawler.rb
346
347
  - lib/glib/json_crawler/action_crawler.rb
347
348
  - lib/glib/json_crawler/action_crawlers/action_http.rb