glib-web 0.5.92 → 0.5.93

Sign up to get free protection for your applications and to get access to all the features.
Files changed (191) hide show
  1. checksums.yaml +4 -4
  2. data/app/channels/glib/channel/is_typing_channel.rb +34 -34
  3. data/app/channels/glib/channel/online_channel.rb +36 -36
  4. data/app/controllers/concerns/glib/analytics/funnel.rb +61 -61
  5. data/app/controllers/concerns/glib/auth/policy.rb +149 -149
  6. data/app/controllers/concerns/glib/json/dynamic_text.rb +126 -126
  7. data/app/controllers/concerns/glib/json/libs.rb +149 -149
  8. data/app/controllers/concerns/glib/json/new_dynamic_text.rb +122 -122
  9. data/app/controllers/concerns/glib/json/transformation.rb +11 -11
  10. data/app/controllers/concerns/glib/json/traversal.rb +92 -92
  11. data/app/controllers/concerns/glib/json/ui.rb +88 -88
  12. data/app/controllers/concerns/glib/json/validation.rb +13 -13
  13. data/app/controllers/glib/home_controller.rb +54 -54
  14. data/app/helpers/glib/app_feature_support_helper.rb +16 -16
  15. data/app/helpers/glib/dynamic_images_helper.rb +55 -55
  16. data/app/helpers/glib/dynamic_texts_helper.rb +42 -42
  17. data/app/helpers/glib/enum_helper.rb +18 -18
  18. data/app/helpers/glib/forms_helper.rb +15 -15
  19. data/app/helpers/glib/json_ui/abstract_builder.rb +309 -309
  20. data/app/helpers/glib/json_ui/action_builder/dialogs.rb +58 -58
  21. data/app/helpers/glib/json_ui/action_builder/http.rb +39 -39
  22. data/app/helpers/glib/json_ui/action_builder/iap.rb +15 -15
  23. data/app/helpers/glib/json_ui/action_builder/panels.rb +14 -14
  24. data/app/helpers/glib/json_ui/action_builder/sheets.rb +15 -15
  25. data/app/helpers/glib/json_ui/action_builder/snackbars.rb +41 -41
  26. data/app/helpers/glib/json_ui/action_builder/windows.rb +38 -38
  27. data/app/helpers/glib/json_ui/action_builder.rb +140 -140
  28. data/app/helpers/glib/json_ui/analytics_helper.rb +17 -17
  29. data/app/helpers/glib/json_ui/dynamic_field_builders.rb +25 -25
  30. data/app/helpers/glib/json_ui/generic_builders.rb +28 -28
  31. data/app/helpers/glib/json_ui/list_builders.rb +110 -110
  32. data/app/helpers/glib/json_ui/menu_builder.rb +96 -96
  33. data/app/helpers/glib/json_ui/page_helper.rb +221 -221
  34. data/app/helpers/glib/json_ui/response_helper.rb +25 -25
  35. data/app/helpers/glib/json_ui/styling_helper.rb +55 -55
  36. data/app/helpers/glib/json_ui/table_builders.rb +74 -74
  37. data/app/helpers/glib/json_ui/view_builder/banners.rb +26 -26
  38. data/app/helpers/glib/json_ui/view_builder/charts.rb +49 -49
  39. data/app/helpers/glib/json_ui/view_builder/fields.rb +293 -291
  40. data/app/helpers/glib/json_ui/view_builder/iap.rb +11 -11
  41. data/app/helpers/glib/json_ui/view_builder/panels.rb +262 -262
  42. data/app/helpers/glib/json_ui/view_builder.rb +251 -251
  43. data/app/helpers/glib/urls_helper.rb +12 -12
  44. data/app/models/concerns/glib/soft_deletable.rb +73 -73
  45. data/app/models/glib/active_storage/attachment.rb +9 -9
  46. data/app/models/glib/active_storage/blob.rb +9 -9
  47. data/app/models/glib/application_record.rb +18 -18
  48. data/app/models/glib/dynamic_text_record.rb +9 -9
  49. data/app/models/glib/text.rb +95 -95
  50. data/app/policies/glib/application_policy.rb +191 -191
  51. data/app/validators/email_typo_validator.rb +38 -38
  52. data/app/validators/email_validator.rb +7 -7
  53. data/app/validators/url_validator.rb +20 -20
  54. data/app/views/json_ui/garage/_nav_menu.json.jbuilder +72 -72
  55. data/app/views/json_ui/garage/actions/_dialogs.json.jbuilder +104 -104
  56. data/app/views/json_ui/garage/actions/_http.json.jbuilder +24 -24
  57. data/app/views/json_ui/garage/actions/_panels.json.jbuilder +18 -18
  58. data/app/views/json_ui/garage/actions/_reload.json.jbuilder +17 -17
  59. data/app/views/json_ui/garage/actions/_sheets.json.jbuilder +18 -18
  60. data/app/views/json_ui/garage/actions/_snackbars.json.jbuilder +33 -33
  61. data/app/views/json_ui/garage/actions/_timeouts.json.jbuilder +24 -24
  62. data/app/views/json_ui/garage/actions/_windows.json.jbuilder +24 -24
  63. data/app/views/json_ui/garage/actions/dialogs_oauth_post.json.jbuilder +6 -6
  64. data/app/views/json_ui/garage/actions/index.json.jbuilder +24 -24
  65. data/app/views/json_ui/garage/forms/_alert_post_data.json.jbuilder +10 -10
  66. data/app/views/json_ui/garage/forms/basic.json.jbuilder +21 -21
  67. data/app/views/json_ui/garage/forms/basic_post.json.jbuilder +8 -8
  68. data/app/views/json_ui/garage/forms/checkboxes.json.jbuilder +61 -61
  69. data/app/views/json_ui/garage/forms/conditional_value.json.jbuilder +36 -36
  70. data/app/views/json_ui/garage/forms/dynamic_group.json.jbuilder +39 -39
  71. data/app/views/json_ui/garage/forms/dynamic_select.json.jbuilder +24 -24
  72. data/app/views/json_ui/garage/forms/dynamic_select_data.json.jbuilder +38 -38
  73. data/app/views/json_ui/garage/forms/file_upload.json.jbuilder +37 -37
  74. data/app/views/json_ui/garage/forms/floating_submit.json.jbuilder +19 -19
  75. data/app/views/json_ui/garage/forms/generic_post.json.jbuilder +3 -3
  76. data/app/views/json_ui/garage/forms/get_request.json.jbuilder +27 -27
  77. data/app/views/json_ui/garage/forms/index.json.jbuilder +116 -116
  78. data/app/views/json_ui/garage/forms/new_rich_text.json.jbuilder +40 -40
  79. data/app/views/json_ui/garage/forms/online_participant1.json.jbuilder +25 -25
  80. data/app/views/json_ui/garage/forms/online_participant2.json.jbuilder +25 -25
  81. data/app/views/json_ui/garage/forms/payments.json.jbuilder +34 -34
  82. data/app/views/json_ui/garage/forms/pickers.json.jbuilder +89 -81
  83. data/app/views/json_ui/garage/forms/ratings.json.jbuilder +49 -49
  84. data/app/views/json_ui/garage/forms/rich_text.json.jbuilder +40 -40
  85. data/app/views/json_ui/garage/forms/selects.json.jbuilder +91 -91
  86. data/app/views/json_ui/garage/forms/show_hide.json.jbuilder +150 -150
  87. data/app/views/json_ui/garage/forms/styled_boxes.json.jbuilder +35 -35
  88. data/app/views/json_ui/garage/forms/submission_flow.json.jbuilder +17 -17
  89. data/app/views/json_ui/garage/forms/submission_flow_post.json.jbuilder +26 -26
  90. data/app/views/json_ui/garage/forms/submission_indicator.json.jbuilder +63 -63
  91. data/app/views/json_ui/garage/forms/submission_indicator_post.json.jbuilder +25 -25
  92. data/app/views/json_ui/garage/forms/text_validation.json.jbuilder +65 -65
  93. data/app/views/json_ui/garage/forms/timers.json.jbuilder +120 -120
  94. data/app/views/json_ui/garage/home/blank.json.jbuilder +10 -10
  95. data/app/views/json_ui/garage/home/index.json.jbuilder +36 -36
  96. data/app/views/json_ui/garage/home/slow.json.jbuilder +11 -11
  97. data/app/views/json_ui/garage/lists/_autoload_section.json.jbuilder +30 -30
  98. data/app/views/json_ui/garage/lists/autoload_all.json.jbuilder +32 -32
  99. data/app/views/json_ui/garage/lists/autoload_as_needed.json.jbuilder +35 -35
  100. data/app/views/json_ui/garage/lists/autoload_as_needed_responsive_columns.json.jbuilder +27 -27
  101. data/app/views/json_ui/garage/lists/chat_ui.json.jbuilder +94 -94
  102. data/app/views/json_ui/garage/lists/edit_actions.json.jbuilder +62 -62
  103. data/app/views/json_ui/garage/lists/fab.json.jbuilder +12 -12
  104. data/app/views/json_ui/garage/lists/index.json.jbuilder +41 -41
  105. data/app/views/json_ui/garage/lists/reordering.json.jbuilder +34 -34
  106. data/app/views/json_ui/garage/lists/templating.json.jbuilder +35 -35
  107. data/app/views/json_ui/garage/notifications/action_cable.json.jbuilder +114 -114
  108. data/app/views/json_ui/garage/notifications/android_post.json.jbuilder +48 -48
  109. data/app/views/json_ui/garage/notifications/index.json.jbuilder +36 -36
  110. data/app/views/json_ui/garage/notifications/web_socket.json.jbuilder +60 -60
  111. data/app/views/json_ui/garage/pages/flat_centered.json.jbuilder +29 -29
  112. data/app/views/json_ui/garage/pages/full_width.json.jbuilder +29 -29
  113. data/app/views/json_ui/garage/pages/full_width_height.json.jbuilder +16 -16
  114. data/app/views/json_ui/garage/pages/index.json.jbuilder +62 -62
  115. data/app/views/json_ui/garage/pages/layout.json.jbuilder +18 -18
  116. data/app/views/json_ui/garage/pages/lifecycle_hooks.json.jbuilder +13 -13
  117. data/app/views/json_ui/garage/pages/loading_indicator.json.jbuilder +10 -10
  118. data/app/views/json_ui/garage/pages/nav_buttons.json.jbuilder +21 -21
  119. data/app/views/json_ui/garage/pages/nested_scroll.json.jbuilder +40 -40
  120. data/app/views/json_ui/garage/pages/tab_bar.json.jbuilder +92 -92
  121. data/app/views/json_ui/garage/panels/_styled.json.jbuilder +78 -78
  122. data/app/views/json_ui/garage/panels/card.json.jbuilder +4 -4
  123. data/app/views/json_ui/garage/panels/carousel.json.jbuilder +38 -38
  124. data/app/views/json_ui/garage/panels/custom.json.jbuilder +17 -17
  125. data/app/views/json_ui/garage/panels/flow.json.jbuilder +59 -59
  126. data/app/views/json_ui/garage/panels/horizontal.json.jbuilder +101 -101
  127. data/app/views/json_ui/garage/panels/index.json.jbuilder +138 -138
  128. data/app/views/json_ui/garage/panels/outlined.json.jbuilder +4 -4
  129. data/app/views/json_ui/garage/panels/responsive.json.jbuilder +98 -98
  130. data/app/views/json_ui/garage/panels/split.json.jbuilder +182 -182
  131. data/app/views/json_ui/garage/panels/ul.json.jbuilder +33 -33
  132. data/app/views/json_ui/garage/panels/vertical.json.jbuilder +55 -55
  133. data/app/views/json_ui/garage/panels/web.json.jbuilder +15 -15
  134. data/app/views/json_ui/garage/services/dynamic_text.json.jbuilder +13 -13
  135. data/app/views/json_ui/garage/services/image.json.jbuilder +47 -47
  136. data/app/views/json_ui/garage/services/index.json.jbuilder +17 -17
  137. data/app/views/json_ui/garage/tables/_autoload_section.json.jbuilder +16 -16
  138. data/app/views/json_ui/garage/tables/autoload_all.json.jbuilder +43 -43
  139. data/app/views/json_ui/garage/tables/autoload_as_needed.json.jbuilder +50 -50
  140. data/app/views/json_ui/garage/tables/export_import.json.jbuilder +29 -29
  141. data/app/views/json_ui/garage/tables/horizontal_scroll.json.jbuilder +26 -26
  142. data/app/views/json_ui/garage/tables/index.json.jbuilder +25 -25
  143. data/app/views/json_ui/garage/tables/layout.json.jbuilder +40 -40
  144. data/app/views/json_ui/garage/views/_chart_data.json.jbuilder +17 -17
  145. data/app/views/json_ui/garage/views/banners.json.jbuilder +67 -67
  146. data/app/views/json_ui/garage/views/calendar_data.json.jbuilder +30 -30
  147. data/app/views/json_ui/garage/views/charts.json.jbuilder +125 -125
  148. data/app/views/json_ui/garage/views/controls.json.jbuilder +39 -39
  149. data/app/views/json_ui/garage/views/iap.json.jbuilder +21 -21
  150. data/app/views/json_ui/garage/views/icon_names.json.jbuilder +1450 -1450
  151. data/app/views/json_ui/garage/views/icons.json.jbuilder +15 -15
  152. data/app/views/json_ui/garage/views/images.json.jbuilder +89 -89
  153. data/app/views/json_ui/garage/views/index.json.jbuilder +83 -83
  154. data/app/views/json_ui/garage/views/links.json.jbuilder +70 -70
  155. data/app/views/json_ui/garage/views/map_cluster_data.json.jbuilder +41 -41
  156. data/app/views/json_ui/garage/views/map_data.json.jbuilder +51 -51
  157. data/app/views/json_ui/garage/views/maps.json.jbuilder +31 -31
  158. data/app/views/json_ui/garage/views/markdowns.json.jbuilder +41 -41
  159. data/app/views/json_ui/garage/views/misc.json.jbuilder +34 -34
  160. data/app/views/json_ui/garage/views/progress.json.jbuilder +31 -31
  161. data/app/views/json_ui/garage/views/texts.json.jbuilder +35 -35
  162. data/app/views/layouts/json_ui/renderer.html.erb +35 -35
  163. data/config/routes.rb +7 -7
  164. data/lib/generators/glib/install_generator.rb +24 -24
  165. data/lib/generators/templates/20191017062519_create_texts.rb +12 -12
  166. data/lib/generators/templates/20191024063257_add_scope_to_texts.rb +7 -7
  167. data/lib/generators/templates/20191112095018_add_lang_to_texts.rb +7 -7
  168. data/lib/generators/templates/20191126071051_create_active_storage_tables.active_storage.rb +27 -27
  169. data/lib/generators/templates/database.yml +107 -107
  170. data/lib/generators/templates/dynamic_text.rb +2 -2
  171. data/lib/glib/crypt/utils.rb +26 -26
  172. data/lib/glib/dynamic_text/config.rb +21 -21
  173. data/lib/glib/engine.rb +7 -7
  174. data/lib/glib/json_crawler/action_crawler.rb +23 -23
  175. data/lib/glib/json_crawler/action_crawlers/action_http.rb +11 -11
  176. data/lib/glib/json_crawler/action_crawlers/forms_submit.rb +48 -48
  177. data/lib/glib/json_crawler/action_crawlers/menu.rb +12 -12
  178. data/lib/glib/json_crawler/action_crawlers/nav_initiate.rb +19 -19
  179. data/lib/glib/json_crawler/action_crawlers/run_multiple.rb +13 -13
  180. data/lib/glib/json_crawler/action_crawlers/windows_open.rb +33 -33
  181. data/lib/glib/json_crawler/coverage.rb +20 -20
  182. data/lib/glib/json_crawler/http.rb +120 -120
  183. data/lib/glib/json_crawler/router.rb +90 -90
  184. data/lib/glib/json_crawler.rb +11 -11
  185. data/lib/glib/mailer_tester.rb +36 -36
  186. data/lib/glib/test_helpers.rb +52 -52
  187. data/lib/glib/value.rb +7 -7
  188. data/lib/glib/version.rb +5 -5
  189. data/lib/glib-web.rb +9 -9
  190. data/lib/tasks/db.rake +95 -95
  191. metadata +2 -3
@@ -1,309 +1,309 @@
1
- module Glib
2
- module JsonUi
3
- class AbstractBuilder
4
- attr_reader :json, :page
5
-
6
- def initialize(json, page)
7
- @json = json
8
- @page = page
9
- end
10
-
11
- private
12
- def capitalize_first_letter_and_leave_others_alone(str)
13
- str.slice(0, 1).capitalize + str.slice(1..-1)
14
- end
15
-
16
- def add_singleton_element(type, name, *args)
17
- name_components = name.to_s.split('_')
18
- json.set! type, "#{name_components.join('/')}" if type
19
- args = [yield] if block_given?
20
-
21
- # TODO: consider caching these instances
22
- "#{self.class.name}::#{name_components.map { |str| capitalize_first_letter_and_leave_others_alone(str) }.join('::')}".constantize.new(json, @page).props(*args)
23
- end
24
-
25
- def add_element_to_array(type, name, *args)
26
- json.child! do
27
- add_singleton_element type, name, *args
28
- end
29
- end
30
-
31
- # TODO: Consider removing this in favour of non 'v1' suffix
32
- def add_singleton_element_v1(type, name, *args)
33
- name_components = name.to_s.split('_')
34
- json.set! type, "#{name_components.join('/')}-v1" if type
35
- args = [yield] if block_given?
36
- "#{self.class.name}::#{name_components.map { |str| capitalize_first_letter_and_leave_others_alone(str) }.join('::')}".constantize.new(json, @page).props(*args)
37
- end
38
-
39
- # TODO: Consider removing this in favour of non 'v1' suffix
40
- def add_element_to_array_v1(type, name, *args)
41
- json.child! do
42
- add_singleton_element_v1 type, name, *args
43
- end
44
- end
45
-
46
- end
47
-
48
- class JsonUiElement
49
- attr_reader :json, :page
50
-
51
- @@_required_properties = {}
52
-
53
- def initialize(json, page)
54
- @json = json
55
- @page = page
56
- end
57
-
58
- def props(args = {})
59
- @args = args
60
-
61
- if args.is_a? Hash
62
- args.each do |k, v|
63
- send(k, v)
64
- end
65
-
66
- required_properties = @@_required_properties[self.class.component_name] || []
67
- required_properties.each do |prop|
68
- raise "Property required: #{prop}. Properties provided: #{args}. Component: #{self.class.component_name}" unless args[prop].present?
69
- end
70
- else
71
- raise "Invalid properties: #{args}"
72
- end
73
-
74
- created
75
- end
76
-
77
- private
78
- def self.component_name
79
- @component_name ||= self.name.sub('Glib::JsonUi::ActionBuilder::', '')
80
- end
81
-
82
- def self.any(propName)
83
- define_method(propName) do |value|
84
- json.set! propName, value
85
- end
86
- end
87
-
88
- def self.date(propName)
89
- define_method(propName) do |value|
90
- json.set! propName, value&.to_date
91
-
92
- # if (value = value&.to_s)
93
- # if !Rails.env.production?
94
- # raise "Invalid date for #{propName}: #{value}" unless value =~ /^\d{4}-\d{2}-\d{2}$/
95
- # end
96
-
97
- # json.set! propName, value
98
- # end
99
- end
100
- end
101
-
102
- def self.date_time(propName)
103
- define_method(propName) do |value|
104
- json.set! propName, value&.to_datetime
105
-
106
- # if (value = value&.to_s)
107
- # if !Rails.env.production?
108
- # try Date.parse(value) rescue raise "Invalid date: #{value}"
109
- # end
110
-
111
- # json.set! propName, value
112
- # end
113
- end
114
- end
115
-
116
- def self.color(propName)
117
- define_method(propName) do |value|
118
- if (value = value&.to_s)
119
- if !Rails.env.production?
120
- if !value.match /^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/i
121
- raise "Invalid color: #{value}"
122
- end
123
- end
124
-
125
- json.set! propName, value
126
- end
127
- end
128
- end
129
-
130
- def self.length(propName)
131
- define_method(propName) do |value|
132
- if value
133
- if !Rails.env.production?
134
- case value
135
- when 'matchParent'
136
- when 'wrapContent'
137
- else
138
- if !value.is_a? Integer
139
- raise "Invalid length: #{value}"
140
- end
141
- end
142
- end
143
-
144
- json.set! propName, value
145
- end
146
- end
147
- end
148
-
149
- def self.string(propName, options = {})
150
- define_method(propName) do |value|
151
- str = value&.to_s
152
- instance_variable_set("@#{propName}", str) if options[:cache]
153
- json.set! propName, str
154
- end
155
- end
156
-
157
- # Support either string or dynamic_text hash
158
- def self.text(propName, options = {})
159
- define_method(propName) do |value|
160
- if value.is_a?(Hash)
161
- json.set! propName, value
162
- else
163
- json.set! propName, value&.to_s
164
- end
165
- end
166
- end
167
-
168
- def self.int(propName)
169
- define_method(propName) do |value|
170
- json.set! propName, value&.to_i
171
- end
172
- end
173
-
174
- def self.float(propName)
175
- define_method(propName) do |value|
176
- json.set! propName, value&.to_f
177
- end
178
- end
179
-
180
- def self.bool(propName, options = {})
181
- define_method(propName) do |value|
182
- bool = value == true
183
- instance_variable_set("@#{propName}", bool) if options[:cache]
184
- json.set! propName, bool
185
- end
186
- end
187
-
188
- def self.icon(propName, options = {})
189
- define_method(propName) do |value|
190
-
191
- if value.is_a?(Hash)
192
- data = value
193
- name = data[:name]
194
- else
195
- data = {}
196
- name = value
197
- # data = { material: { name: value } }
198
-
199
- # name = value
200
-
201
- # TODO: deprecated
202
- # json.set!(propName) do
203
- # json.name name
204
- # end
205
- end
206
-
207
- json.set!(propName) do
208
- if name
209
- data[:material] ||= {}
210
- data[:material][:name] = name
211
- end
212
-
213
- if (material = data[:material])
214
- json.material do
215
- json.name material[:name]
216
- json.size material[:size] if material[:size]
217
- end
218
- end
219
-
220
- if (fa = data[:fa])
221
- json.fa do
222
- json.name fa[:name]
223
- json.size fa[:size] if fa[:size]
224
- end
225
- end
226
-
227
- if (custom = data[:custom])
228
- json.custom do
229
- json.name custom[:name]
230
- json.size custom[:size] if custom[:size]
231
- end
232
- end
233
-
234
- if (badge = data[:badge])
235
- if badge.is_a?(Hash)
236
- json.badge badge
237
- else
238
- json.badge do
239
- json.text badge
240
- end
241
- end
242
- end
243
-
244
- end
245
-
246
- # raise "Invalid properties: #{options.keys}" if options.size > 0
247
-
248
- # instance_variable_set("@#{propName}", name) if options[:cache]
249
-
250
- end
251
- end
252
-
253
- def self.action(propName)
254
- define_method(propName) do |value|
255
- json.set!(propName) { value.call(page.action_builder) }
256
- end
257
- end
258
-
259
- def self.views(propName)
260
- define_method(propName) do |value|
261
- json.set!(propName) { value.call(page.view_builder) }
262
- end
263
- end
264
-
265
- def self.array(propName)
266
- define_method(propName) do |value|
267
- json.set! propName, value&.to_a
268
- end
269
- end
270
-
271
- def self.hash(propName)
272
- define_method(propName) do |value|
273
- json.set! propName, value
274
- end
275
- end
276
-
277
- def self.menu(propName)
278
- define_method(propName) do |value|
279
- json.set! propName do
280
- value.call(page.menu_builder)
281
- end
282
- end
283
- end
284
-
285
- def self.singleton_array(singletonName, arrayName)
286
- array arrayName
287
-
288
- define_method(singletonName) do |value|
289
- json.set! arrayName, [value]
290
- end
291
- end
292
-
293
- def self.panels_builder(propName, *panelNames)
294
- define_method(propName) do |value|
295
- value.call(page.content_builder(panelNames))
296
- end
297
- end
298
-
299
- def self.required(*prop_names)
300
- @@_required_properties[self.component_name] = prop_names
301
- end
302
-
303
- def created
304
- # To be overridden
305
- end
306
-
307
- end
308
- end
309
- end
1
+ module Glib
2
+ module JsonUi
3
+ class AbstractBuilder
4
+ attr_reader :json, :page
5
+
6
+ def initialize(json, page)
7
+ @json = json
8
+ @page = page
9
+ end
10
+
11
+ private
12
+ def capitalize_first_letter_and_leave_others_alone(str)
13
+ str.slice(0, 1).capitalize + str.slice(1..-1)
14
+ end
15
+
16
+ def add_singleton_element(type, name, *args)
17
+ name_components = name.to_s.split('_')
18
+ json.set! type, "#{name_components.join('/')}" if type
19
+ args = [yield] if block_given?
20
+
21
+ # TODO: consider caching these instances
22
+ "#{self.class.name}::#{name_components.map { |str| capitalize_first_letter_and_leave_others_alone(str) }.join('::')}".constantize.new(json, @page).props(*args)
23
+ end
24
+
25
+ def add_element_to_array(type, name, *args)
26
+ json.child! do
27
+ add_singleton_element type, name, *args
28
+ end
29
+ end
30
+
31
+ # TODO: Consider removing this in favour of non 'v1' suffix
32
+ def add_singleton_element_v1(type, name, *args)
33
+ name_components = name.to_s.split('_')
34
+ json.set! type, "#{name_components.join('/')}-v1" if type
35
+ args = [yield] if block_given?
36
+ "#{self.class.name}::#{name_components.map { |str| capitalize_first_letter_and_leave_others_alone(str) }.join('::')}".constantize.new(json, @page).props(*args)
37
+ end
38
+
39
+ # TODO: Consider removing this in favour of non 'v1' suffix
40
+ def add_element_to_array_v1(type, name, *args)
41
+ json.child! do
42
+ add_singleton_element_v1 type, name, *args
43
+ end
44
+ end
45
+
46
+ end
47
+
48
+ class JsonUiElement
49
+ attr_reader :json, :page
50
+
51
+ @@_required_properties = {}
52
+
53
+ def initialize(json, page)
54
+ @json = json
55
+ @page = page
56
+ end
57
+
58
+ def props(args = {})
59
+ @args = args
60
+
61
+ if args.is_a? Hash
62
+ args.each do |k, v|
63
+ send(k, v)
64
+ end
65
+
66
+ required_properties = @@_required_properties[self.class.component_name] || []
67
+ required_properties.each do |prop|
68
+ raise "Property required: #{prop}. Properties provided: #{args}. Component: #{self.class.component_name}" unless args[prop].present?
69
+ end
70
+ else
71
+ raise "Invalid properties: #{args}"
72
+ end
73
+
74
+ created
75
+ end
76
+
77
+ private
78
+ def self.component_name
79
+ @component_name ||= self.name.sub('Glib::JsonUi::ActionBuilder::', '')
80
+ end
81
+
82
+ def self.any(propName)
83
+ define_method(propName) do |value|
84
+ json.set! propName, value
85
+ end
86
+ end
87
+
88
+ def self.date(propName)
89
+ define_method(propName) do |value|
90
+ json.set! propName, value&.to_date
91
+
92
+ # if (value = value&.to_s)
93
+ # if !Rails.env.production?
94
+ # raise "Invalid date for #{propName}: #{value}" unless value =~ /^\d{4}-\d{2}-\d{2}$/
95
+ # end
96
+
97
+ # json.set! propName, value
98
+ # end
99
+ end
100
+ end
101
+
102
+ def self.date_time(propName)
103
+ define_method(propName) do |value|
104
+ json.set! propName, value&.to_datetime
105
+
106
+ # if (value = value&.to_s)
107
+ # if !Rails.env.production?
108
+ # try Date.parse(value) rescue raise "Invalid date: #{value}"
109
+ # end
110
+
111
+ # json.set! propName, value
112
+ # end
113
+ end
114
+ end
115
+
116
+ def self.color(propName)
117
+ define_method(propName) do |value|
118
+ if (value = value&.to_s)
119
+ if !Rails.env.production?
120
+ if !value.match /^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/i
121
+ raise "Invalid color: #{value}"
122
+ end
123
+ end
124
+
125
+ json.set! propName, value
126
+ end
127
+ end
128
+ end
129
+
130
+ def self.length(propName)
131
+ define_method(propName) do |value|
132
+ if value
133
+ if !Rails.env.production?
134
+ case value
135
+ when 'matchParent'
136
+ when 'wrapContent'
137
+ else
138
+ if !value.is_a? Integer
139
+ raise "Invalid length: #{value}"
140
+ end
141
+ end
142
+ end
143
+
144
+ json.set! propName, value
145
+ end
146
+ end
147
+ end
148
+
149
+ def self.string(propName, options = {})
150
+ define_method(propName) do |value|
151
+ str = value&.to_s
152
+ instance_variable_set("@#{propName}", str) if options[:cache]
153
+ json.set! propName, str
154
+ end
155
+ end
156
+
157
+ # Support either string or dynamic_text hash
158
+ def self.text(propName, options = {})
159
+ define_method(propName) do |value|
160
+ if value.is_a?(Hash)
161
+ json.set! propName, value
162
+ else
163
+ json.set! propName, value&.to_s
164
+ end
165
+ end
166
+ end
167
+
168
+ def self.int(propName)
169
+ define_method(propName) do |value|
170
+ json.set! propName, value&.to_i
171
+ end
172
+ end
173
+
174
+ def self.float(propName)
175
+ define_method(propName) do |value|
176
+ json.set! propName, value&.to_f
177
+ end
178
+ end
179
+
180
+ def self.bool(propName, options = {})
181
+ define_method(propName) do |value|
182
+ bool = value == true
183
+ instance_variable_set("@#{propName}", bool) if options[:cache]
184
+ json.set! propName, bool
185
+ end
186
+ end
187
+
188
+ def self.icon(propName, options = {})
189
+ define_method(propName) do |value|
190
+
191
+ if value.is_a?(Hash)
192
+ data = value
193
+ name = data[:name]
194
+ else
195
+ data = {}
196
+ name = value
197
+ # data = { material: { name: value } }
198
+
199
+ # name = value
200
+
201
+ # TODO: deprecated
202
+ # json.set!(propName) do
203
+ # json.name name
204
+ # end
205
+ end
206
+
207
+ json.set!(propName) do
208
+ if name
209
+ data[:material] ||= {}
210
+ data[:material][:name] = name
211
+ end
212
+
213
+ if (material = data[:material])
214
+ json.material do
215
+ json.name material[:name]
216
+ json.size material[:size] if material[:size]
217
+ end
218
+ end
219
+
220
+ if (fa = data[:fa])
221
+ json.fa do
222
+ json.name fa[:name]
223
+ json.size fa[:size] if fa[:size]
224
+ end
225
+ end
226
+
227
+ if (custom = data[:custom])
228
+ json.custom do
229
+ json.name custom[:name]
230
+ json.size custom[:size] if custom[:size]
231
+ end
232
+ end
233
+
234
+ if (badge = data[:badge])
235
+ if badge.is_a?(Hash)
236
+ json.badge badge
237
+ else
238
+ json.badge do
239
+ json.text badge
240
+ end
241
+ end
242
+ end
243
+
244
+ end
245
+
246
+ # raise "Invalid properties: #{options.keys}" if options.size > 0
247
+
248
+ # instance_variable_set("@#{propName}", name) if options[:cache]
249
+
250
+ end
251
+ end
252
+
253
+ def self.action(propName)
254
+ define_method(propName) do |value|
255
+ json.set!(propName) { value.call(page.action_builder) }
256
+ end
257
+ end
258
+
259
+ def self.views(propName)
260
+ define_method(propName) do |value|
261
+ json.set!(propName) { value.call(page.view_builder) }
262
+ end
263
+ end
264
+
265
+ def self.array(propName)
266
+ define_method(propName) do |value|
267
+ json.set! propName, value&.to_a
268
+ end
269
+ end
270
+
271
+ def self.hash(propName)
272
+ define_method(propName) do |value|
273
+ json.set! propName, value
274
+ end
275
+ end
276
+
277
+ def self.menu(propName)
278
+ define_method(propName) do |value|
279
+ json.set! propName do
280
+ value.call(page.menu_builder)
281
+ end
282
+ end
283
+ end
284
+
285
+ def self.singleton_array(singletonName, arrayName)
286
+ array arrayName
287
+
288
+ define_method(singletonName) do |value|
289
+ json.set! arrayName, [value]
290
+ end
291
+ end
292
+
293
+ def self.panels_builder(propName, *panelNames)
294
+ define_method(propName) do |value|
295
+ value.call(page.content_builder(panelNames))
296
+ end
297
+ end
298
+
299
+ def self.required(*prop_names)
300
+ @@_required_properties[self.component_name] = prop_names
301
+ end
302
+
303
+ def created
304
+ # To be overridden
305
+ end
306
+
307
+ end
308
+ end
309
+ end