glib-web 0.5.52 → 0.5.53

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