glib-web 4.36.7 → 4.36.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/helpers/glib/json_ui/action_builder/popovers.rb +1 -1
- data/app/helpers/glib/json_ui/view_builder/fields.rb +50 -6
- data/app/helpers/glib/json_ui/view_builder.rb +73 -0
- data/app/views/json_ui/garage/forms/file_upload.json.jbuilder +1 -1
- data/app/views/json_ui/garage/forms/file_upload_new.json.jbuilder +128 -0
- data/app/views/json_ui/garage/forms/index.json.jbuilder +3 -0
- data/app/views/json_ui/garage/views/controls.json.jbuilder +3 -1
- data/app/views/json_ui/garage/views/popovers_open.json.jbuilder +2 -0
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46f0038f026665e4c7c8cefecd766bf728ca5c807ef1216b42ae0fab40fd644a
|
4
|
+
data.tar.gz: 06e074f158733ce9ea65bef4b53cddadabbe5eb468cb20175fbb8dc1352c7c81
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6428f530b4309e009f66905ec030ee68acbd98b9543ef4480e8835408fe3601d856d98e6e517cd2d76e33a4311ee3e0b873c1e51179a5d68da5b35663e1dc2c9
|
7
|
+
data.tar.gz: 61a08e0100e9d85582933e4931f19162e5b5303f309370420d0dc4d3cdd0c183dd9a5a4b325c506e4974ec913cc20518497251cfa76583615c67137bf8ddf47c
|
@@ -13,6 +13,7 @@ class Glib::JsonUi::ActionBuilder
|
|
13
13
|
bool :persistent
|
14
14
|
hash :overlay, required: [:closeOnFocus]
|
15
15
|
singleton_array :styleClass, :styleClasses
|
16
|
+
bool :updateExisting
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
@@ -26,7 +27,6 @@ class Glib::JsonUi::ActionBuilder
|
|
26
27
|
include PopoverAttributes
|
27
28
|
|
28
29
|
string :url
|
29
|
-
bool :updateExisting
|
30
30
|
end
|
31
31
|
|
32
32
|
class Close < Action
|
@@ -334,6 +334,7 @@ class Glib::JsonUi::ViewBuilder
|
|
334
334
|
views :childViews
|
335
335
|
end
|
336
336
|
|
337
|
+
# Deprecated
|
337
338
|
class File < Text
|
338
339
|
# file_rules = { fileType: 'image/*', maxFileSize: 5000 }
|
339
340
|
# file_rules = { fileType: 'video/*', maxFileSize: 50000 }
|
@@ -379,19 +380,17 @@ class Glib::JsonUi::ViewBuilder
|
|
379
380
|
end
|
380
381
|
end
|
381
382
|
|
383
|
+
# deprecated
|
382
384
|
class MultiUpload < AbstractField
|
383
385
|
include Glib::JsonUi::Default
|
384
386
|
include Glib::JsonUi::Upload
|
387
|
+
include Glib::JsonUi::FileUploadErrorHandler
|
385
388
|
|
386
389
|
array :files
|
387
390
|
string :uploadTitle
|
388
391
|
action :onFinishUpload
|
389
392
|
string :url # http post end point if you don't want to use onFinishUpload
|
390
393
|
|
391
|
-
def accepts(value)
|
392
|
-
@accepts = value
|
393
|
-
end
|
394
|
-
|
395
394
|
def files(values)
|
396
395
|
@files = values
|
397
396
|
end
|
@@ -402,6 +401,7 @@ class Glib::JsonUi::ViewBuilder
|
|
402
401
|
|
403
402
|
def created
|
404
403
|
super
|
404
|
+
file_upload_error_handler_on_create
|
405
405
|
|
406
406
|
@placeholder ||= I18n.t('glib.multi_upload.placeholder', default: nil)
|
407
407
|
@hint ||= I18n.t('glib.multi_upload.hint', default: nil)
|
@@ -420,8 +420,6 @@ class Glib::JsonUi::ViewBuilder
|
|
420
420
|
json.placeholder @placeholder if @placeholder
|
421
421
|
json.hint @hint if @hint
|
422
422
|
|
423
|
-
json.accepts default_accepts(@accepts)
|
424
|
-
|
425
423
|
if @prop && context
|
426
424
|
# association = form.nested_associations.last
|
427
425
|
# context = association || form
|
@@ -433,6 +431,52 @@ class Glib::JsonUi::ViewBuilder
|
|
433
431
|
end
|
434
432
|
end
|
435
433
|
|
434
|
+
class Upload < AbstractField
|
435
|
+
include Glib::JsonUi::Upload
|
436
|
+
include Glib::JsonUi::FileUploadErrorHandler
|
437
|
+
|
438
|
+
action :onFinishUpload
|
439
|
+
bool :multiple
|
440
|
+
hash :placeholderView, required: [:type, :width, :height], optional: [:url]
|
441
|
+
hash :inputView, optional: [:multiple, :files, :variant]
|
442
|
+
|
443
|
+
def multiProgressView(values)
|
444
|
+
@multi_progress = values
|
445
|
+
end
|
446
|
+
|
447
|
+
def created
|
448
|
+
super
|
449
|
+
file_upload_error_handler_on_create
|
450
|
+
|
451
|
+
@placeholder ||= I18n.t('glib.multi_upload.placeholder', default: nil)
|
452
|
+
@hint ||= I18n.t('glib.multi_upload.hint', default: nil)
|
453
|
+
|
454
|
+
if @prop && context && @multi_progress
|
455
|
+
@multi_progress['files'] ||= context.field_value(@prop, collect_ids: false).to_a.map { |file| { name: file.blob&.filename, signed_id: file.signed_id, url: url_for(file) } }
|
456
|
+
end
|
457
|
+
|
458
|
+
if @multi_progress
|
459
|
+
@multi_progress['responseMessages'] ||= {}
|
460
|
+
['200', '403', '401', 'else'].each do |status|
|
461
|
+
key = "glib.multi_upload.responseMessages.#{status}"
|
462
|
+
@multi_progress['responseMessages'][status] = I18n.t(key) if I18n.exists?(key)
|
463
|
+
end
|
464
|
+
|
465
|
+
json.responseMessages (@multi_progress['responseMessages'] || {}).reverse_merge({
|
466
|
+
'200' => 'Completed',
|
467
|
+
'403' => 'Forbidden',
|
468
|
+
'401' => 'Session expired',
|
469
|
+
'else' => 'Failed'
|
470
|
+
})
|
471
|
+
|
472
|
+
json.placeholder @placeholder if @placeholder
|
473
|
+
json.hint @hint if @hint
|
474
|
+
|
475
|
+
json.multiProgressView @multi_progress
|
476
|
+
end
|
477
|
+
end
|
478
|
+
end
|
479
|
+
|
436
480
|
class Sign < AbstractField
|
437
481
|
string :directUploadUrl
|
438
482
|
required :directUploadUrl
|
@@ -15,6 +15,79 @@ module Glib
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
+
module FileUploadErrorHandler
|
19
|
+
extend ActiveSupport::Concern
|
20
|
+
|
21
|
+
included do
|
22
|
+
def accepts(options)
|
23
|
+
@accepts = options.with_indifferent_access
|
24
|
+
end
|
25
|
+
|
26
|
+
def onMaxFileLengthError(handler)
|
27
|
+
@onMaxFileLengthError = handler
|
28
|
+
end
|
29
|
+
|
30
|
+
def onMaxFileSizeError(handler)
|
31
|
+
@onMaxFileSizeError = handler
|
32
|
+
end
|
33
|
+
|
34
|
+
def onFileTypeError(handler)
|
35
|
+
@onFileTypeError = handler
|
36
|
+
end
|
37
|
+
|
38
|
+
def file_upload_error_handler_on_create
|
39
|
+
@accepts ||= {}
|
40
|
+
if @onMaxFileSizeError.blank?
|
41
|
+
@onMaxFileSizeError = ->(action) do
|
42
|
+
action.snackbars_alert \
|
43
|
+
message: I18n.t(
|
44
|
+
'glib.fields.upload.on_max_file_size_error',
|
45
|
+
max: @accepts['maxFileSize'],
|
46
|
+
default: "Your upload failed because your file is too large. Please select a file that is smaller than the maximum allowed size of #{@accepts['maxFileSize']} KB and try again."),
|
47
|
+
styleClass: 'error'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
if @onMaxFileLengthError.blank?
|
52
|
+
@onMaxFileLengthError = ->(action) do
|
53
|
+
action.snackbars_alert \
|
54
|
+
message: I18n.t(
|
55
|
+
'glib.fields.upload.on_max_file_length_error',
|
56
|
+
max: @accepts['maxFileLength'],
|
57
|
+
default: "You can't upload more than the maximum number of files allowed. The limit is #{@accepts['maxFileLength']} files."),
|
58
|
+
styleClass: 'error'
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
if @onMaxFileLengthError.blank?
|
63
|
+
@onMaxFileLengthError = ->(action) do
|
64
|
+
action.snackbars_alert \
|
65
|
+
message: I18n.t(
|
66
|
+
'glib.fields.upload.on_max_file_length_error',
|
67
|
+
max: @accepts['maxFileLength'],
|
68
|
+
default: "You can't upload more than the maximum number of files allowed. The limit is #{@accepts['maxFileLength']} files."),
|
69
|
+
styleClass: 'error'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
if @onFileTypeError.blank?
|
74
|
+
@onFileTypeError = ->(action) do
|
75
|
+
action.snackbars_alert \
|
76
|
+
message: I18n.t(
|
77
|
+
'glib.fields.upload.on_file_type_error',
|
78
|
+
default: 'The file you uploaded is not a supported file type.'),
|
79
|
+
styleClass: 'error'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
json.accepts @accepts
|
84
|
+
json.set!('onMaxFileSizeError') { @onMaxFileSizeError.call(page.action_builder) }
|
85
|
+
json.set!('onMaxFileLengthError') { @onMaxFileLengthError.call(page.action_builder) }
|
86
|
+
json.set!('onFileTypeError') { @onFileTypeError.call(page.action_builder) }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
18
91
|
class ViewBuilder < AbstractBuilder
|
19
92
|
def initialize(json, page, multiple)
|
20
93
|
super(json, page)
|
@@ -0,0 +1,128 @@
|
|
1
|
+
json.title 'Forms'
|
2
|
+
page = json_ui_page json
|
3
|
+
render "#{@path_prefix}/nav_menu", json: json, page: page
|
4
|
+
|
5
|
+
image = OpenStruct.new(
|
6
|
+
url: 'https://picsum.photos/id/11/100/60',
|
7
|
+
signed_id: 'test',
|
8
|
+
filename: 'upload.png'
|
9
|
+
)
|
10
|
+
|
11
|
+
accepts = {
|
12
|
+
fileType: 'image',
|
13
|
+
maxFileSize: 100,
|
14
|
+
maxFileLength: 2
|
15
|
+
}
|
16
|
+
|
17
|
+
if params[:mode] == 'html'
|
18
|
+
directUploadUrl = nil
|
19
|
+
else
|
20
|
+
directUploadUrl = glib_direct_uploads_url
|
21
|
+
end
|
22
|
+
|
23
|
+
properties = {
|
24
|
+
styleClass: 'pb-2',
|
25
|
+
directUploadUrl: params,
|
26
|
+
accepts: accepts,
|
27
|
+
directUploadUrl: directUploadUrl,
|
28
|
+
value: image&.signed_id
|
29
|
+
}
|
30
|
+
|
31
|
+
# properties[:onMaxFileLengthError] = ->(action) do
|
32
|
+
# action.snackbars_alert message: 'max file length exceeded'
|
33
|
+
# end
|
34
|
+
|
35
|
+
# properties[:onMaxFileSizeError] = ->(action) do
|
36
|
+
# action.snackbars_alert message: 'max file size exceeded'
|
37
|
+
# end
|
38
|
+
|
39
|
+
# properties[:onFileTypeError] = ->(action) do
|
40
|
+
# action.snackbars_alert message: 'file type invalid'
|
41
|
+
# end
|
42
|
+
|
43
|
+
properties[:onFinishUpload] = ->(action) do
|
44
|
+
action.snackbars_alert message: 'Get the signed ids!'
|
45
|
+
end
|
46
|
+
|
47
|
+
page.form \
|
48
|
+
url: json_ui_garage_url(path: 'forms/generic_post'),
|
49
|
+
method: 'post',
|
50
|
+
padding: { top: 12, left: 20, right: 20, bottom: 12 },
|
51
|
+
childViews: ->(form) do
|
52
|
+
form.panels_flow styleClass: 'items-center justify-center gap-2 pb-4', childViews: ->(flow) do
|
53
|
+
flow.label text: "MODE: #{params[:mode] || 'directUpload'}"
|
54
|
+
change = params[:mode] == 'html' ? 'directUpload' : 'html'
|
55
|
+
flow.button text: 'Change', onClick: ->(action) { action.windows_open url: json_ui_garage_current_url({ mode: change }) }
|
56
|
+
end
|
57
|
+
|
58
|
+
form.h2 text: 'Field Upload', styleClass: 'pb-4'
|
59
|
+
form.label text: 'placeholder image', styleClass: 'pb-1'
|
60
|
+
form.panels_flow styleClass: 'align-center', xs: { gap: { all: 4 } }, childViews: ->(flow) do
|
61
|
+
form.fields_upload properties.merge(
|
62
|
+
name: 'user[file_placeholderView]',
|
63
|
+
id: 'pv1',
|
64
|
+
placeholderView: { type: 'image', url: image&.url, width: 144, height: 144 }
|
65
|
+
)
|
66
|
+
|
67
|
+
flow.button text: 'trigger', onClick: ->(action) do
|
68
|
+
action.components_invoke targetId: 'pv1', name: 'trigger'
|
69
|
+
end
|
70
|
+
flow.button text: 'reset', onClick: ->(action) do
|
71
|
+
action.components_invoke targetId: 'pv1', name: 'reset'
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
form.label text: 'placeholder avatar', styleClass: 'pb-1'
|
76
|
+
form.panels_flow styleClass: 'align-center', xs: { gap: { all: 4 } }, childViews: ->(flow) do
|
77
|
+
flow.fields_upload \
|
78
|
+
properties.merge(
|
79
|
+
name: 'user[file_placeholderView2]',
|
80
|
+
id: 'pv2',
|
81
|
+
placeholderView: { type: 'avatar', url: image&.url, width: 64, height: 64 }
|
82
|
+
)
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
form.label text: 'file input', styleClass: 'pb-1'
|
87
|
+
form.fields_upload \
|
88
|
+
properties.merge(
|
89
|
+
name: 'user[file_input1]',
|
90
|
+
id: 'fi1',
|
91
|
+
label: 'Upload file',
|
92
|
+
width: 300,
|
93
|
+
label: 'Choose file',
|
94
|
+
inputView: { variant: 'outlined' },
|
95
|
+
multiple: false
|
96
|
+
)
|
97
|
+
|
98
|
+
|
99
|
+
form.label text: 'multiprogress', styleClass: 'pb-1'
|
100
|
+
form.fields_upload \
|
101
|
+
properties.merge(
|
102
|
+
name: 'user[file_multiprogress1][]',
|
103
|
+
id: 'mp1',
|
104
|
+
width: 300,
|
105
|
+
label: 'Upload file',
|
106
|
+
multiple: true,
|
107
|
+
multiProgressView: { files: [] }
|
108
|
+
)
|
109
|
+
|
110
|
+
|
111
|
+
form.label text: 'Button file upload', styleClass: 'pb-1'
|
112
|
+
form.button text: 'click me to select file', onClick: ->(action) do
|
113
|
+
action.components_invoke targetId: 'btn1', name: 'trigger'
|
114
|
+
end
|
115
|
+
form.fields_upload \
|
116
|
+
properties.merge(
|
117
|
+
name: 'user[file_btn1][]',
|
118
|
+
id: 'btn1',
|
119
|
+
width: 300,
|
120
|
+
label: 'Upload file',
|
121
|
+
multiple: true,
|
122
|
+
inputView: { files: [] },
|
123
|
+
styleClass: 'pb-4 d-none'
|
124
|
+
)
|
125
|
+
|
126
|
+
form.fields_submit text: 'submit'
|
127
|
+
|
128
|
+
end
|
@@ -72,6 +72,9 @@ page.list sections: [
|
|
72
72
|
template.thumbnail title: 'File Upload', onClick: ->(action) do
|
73
73
|
action.windows_open url: json_ui_garage_url(path: 'forms/file_upload')
|
74
74
|
end
|
75
|
+
template.thumbnail title: 'File Upload (NEW)', onClick: ->(action) do
|
76
|
+
action.windows_open url: json_ui_garage_url(path: 'forms/file_upload_new')
|
77
|
+
end
|
75
78
|
template.thumbnail title: 'Floating Submit', onClick: ->(action) do
|
76
79
|
action.windows_open url: json_ui_garage_url(path: 'forms/floating_submit')
|
77
80
|
end
|
@@ -65,6 +65,7 @@ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
|
|
65
65
|
key: 'menu2',
|
66
66
|
placement: 'right-start',
|
67
67
|
width: 200,
|
68
|
+
updateExisting: true,
|
68
69
|
content: ->(dialog) do
|
69
70
|
dialog.body styleClass: 'popover-menu', padding: glib_json_padding_body, childViews: ->(res) do
|
70
71
|
res.label text: 'Item 1', styleClass: 'popover-menu-item', onClick: ->(saction) do
|
@@ -95,7 +96,8 @@ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
|
|
95
96
|
action.popovers_open \
|
96
97
|
url: json_ui_garage_url(path: 'views/popovers_open', key: key),
|
97
98
|
styleClass: 'popover-container',
|
98
|
-
key: key
|
99
|
+
key: key,
|
100
|
+
updateExisting: true
|
99
101
|
end
|
100
102
|
|
101
103
|
scroll.spacer height: 10
|
metadata
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glib-web
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.36.
|
4
|
+
version: 4.36.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ''
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
date: 2019-10-04 00:00:00.000000000 Z
|
@@ -136,7 +136,7 @@ dependencies:
|
|
136
136
|
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
|
-
description:
|
139
|
+
description:
|
140
140
|
email: ''
|
141
141
|
executables: []
|
142
142
|
extensions: []
|
@@ -268,6 +268,7 @@ files:
|
|
268
268
|
- app/views/json_ui/garage/forms/dynamic_select.json.jbuilder
|
269
269
|
- app/views/json_ui/garage/forms/dynamic_select_data.json.jbuilder
|
270
270
|
- app/views/json_ui/garage/forms/file_upload.json.jbuilder
|
271
|
+
- app/views/json_ui/garage/forms/file_upload_new.json.jbuilder
|
271
272
|
- app/views/json_ui/garage/forms/floating_submit.json.jbuilder
|
272
273
|
- app/views/json_ui/garage/forms/full_page_form.json.jbuilder
|
273
274
|
- app/views/json_ui/garage/forms/full_page_form_dialog.json.jbuilder
|
@@ -445,10 +446,10 @@ files:
|
|
445
446
|
- lib/glib/value.rb
|
446
447
|
- lib/glib/version.rb
|
447
448
|
- lib/tasks/db.rake
|
448
|
-
homepage:
|
449
|
+
homepage:
|
449
450
|
licenses: []
|
450
451
|
metadata: {}
|
451
|
-
post_install_message:
|
452
|
+
post_install_message:
|
452
453
|
rdoc_options: []
|
453
454
|
require_paths:
|
454
455
|
- lib
|
@@ -464,7 +465,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
464
465
|
version: '0'
|
465
466
|
requirements: []
|
466
467
|
rubygems_version: 3.4.6
|
467
|
-
signing_key:
|
468
|
+
signing_key:
|
468
469
|
specification_version: 4
|
469
470
|
summary: ''
|
470
471
|
test_files: []
|