glib-web 0.5.76 → 0.5.80
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/controllers/concerns/glib/auth/policy.rb +21 -20
- data/app/helpers/glib/json_ui/action_builder/iap.rb +15 -0
- data/app/helpers/glib/json_ui/action_builder/windows.rb +5 -0
- data/app/helpers/glib/json_ui/view_builder/fields.rb +13 -0
- data/app/helpers/glib/json_ui/view_builder/iap.rb +11 -0
- data/app/policies/glib/application_policy.rb +98 -68
- data/app/views/json_ui/garage/forms/_alert_post_data.json.jbuilder +5 -2
- data/app/views/json_ui/garage/forms/file_upload.json.jbuilder +5 -0
- data/app/views/json_ui/garage/forms/index.json.jbuilder +5 -2
- data/app/views/json_ui/garage/forms/new_rich_text.json.jbuilder +2 -1
- data/app/views/json_ui/garage/forms/payments.json.jbuilder +34 -0
- data/app/views/json_ui/garage/forms/rich_text.json.jbuilder +1 -1
- data/app/views/json_ui/garage/forms/show_hide.json.jbuilder +20 -0
- data/app/views/json_ui/garage/forms/text_validation.json.jbuilder +1 -17
- data/app/views/json_ui/garage/panels/carousel.json.jbuilder +8 -7
- data/app/views/json_ui/garage/views/iap.json.jbuilder +21 -0
- data/app/views/json_ui/garage/views/index.json.jbuilder +11 -0
- data/app/views/layouts/json_ui/renderer.html.erb +1 -1
- metadata +5 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e353f7685e62fafe9e1b265db2226f4d9c81def42152c51a4fd87508f90b8341
|
4
|
+
data.tar.gz: e4d4636d3b385b49c89efd0120e0fec04b1e259527377fa0cacd87912d0a4cd1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 52525e97d08b324b45d6c695fe4c033f58594a1e267125220e043d4fb004cfd56c9c7afb91cbd6b92a4ea76321fb9544115e5b034823c9a5335e33aafcf3ee75
|
7
|
+
data.tar.gz: f108306d3c3994752caf3a52801b278c9512b49b05f2c94b8835f51af7ec76ba88570ce08b28daeef1abeb798d6caea0b33a240f62e93d6f4fa9b24e2152b075
|
@@ -20,7 +20,7 @@ module Glib::Auth
|
|
20
20
|
module Overrides
|
21
21
|
|
22
22
|
public # Override
|
23
|
-
def policy(record, policy_name = nil)
|
23
|
+
def policy(record, policy_name = nil, attributes = {})
|
24
24
|
policy_name ||= record
|
25
25
|
|
26
26
|
@__pundit_policies ||= {}
|
@@ -34,7 +34,7 @@ module Glib::Auth
|
|
34
34
|
|
35
35
|
raise "Policy not found for #{policy_name.is_a?(Symbol) || policy_name.is_a?(Class) ? policy_name : policy_name.class}" unless policy_class
|
36
36
|
|
37
|
-
@__pundit_policies[policy_name] = policy_class.new(current_user, record, policy_name, self, request, params,
|
37
|
+
@__pundit_policies[policy_name] = policy_class.new(current_user, record, policy_name, self, request, params, attributes: attributes)
|
38
38
|
end
|
39
39
|
|
40
40
|
# Expose protected method
|
@@ -42,16 +42,17 @@ module Glib::Auth
|
|
42
42
|
def policy_scope(*args)
|
43
43
|
super
|
44
44
|
end
|
45
|
+
|
45
46
|
end
|
46
47
|
|
47
48
|
private
|
48
|
-
|
49
|
-
|
50
|
-
|
49
|
+
def raise_access_denied(record, policy)
|
50
|
+
raise UnauthorizedError.new(record: record, policy: policy, query: "#{action_name}?")
|
51
|
+
end
|
51
52
|
|
52
53
|
public
|
53
|
-
def can?(action, record)
|
54
|
-
policy(record).send("#{action}?")
|
54
|
+
def can?(action, record, attributes = {})
|
55
|
+
policy(record, nil, attributes).send("#{action}?")
|
55
56
|
end
|
56
57
|
|
57
58
|
public
|
@@ -71,19 +72,19 @@ module Glib::Auth
|
|
71
72
|
policy_name = resource_name.camelize.constantize
|
72
73
|
else
|
73
74
|
policy_name = case resource_key
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
75
|
+
when false
|
76
|
+
resource_name.to_sym
|
77
|
+
when Symbol, Class
|
78
|
+
resource_key
|
79
|
+
else
|
80
|
+
raise "Invalid resource class: #{resource_key}"
|
80
81
|
end
|
81
82
|
end
|
82
83
|
|
83
84
|
resource_instance = instance_variable_get("@#{resource_name}") || policy_name
|
84
85
|
|
85
86
|
query = "#{action_name}?"
|
86
|
-
policy_instance = policy(resource_instance, policy_name)
|
87
|
+
policy_instance = policy(resource_instance, policy_name, options.except(:class))
|
87
88
|
raise_access_denied(resource_instance, policy_instance) unless policy_instance.public_send(query)
|
88
89
|
end
|
89
90
|
|
@@ -118,12 +119,12 @@ module Glib::Auth
|
|
118
119
|
begin
|
119
120
|
if !(resource_key = options[:class]).nil?
|
120
121
|
resource = case resource_key
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
122
|
+
when false
|
123
|
+
resource_name.to_sym
|
124
|
+
when Symbol, Class
|
125
|
+
resource_key
|
126
|
+
else
|
127
|
+
raise "Invalid resource class: #{resource_key}"
|
127
128
|
end
|
128
129
|
|
129
130
|
authorize resource
|
@@ -29,5 +29,10 @@ class Glib::JsonUi::ActionBuilder
|
|
29
29
|
|
30
30
|
required :fallbackUrl
|
31
31
|
end
|
32
|
+
|
33
|
+
# Any component can listen to the refresh_state event and react appropriately.
|
34
|
+
# E.g. Stripe credit card component can refresh its token to make sure it is not stale.
|
35
|
+
class RefreshState < Action
|
36
|
+
end
|
32
37
|
end
|
33
38
|
end
|
@@ -225,6 +225,19 @@ class Glib::JsonUi::ViewBuilder
|
|
225
225
|
hash :placeholderView
|
226
226
|
end
|
227
227
|
|
228
|
+
# TODO
|
229
|
+
# class MultiImage < Text
|
230
|
+
# # file_rules = { fileType: 'image/*', maxFileSize: 5000 }
|
231
|
+
# # file_rules = { fileType: 'video/*', maxFileSize: 50000 }
|
232
|
+
# # file_rules = { fileType: 'application/pdf', maxFileSize: 5000 }
|
233
|
+
# # hash :accepts
|
234
|
+
|
235
|
+
# string :directUploadUrl
|
236
|
+
# # string :fileUrl
|
237
|
+
# # string :fileTitle
|
238
|
+
# hash :placeholderView
|
239
|
+
# end
|
240
|
+
|
228
241
|
class Date < AbstractField
|
229
242
|
date :min
|
230
243
|
date :max
|
@@ -3,98 +3,123 @@
|
|
3
3
|
module Glib
|
4
4
|
class ApplicationPolicy
|
5
5
|
attr_reader :user, :record, :policy_name, :controller, :request, :params
|
6
|
+
class_attribute :should_exist_attributes, instance_writer: false, default: []
|
6
7
|
|
7
8
|
private
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
9
|
+
def initialize(user, record, policy_name, controller, request, params, attributes: {})
|
10
|
+
@user = user
|
11
|
+
@record = record
|
12
|
+
@controller = controller
|
13
|
+
@request = request
|
14
|
+
# Don't get params from request because we might not have a proper request object. This might execute in Sidekiq.
|
15
|
+
# See Presenter::Model::inside_mock_controller()
|
16
|
+
@params = params
|
17
|
+
@policy_name = policy_name
|
18
|
+
|
19
|
+
if attributes.present? && controller.action_name != 'index'
|
20
|
+
self.class.module_eval { attr_accessor(*attributes.keys) }
|
21
|
+
attributes.each do |key, value|
|
22
|
+
send("#{key}=", value)
|
23
|
+
end
|
24
|
+
end
|
18
25
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
private # Used by child
|
25
|
-
def authorize(*actions, &block)
|
26
|
-
actions.each do |action|
|
27
|
-
if action == :glib_all
|
28
|
-
# Serve as a catch-all to all actions that have not been specified in the policy.
|
29
|
-
@catch_all = block
|
30
|
-
else
|
31
|
-
method_name = "#{action}?"
|
32
|
-
# Avoid accidentally redefining multiple times from child policies. But it's okay if the child policy
|
33
|
-
# wants to override the parent's authorization method.
|
34
|
-
raise "Action authorization has been declared: #{action}" if instance_methods(false).include?(method_name.to_sym)
|
35
|
-
define_method method_name, &block
|
26
|
+
if controller.user_signed_in?
|
27
|
+
should_exist_attributes.each do |attribute|
|
28
|
+
if try(attribute).blank? && !['index'].include?(controller.action_name)
|
29
|
+
raise "Attribute #{attribute} is blank, policy will not working properly"
|
30
|
+
end
|
36
31
|
end
|
37
32
|
end
|
38
33
|
end
|
39
|
-
|
34
|
+
|
35
|
+
class << self
|
36
|
+
attr_reader :catch_all
|
37
|
+
|
38
|
+
def inherited(base)
|
39
|
+
base.should_exist_attributes = should_exist_attributes.dup
|
40
|
+
super
|
41
|
+
end
|
42
|
+
|
43
|
+
# This is to define the authorization logic for an action (or a group of actions). It's different from controller's
|
44
|
+
# authorize().
|
45
|
+
private # Used by child
|
46
|
+
def authorize(*actions, &block)
|
47
|
+
actions.each do |action|
|
48
|
+
if action == :glib_all
|
49
|
+
# Serve as a catch-all to all actions that have not been specified in the policy.
|
50
|
+
@catch_all = block
|
51
|
+
else
|
52
|
+
method_name = "#{action}?"
|
53
|
+
# Avoid accidentally redefining multiple times from child policies. But it's okay if the child policy
|
54
|
+
# wants to override the parent's authorization method.
|
55
|
+
raise "Action authorization has been declared: #{action}" if instance_methods(false).include?(method_name.to_sym)
|
56
|
+
define_method method_name, &block
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def should_exist(*attributes)
|
62
|
+
should_exist_attributes.push(*attributes)
|
63
|
+
end
|
64
|
+
end
|
40
65
|
|
41
66
|
private
|
42
|
-
|
43
|
-
|
44
|
-
|
67
|
+
def catch_all
|
68
|
+
self.class.catch_all
|
69
|
+
end
|
45
70
|
|
46
71
|
private
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
72
|
+
# To ensure the block is called on the policy's instance instead class.
|
73
|
+
def call_catch_all
|
74
|
+
instance_eval(&catch_all)
|
75
|
+
end
|
51
76
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
77
|
+
authorize :index do
|
78
|
+
# We need this line because in `index` action, this method will be called instead of method_missing().
|
79
|
+
# Having this line ensures that the catch_all behaviour works according to the priority below:
|
80
|
+
# - child_policy#index?
|
81
|
+
# - child_policy#manage? -- catch_all
|
82
|
+
# - application_policy@index?
|
83
|
+
return call_catch_all if catch_all
|
59
84
|
|
60
|
-
|
61
|
-
|
85
|
+
false
|
86
|
+
end
|
62
87
|
|
63
|
-
|
64
|
-
|
88
|
+
authorize :show do
|
89
|
+
return call_catch_all if catch_all
|
65
90
|
|
66
|
-
|
67
|
-
|
91
|
+
scope.where(id: record.id).exists?
|
92
|
+
end
|
68
93
|
|
69
|
-
|
70
|
-
|
94
|
+
authorize :create do
|
95
|
+
return call_catch_all if catch_all
|
71
96
|
|
72
|
-
|
73
|
-
|
97
|
+
false
|
98
|
+
end
|
74
99
|
|
75
|
-
|
76
|
-
|
100
|
+
authorize :new do
|
101
|
+
return call_catch_all if catch_all
|
77
102
|
|
78
|
-
|
79
|
-
|
103
|
+
create?
|
104
|
+
end
|
80
105
|
|
81
|
-
|
82
|
-
|
106
|
+
authorize :update do
|
107
|
+
return call_catch_all if catch_all
|
83
108
|
|
84
|
-
|
85
|
-
|
109
|
+
false
|
110
|
+
end
|
86
111
|
|
87
|
-
|
88
|
-
|
112
|
+
authorize :edit do
|
113
|
+
return call_catch_all if catch_all
|
89
114
|
|
90
|
-
|
91
|
-
|
115
|
+
update?
|
116
|
+
end
|
92
117
|
|
93
|
-
|
94
|
-
|
118
|
+
authorize :destroy do
|
119
|
+
return call_catch_all if catch_all
|
95
120
|
|
96
|
-
|
97
|
-
|
121
|
+
false
|
122
|
+
end
|
98
123
|
|
99
124
|
public
|
100
125
|
def method_missing(name, *args, &block)
|
@@ -118,6 +143,11 @@ module Glib
|
|
118
143
|
Proc.new { |controller| [] }
|
119
144
|
end
|
120
145
|
|
146
|
+
public
|
147
|
+
def helpers
|
148
|
+
controller.helpers
|
149
|
+
end
|
150
|
+
|
121
151
|
# TODO: Remove. Deprecated
|
122
152
|
# private # Used by child
|
123
153
|
# def public?
|
@@ -3,5 +3,8 @@ params.require(:user).each do |k, v|
|
|
3
3
|
value = v.is_a?(String) ? '"' + v + '"' : v
|
4
4
|
info += " #{k} => #{value}\n"
|
5
5
|
end
|
6
|
-
info +=
|
7
|
-
|
6
|
+
info += '}'
|
7
|
+
|
8
|
+
action.dialogs_alert message: info, onClose: ->(action) do
|
9
|
+
action.windows_refreshState
|
10
|
+
end
|
@@ -28,5 +28,10 @@ page.form options.merge(childViews: ->(form) do
|
|
28
28
|
rules = { fileType: 'pdf', maxFileSize: 5000 }
|
29
29
|
form.fields_file name: 'user[pdf2][]', width: 'matchParent', label: 'PDF Document', accepts: rules, directUploadUrl: rails_direct_uploads_url
|
30
30
|
|
31
|
+
# TODO
|
32
|
+
# rules = { fileType: 'image/*', maxFileSize: 1, fileTypeErrorText: 'Invalid!', maxFileSizeErrorText: 'Too big!' }
|
33
|
+
# form.fields_multiImage name: 'user[photos][]', width: 'matchParent', label: 'Avatar', accepts: rules, directUploadUrl: rails_direct_uploads_url,
|
34
|
+
# placeholderView: { type: 'avatar', width: 100, height: 100, url: 'data:image/jpeg;base64,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' }
|
35
|
+
|
31
36
|
form.fields_submit text: 'Submit'
|
32
37
|
end)
|
@@ -65,6 +65,9 @@ page.list sections: [
|
|
65
65
|
template.thumbnail title: 'Timers', onClick: ->(action) do
|
66
66
|
action.windows_open url: json_ui_garage_url(path: 'forms/timers')
|
67
67
|
end
|
68
|
+
template.thumbnail title: 'Payments', onClick: ->(action) do
|
69
|
+
action.windows_open url: json_ui_garage_url(path: 'forms/payments')
|
70
|
+
end
|
68
71
|
end
|
69
72
|
end, ->(section) do
|
70
73
|
section.header padding: glib_json_padding_list, childViews: ->(header) do
|
@@ -81,13 +84,13 @@ page.list sections: [
|
|
81
84
|
end
|
82
85
|
|
83
86
|
section.rows builder: ->(template) do
|
84
|
-
template.thumbnail title: 'Rich Text Editor', onClick: ->(action) do
|
87
|
+
template.thumbnail title: 'Basic Rich Text Editor', onClick: ->(action) do
|
85
88
|
action.windows_open url: json_ui_garage_url(path: 'forms/rich_text')
|
86
89
|
end
|
87
90
|
end
|
88
91
|
|
89
92
|
section.rows builder: ->(template) do
|
90
|
-
template.thumbnail title: '
|
93
|
+
template.thumbnail title: 'Advanced Rich Text Editor', onClick: ->(action) do
|
91
94
|
action.windows_open url: json_ui_garage_url(path: 'forms/new_rich_text')
|
92
95
|
end
|
93
96
|
|
@@ -4,7 +4,7 @@ page = json_ui_page json
|
|
4
4
|
render "#{@path_prefix}/nav_menu", json: json, page: page
|
5
5
|
|
6
6
|
page.form url: json_ui_garage_url(path: 'forms/basic_post'), method: 'post', padding: { top: 12, left: 20, right: 20, bottom: 12 }, childViews: ->(form) do
|
7
|
-
form.fields_text name: 'user[name]', width: 'matchParent', label: 'Name'
|
7
|
+
form.fields_text name: 'user[name]', width: 'matchParent', label: 'Name', value: 'Rich Text Editor'
|
8
8
|
|
9
9
|
# images = [
|
10
10
|
# {
|
@@ -30,6 +30,7 @@ page.form url: json_ui_garage_url(path: 'forms/basic_post'), method: 'post', pad
|
|
30
30
|
end
|
31
31
|
|
32
32
|
json.imageUploader do
|
33
|
+
json.fieldName 'user[images_attributes]'
|
33
34
|
json.accepts(fileType: "image/*", maxFileSize: 5000)
|
34
35
|
json.directUploadUrl rails_direct_uploads_url
|
35
36
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
json.title 'Forms'
|
2
|
+
|
3
|
+
page = json_ui_page json
|
4
|
+
render "#{@path_prefix}/nav_menu", json: json, page: page
|
5
|
+
|
6
|
+
# Pass `refresh_state` to refresh the CC token after submission.
|
7
|
+
page.form \
|
8
|
+
url: json_ui_garage_url(path: 'forms/generic_post', refresh_state: true),
|
9
|
+
method: 'post',
|
10
|
+
padding: glib_json_padding_body,
|
11
|
+
childViews: ->(form) do
|
12
|
+
form.spacer height: 20
|
13
|
+
form.h2 text: 'Credit card'
|
14
|
+
form.spacer height: 6
|
15
|
+
form.fields_stripeToken \
|
16
|
+
name: 'user[stripe_token]',
|
17
|
+
width: 'matchParent',
|
18
|
+
publicKey: 'pk_test_TYooMQauvdEDq54NiTphI7jx'
|
19
|
+
|
20
|
+
form.spacer height: 20
|
21
|
+
form.h2 text: 'Bank account'
|
22
|
+
form.spacer height: 6
|
23
|
+
form.fields_stripeExternalAccount \
|
24
|
+
name: 'user[stripe_external_account]',
|
25
|
+
width: 'matchParent',
|
26
|
+
publicKey: 'pk_test_TYooMQauvdEDq54NiTphI7jx',
|
27
|
+
accountHolderName: 'John Doe',
|
28
|
+
accountHolderType: 'individual',
|
29
|
+
country: 'AU',
|
30
|
+
currency: 'AUD'
|
31
|
+
|
32
|
+
form.spacer height: 30
|
33
|
+
form.fields_submit text: 'Submit'
|
34
|
+
end
|
@@ -5,7 +5,7 @@ page = json_ui_page json
|
|
5
5
|
render "#{@path_prefix}/nav_menu", json: json, page: page
|
6
6
|
|
7
7
|
page.form url: json_ui_garage_url(path: 'forms/basic_post'), method: 'post', padding: { top: 12, left: 20, right: 20, bottom: 12 }, childViews: ->(form) do
|
8
|
-
form.fields_text name: 'user[name]', width: 'matchParent', label: 'Name'
|
8
|
+
form.fields_text name: 'user[name]', width: 'matchParent', label: 'Name', value: 'Rich Text Editor'
|
9
9
|
|
10
10
|
# images = [
|
11
11
|
# {
|
@@ -48,6 +48,26 @@ page.form url: json_ui_garage_url(path: 'forms/generic_post'), method: 'post', p
|
|
48
48
|
]
|
49
49
|
}
|
50
50
|
|
51
|
+
form.spacer height: 6
|
52
|
+
form.fields_check name: 'user[check1]', checkValue: 'on', label: 'Show text'
|
53
|
+
form.spacer height: 10
|
54
|
+
form.label text: 'Checked', showIf: {
|
55
|
+
"==": [
|
56
|
+
{
|
57
|
+
"var": 'user[check1]'
|
58
|
+
},
|
59
|
+
'on'
|
60
|
+
]
|
61
|
+
}
|
62
|
+
form.label text: 'Checked', showIf: {
|
63
|
+
"!=": [
|
64
|
+
{
|
65
|
+
"var": 'user[check1]'
|
66
|
+
},
|
67
|
+
'on'
|
68
|
+
]
|
69
|
+
}
|
70
|
+
|
51
71
|
form.spacer height: 20
|
52
72
|
form.h1 text: 'Radio Group'
|
53
73
|
form.fields_radioGroup name: 'user[radio1]', value: 'F', childViews: ->(group) do
|
@@ -34,7 +34,7 @@ page.form \
|
|
34
34
|
form.fields_phone \
|
35
35
|
name: 'user[phone2]',
|
36
36
|
width: 'matchParent',
|
37
|
-
label:
|
37
|
+
label: 'Phone field with Australia as the default country',
|
38
38
|
disableAutoDetect: true, # Disable country auto detect by user IP
|
39
39
|
defaultCountry: 'AU' # ISO Country code, see: https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes
|
40
40
|
|
@@ -60,22 +60,6 @@ page.form \
|
|
60
60
|
validation: { required: { message: 'Required' } },
|
61
61
|
options: options
|
62
62
|
|
63
|
-
form.spacer height: 20
|
64
|
-
form.fields_stripeToken \
|
65
|
-
name: 'user[stripe_token]',
|
66
|
-
width: 'matchParent',
|
67
|
-
publicKey: 'pk_test_TYooMQauvdEDq54NiTphI7jx'
|
68
|
-
|
69
|
-
form.spacer height: 20
|
70
|
-
form.fields_stripeExternalAccount \
|
71
|
-
name: 'user[stripe_external_account]',
|
72
|
-
width: 'matchParent',
|
73
|
-
publicKey: 'pk_test_TYooMQauvdEDq54NiTphI7jx',
|
74
|
-
accountHolderName: 'John Doe',
|
75
|
-
accountHolderType: 'individual',
|
76
|
-
country: 'AU',
|
77
|
-
currency: 'AUD'
|
78
|
-
|
79
63
|
form.spacer height: 30
|
80
64
|
form.fields_submit text: 'Submit'
|
81
65
|
end
|
@@ -7,30 +7,31 @@ json_ui_page json do |page|
|
|
7
7
|
render "#{@path_prefix}/nav_menu", json: json, page: page
|
8
8
|
|
9
9
|
page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
|
10
|
-
scroll.label text: "\n"
|
11
10
|
scroll.h1 text: 'Carousel with labels'
|
12
11
|
scroll.panels_carousel width: 'matchParent', childViews: ->(carousel) do
|
13
12
|
carousel.label text: 'Item 1'
|
14
13
|
carousel.label text: 'Item 2'
|
15
14
|
end
|
16
15
|
|
17
|
-
scroll.
|
16
|
+
scroll.spacer height: 20
|
18
17
|
scroll.h1 text: 'Carousel with images'
|
19
18
|
scroll.panels_carousel width: 'matchParent', childViews: ->(carousel) do
|
20
19
|
carousel.image url: image_url1, width: 'matchParent'
|
21
20
|
carousel.image url: image_url2, width: 'matchParent'
|
22
21
|
end
|
23
22
|
|
24
|
-
scroll.
|
23
|
+
scroll.spacer height: 20
|
25
24
|
scroll.h1 text: 'Carousel with complex layout'
|
26
25
|
scroll.panels_carousel width: 'matchParent', childViews: ->(carousel) do
|
27
|
-
|
26
|
+
height = 480
|
27
|
+
|
28
|
+
carousel.panels_vertical align: 'center', childViews: ->(panel) do
|
28
29
|
panel.h3 text: 'Item 1'
|
29
|
-
panel.image
|
30
|
+
panel.image height: height, url: image_url1
|
30
31
|
end
|
31
|
-
carousel.panels_vertical childViews: ->(panel) do
|
32
|
+
carousel.panels_vertical align: 'center', childViews: ->(panel) do
|
32
33
|
panel.h3 text: 'Item 2'
|
33
|
-
panel.image
|
34
|
+
panel.image height: height, url: image_url2
|
34
35
|
end
|
35
36
|
end
|
36
37
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
json.title 'Views'
|
2
|
+
|
3
|
+
json_ui_page json do |page|
|
4
|
+
render "#{@path_prefix}/nav_menu", json: json, page: page
|
5
|
+
|
6
|
+
page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
|
7
|
+
|
8
|
+
product_id = 'APP_STORE_PRODUCT_KEY'
|
9
|
+
|
10
|
+
scroll.h2 text: 'IAP product button'
|
11
|
+
scroll.spacer height: 6
|
12
|
+
scroll.iap_productButton text: 'GET', productId: product_id, onClick: ->(action) do
|
13
|
+
action.iap_initiatePurchase mode: 'purchase', productId: product_id, onSuccess: ->(subaction) do
|
14
|
+
subaction.dialogs_alert message: 'Success'
|
15
|
+
end, onFailure: ->(subaction) do
|
16
|
+
subaction.dialogs_alert message: 'Failure'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -50,6 +50,17 @@ json_ui_page json do |page|
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
end,
|
53
|
+
->(section) do
|
54
|
+
section.header padding: glib_json_padding_list, childViews: ->(header) do
|
55
|
+
header.h2 text: 'Android and iOS only (experimental)'
|
56
|
+
end
|
57
|
+
|
58
|
+
section.rows builder: ->(template) do
|
59
|
+
template.thumbnail title: 'In-App Purchase', onClick: ->(action) do
|
60
|
+
action.windows_open url: json_ui_garage_url(path: 'views/iap')
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end,
|
53
64
|
->(section) do
|
54
65
|
section.header padding: glib_json_padding_list, childViews: ->(header) do
|
55
66
|
header.h2 text: 'Reference'
|
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: 0.5.
|
4
|
+
version: 0.5.80
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ''
|
@@ -93,6 +93,7 @@ files:
|
|
93
93
|
- app/helpers/glib/json_ui/action_builder.rb
|
94
94
|
- app/helpers/glib/json_ui/action_builder/dialogs.rb
|
95
95
|
- app/helpers/glib/json_ui/action_builder/http.rb
|
96
|
+
- app/helpers/glib/json_ui/action_builder/iap.rb
|
96
97
|
- app/helpers/glib/json_ui/action_builder/panels.rb
|
97
98
|
- app/helpers/glib/json_ui/action_builder/sheets.rb
|
98
99
|
- app/helpers/glib/json_ui/action_builder/snackbars.rb
|
@@ -111,6 +112,7 @@ files:
|
|
111
112
|
- app/helpers/glib/json_ui/view_builder/banners.rb
|
112
113
|
- app/helpers/glib/json_ui/view_builder/charts.rb
|
113
114
|
- app/helpers/glib/json_ui/view_builder/fields.rb
|
115
|
+
- app/helpers/glib/json_ui/view_builder/iap.rb
|
114
116
|
- app/helpers/glib/json_ui/view_builder/panels.rb
|
115
117
|
- app/helpers/glib/urls_helper.rb
|
116
118
|
- app/models/concerns/glib/soft_deletable.rb
|
@@ -150,6 +152,7 @@ files:
|
|
150
152
|
- app/views/json_ui/garage/forms/new_rich_text.json.jbuilder
|
151
153
|
- app/views/json_ui/garage/forms/online_participant1.json.jbuilder
|
152
154
|
- app/views/json_ui/garage/forms/online_participant2.json.jbuilder
|
155
|
+
- app/views/json_ui/garage/forms/payments.json.jbuilder
|
153
156
|
- app/views/json_ui/garage/forms/pickers.json.jbuilder
|
154
157
|
- app/views/json_ui/garage/forms/ratings.json.jbuilder
|
155
158
|
- app/views/json_ui/garage/forms/rich_text.json.jbuilder
|
@@ -216,6 +219,7 @@ files:
|
|
216
219
|
- app/views/json_ui/garage/views/calendar_data.json.jbuilder
|
217
220
|
- app/views/json_ui/garage/views/charts.json.jbuilder
|
218
221
|
- app/views/json_ui/garage/views/controls.json.jbuilder
|
222
|
+
- app/views/json_ui/garage/views/iap.json.jbuilder
|
219
223
|
- app/views/json_ui/garage/views/icon_names.json.jbuilder
|
220
224
|
- app/views/json_ui/garage/views/icons.json.jbuilder
|
221
225
|
- app/views/json_ui/garage/views/images.json.jbuilder
|