glib-web 0.5.5
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 +7 -0
- data/app/controllers/concerns/glib/auth/policy.rb +148 -0
- data/app/controllers/concerns/glib/json/dynamic_text.rb +126 -0
- data/app/controllers/concerns/glib/json/libs.rb +144 -0
- data/app/controllers/concerns/glib/json/new_dynamic_text.rb +122 -0
- data/app/controllers/concerns/glib/json/transformation.rb +11 -0
- data/app/controllers/concerns/glib/json/traversal.rb +85 -0
- data/app/controllers/concerns/glib/json/ui.rb +70 -0
- data/app/controllers/concerns/glib/json/validation.rb +13 -0
- data/app/controllers/glib/home_controller.rb +16 -0
- data/app/helpers/glib/app_feature_support_helper.rb +16 -0
- data/app/helpers/glib/dynamic_images_helper.rb +52 -0
- data/app/helpers/glib/dynamic_texts_helper.rb +42 -0
- data/app/helpers/glib/forms_helper.rb +15 -0
- data/app/helpers/glib/json_ui/abstract_builder.rb +281 -0
- data/app/helpers/glib/json_ui/action_builder.rb +81 -0
- data/app/helpers/glib/json_ui/action_builder/dialogs.rb +58 -0
- data/app/helpers/glib/json_ui/action_builder/http.rb +19 -0
- data/app/helpers/glib/json_ui/action_builder/sheets.rb +15 -0
- data/app/helpers/glib/json_ui/action_builder/snackbars.rb +41 -0
- data/app/helpers/glib/json_ui/action_builder/windows.rb +25 -0
- data/app/helpers/glib/json_ui/dynamic_field_builders.rb +25 -0
- data/app/helpers/glib/json_ui/generic_builders.rb +28 -0
- data/app/helpers/glib/json_ui/list_builders.rb +87 -0
- data/app/helpers/glib/json_ui/menu_builder.rb +52 -0
- data/app/helpers/glib/json_ui/page_helper.rb +187 -0
- data/app/helpers/glib/json_ui/response_helper.rb +23 -0
- data/app/helpers/glib/json_ui/split_builders.rb +32 -0
- data/app/helpers/glib/json_ui/styling_helper.rb +25 -0
- data/app/helpers/glib/json_ui/table_builders.rb +74 -0
- data/app/helpers/glib/json_ui/view_builder.rb +185 -0
- data/app/helpers/glib/json_ui/view_builder/banners.rb +24 -0
- data/app/helpers/glib/json_ui/view_builder/charts.rb +33 -0
- data/app/helpers/glib/json_ui/view_builder/fields.rb +213 -0
- data/app/helpers/glib/json_ui/view_builder/panels.rb +219 -0
- data/app/models/glib/active_storage/attachment.rb +9 -0
- data/app/models/glib/active_storage/blob.rb +9 -0
- data/app/models/glib/dynamic_text_record.rb +9 -0
- data/app/models/glib/text.rb +96 -0
- data/app/policies/glib/application_policy.rb +164 -0
- data/app/validators/email_typo_validator.rb +38 -0
- data/app/validators/email_validator.rb +7 -0
- data/app/validators/url_validator.rb +20 -0
- data/app/views/app/views/json_ui/vue/renderer.html.erb +35 -0
- data/app/views/json_ui/garage/_nav_menu.json.jbuilder +71 -0
- data/app/views/json_ui/garage/actions/_dialogs.json.jbuilder +104 -0
- data/app/views/json_ui/garage/actions/_http.json.jbuilder +18 -0
- data/app/views/json_ui/garage/actions/_reload.json.jbuilder +17 -0
- data/app/views/json_ui/garage/actions/_sheets.json.jbuilder +19 -0
- data/app/views/json_ui/garage/actions/_snackbars.json.jbuilder +33 -0
- data/app/views/json_ui/garage/actions/_timeouts.json.jbuilder +18 -0
- data/app/views/json_ui/garage/actions/_windows.json.jbuilder +24 -0
- data/app/views/json_ui/garage/actions/dialogs_oauth_post.json.jbuilder +6 -0
- data/app/views/json_ui/garage/actions/index.json.jbuilder +23 -0
- data/app/views/json_ui/garage/forms/_alert_post_data.json.jbuilder +7 -0
- data/app/views/json_ui/garage/forms/basic.json.jbuilder +34 -0
- data/app/views/json_ui/garage/forms/basic_post.json.jbuilder +8 -0
- data/app/views/json_ui/garage/forms/checkboxes.json.jbuilder +44 -0
- data/app/views/json_ui/garage/forms/dynamic_group.json.jbuilder +41 -0
- data/app/views/json_ui/garage/forms/dynamic_select.json.jbuilder +25 -0
- data/app/views/json_ui/garage/forms/dynamic_select_data.json.jbuilder +38 -0
- data/app/views/json_ui/garage/forms/file_upload.json.jbuilder +58 -0
- data/app/views/json_ui/garage/forms/floating_submit.json.jbuilder +31 -0
- data/app/views/json_ui/garage/forms/generic_post.json.jbuilder +3 -0
- data/app/views/json_ui/garage/forms/get_request.json.jbuilder +28 -0
- data/app/views/json_ui/garage/forms/index.json.jbuilder +101 -0
- data/app/views/json_ui/garage/forms/pickers.json.jbuilder +46 -0
- data/app/views/json_ui/garage/forms/rich_text.json.jbuilder +40 -0
- data/app/views/json_ui/garage/forms/selects.json.jbuilder +70 -0
- data/app/views/json_ui/garage/forms/show_hide.json.jbuilder +88 -0
- data/app/views/json_ui/garage/forms/styled_boxes.json.jbuilder +32 -0
- data/app/views/json_ui/garage/forms/submission_flow.json.jbuilder +17 -0
- data/app/views/json_ui/garage/forms/submission_flow_post.json.jbuilder +24 -0
- data/app/views/json_ui/garage/forms/submission_indicator.json.jbuilder +63 -0
- data/app/views/json_ui/garage/forms/submission_indicator_post.json.jbuilder +25 -0
- data/app/views/json_ui/garage/forms/text_validation.json.jbuilder +22 -0
- data/app/views/json_ui/garage/home/blank.json.jbuilder +11 -0
- data/app/views/json_ui/garage/home/index.json.jbuilder +32 -0
- data/app/views/json_ui/garage/home/slow.json.jbuilder +11 -0
- data/app/views/json_ui/garage/lists/_infinite_scroll_section.json.jbuilder +20 -0
- data/app/views/json_ui/garage/lists/edit_actions.json.jbuilder +19 -0
- data/app/views/json_ui/garage/lists/fab.json.jbuilder +14 -0
- data/app/views/json_ui/garage/lists/index.json.jbuilder +23 -0
- data/app/views/json_ui/garage/lists/infinite_scroll.json.jbuilder +38 -0
- data/app/views/json_ui/garage/lists/templating.json.jbuilder +35 -0
- data/app/views/json_ui/garage/notifications/index.json.jbuilder +18 -0
- data/app/views/json_ui/garage/notifications/web_socket.json.jbuilder +60 -0
- data/app/views/json_ui/garage/pages/flat_centered.json.jbuilder +29 -0
- data/app/views/json_ui/garage/pages/full_width.json.jbuilder +29 -0
- data/app/views/json_ui/garage/pages/full_width_height.json.jbuilder +16 -0
- data/app/views/json_ui/garage/pages/index.json.jbuilder +47 -0
- data/app/views/json_ui/garage/pages/layout.json.jbuilder +19 -0
- data/app/views/json_ui/garage/pages/loading_indicator.json.jbuilder +10 -0
- data/app/views/json_ui/garage/pages/nav_buttons.json.jbuilder +21 -0
- data/app/views/json_ui/garage/pages/tab_bar.json.jbuilder +27 -0
- data/app/views/json_ui/garage/panels/_styled.json.jbuilder +78 -0
- data/app/views/json_ui/garage/panels/card.json.jbuilder +4 -0
- data/app/views/json_ui/garage/panels/carousel.json.jbuilder +16 -0
- data/app/views/json_ui/garage/panels/custom.json.jbuilder +17 -0
- data/app/views/json_ui/garage/panels/flow.json.jbuilder +49 -0
- data/app/views/json_ui/garage/panels/horizontal.json.jbuilder +91 -0
- data/app/views/json_ui/garage/panels/index.json.jbuilder +132 -0
- data/app/views/json_ui/garage/panels/outlined.json.jbuilder +4 -0
- data/app/views/json_ui/garage/panels/responsive.json.jbuilder +88 -0
- data/app/views/json_ui/garage/panels/split.json.jbuilder +183 -0
- data/app/views/json_ui/garage/panels/vertical.json.jbuilder +50 -0
- data/app/views/json_ui/garage/services/dynamic_text.json.jbuilder +13 -0
- data/app/views/json_ui/garage/services/image.json.jbuilder +47 -0
- data/app/views/json_ui/garage/services/index.json.jbuilder +17 -0
- data/app/views/json_ui/garage/tables/_autoload_section.json.jbuilder +13 -0
- data/app/views/json_ui/garage/tables/autoload_all.json.jbuilder +38 -0
- data/app/views/json_ui/garage/tables/autoload_as_needed.json.jbuilder +39 -0
- data/app/views/json_ui/garage/tables/export_import.json.jbuilder +29 -0
- data/app/views/json_ui/garage/tables/horizontal_scroll.json.jbuilder +26 -0
- data/app/views/json_ui/garage/tables/index.json.jbuilder +26 -0
- data/app/views/json_ui/garage/tables/layout.json.jbuilder +38 -0
- data/app/views/json_ui/garage/views/_chart_data.json.jbuilder +17 -0
- data/app/views/json_ui/garage/views/banners.json.jbuilder +51 -0
- data/app/views/json_ui/garage/views/calendar_data.json.jbuilder +30 -0
- data/app/views/json_ui/garage/views/carousels.json.jbuilder +37 -0
- data/app/views/json_ui/garage/views/charts.json.jbuilder +115 -0
- data/app/views/json_ui/garage/views/images.json.jbuilder +89 -0
- data/app/views/json_ui/garage/views/index.json.jbuilder +48 -0
- data/app/views/json_ui/garage/views/links.json.jbuilder +70 -0
- data/app/views/json_ui/garage/views/map_data.json.jbuilder +43 -0
- data/app/views/json_ui/garage/views/markdowns.json.jbuilder +41 -0
- data/app/views/json_ui/garage/views/misc.json.jbuilder +34 -0
- data/app/views/json_ui/garage/views/texts.json.jbuilder +41 -0
- data/app/views/layouts/json_ui/renderer.html.erb +32 -0
- data/config/routes.rb +8 -0
- data/lib/generators/glib/install_generator.rb +24 -0
- data/lib/generators/templates/20191017062519_create_texts.rb +12 -0
- data/lib/generators/templates/20191024063257_add_scope_to_texts.rb +7 -0
- data/lib/generators/templates/20191112095018_add_lang_to_texts.rb +7 -0
- data/lib/generators/templates/20191126071051_create_active_storage_tables.active_storage.rb +27 -0
- data/lib/generators/templates/database.yml +107 -0
- data/lib/generators/templates/dynamic_text.rb +2 -0
- data/lib/glib-web.rb +8 -0
- data/lib/glib/crypt.rb +1 -0
- data/lib/glib/crypt/utils.rb +26 -0
- data/lib/glib/dynamic_text.rb +1 -0
- data/lib/glib/dynamic_text/config.rb +21 -0
- data/lib/glib/engine.rb +7 -0
- data/lib/glib/json_crawler.rb +10 -0
- data/lib/glib/json_crawler/action_crawler.rb +20 -0
- data/lib/glib/json_crawler/action_crawlers/action_http.rb +14 -0
- data/lib/glib/json_crawler/action_crawlers/forms_submit.rb +48 -0
- data/lib/glib/json_crawler/action_crawlers/menu.rb +12 -0
- data/lib/glib/json_crawler/action_crawlers/nav_initiate.rb +15 -0
- data/lib/glib/json_crawler/action_crawlers/windows_open.rb +28 -0
- data/lib/glib/json_crawler/coverage.rb +20 -0
- data/lib/glib/json_crawler/http.rb +120 -0
- data/lib/glib/json_crawler/router.rb +86 -0
- data/lib/glib/test_helpers.rb +40 -0
- data/lib/glib/value.rb +7 -0
- data/lib/glib/version.rb +5 -0
- data/lib/tasks/db.rake +95 -0
- metadata +246 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module Glib::Json::Transformation
|
|
2
|
+
def json_transformation_start
|
|
3
|
+
if request.format == 'json'
|
|
4
|
+
@__transformed_json ||= JSON.parse(response.body) rescue nil
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def __json_transformation_commit
|
|
9
|
+
response.body = @__transformed_json.to_json if @__transformed_json
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
module Glib::Json::Traversal
|
|
2
|
+
def __json_traversal_on_traverse(&block)
|
|
3
|
+
@__json_traversal_on_traverses ||= []
|
|
4
|
+
@__json_traversal_on_traverses << block
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def __json_traversal_on_complete(&block)
|
|
8
|
+
@__json_traversal_on_completes ||= []
|
|
9
|
+
@__json_traversal_on_completes << block
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def __json_traversal_perform
|
|
13
|
+
if (hash = json_transformation_start).is_a?(Hash)
|
|
14
|
+
traverse hash['header']&.[]('childViews')
|
|
15
|
+
traverse hash['body']&.[]('childViews')
|
|
16
|
+
traverse hash['footer']&.[]('childViews')
|
|
17
|
+
|
|
18
|
+
@__json_traversal_on_completes.each do |block|
|
|
19
|
+
block.call
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def traverse(views)
|
|
25
|
+
Visitor.new.traverse_multiple views, ->(view) do
|
|
26
|
+
@__json_traversal_on_traverses.each do |block|
|
|
27
|
+
block.call(view)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class Visitor
|
|
35
|
+
# Used in test crawler
|
|
36
|
+
attr_reader :forms
|
|
37
|
+
|
|
38
|
+
def initialize
|
|
39
|
+
@forms = []
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def traverse_multiple(views, block)
|
|
43
|
+
if views.is_a? Array
|
|
44
|
+
views.each do |view|
|
|
45
|
+
case view['view']
|
|
46
|
+
when 'panels/form-v1'
|
|
47
|
+
@forms << view
|
|
48
|
+
traverse_single view, block
|
|
49
|
+
@forms.pop
|
|
50
|
+
else
|
|
51
|
+
traverse_single view, block
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def traverse_vertical_content(view, block)
|
|
58
|
+
traverse_multiple view['childViews'], block if view
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def traverse_single(view, block)
|
|
62
|
+
block.call view
|
|
63
|
+
|
|
64
|
+
# Generic view children
|
|
65
|
+
traverse_multiple view['childViews'], block
|
|
66
|
+
|
|
67
|
+
# Generic menu buttons
|
|
68
|
+
traverse_multiple view['buttons'], block
|
|
69
|
+
|
|
70
|
+
# Split panel
|
|
71
|
+
traverse_vertical_content view['left'], block
|
|
72
|
+
traverse_vertical_content view['center'], block
|
|
73
|
+
traverse_vertical_content view['right'], block
|
|
74
|
+
|
|
75
|
+
# TODO: crawl header and footer
|
|
76
|
+
# Table/List
|
|
77
|
+
if (sections = view['sections']).is_a? Array
|
|
78
|
+
sections.each do |section|
|
|
79
|
+
# Table
|
|
80
|
+
traverse_multiple section['rows'], block
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
module Glib::Json::Ui
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
included do
|
|
5
|
+
rescue_from ActionController::UnknownFormat do |exception|
|
|
6
|
+
if json_ui_activated?
|
|
7
|
+
# Tell `__json_ui_start()` to avoid rendering this page while still retaining the `_render` param
|
|
8
|
+
# so that the page remains linking to other json_ui pages.
|
|
9
|
+
redirect_to url_for(format: nil, _skip_render: true)
|
|
10
|
+
else
|
|
11
|
+
raise exception
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Override
|
|
17
|
+
def form_authenticity_token(*args)
|
|
18
|
+
Rails.env.test? ? 'test_token' : super
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# NOTE: Override default_url_options and call this method
|
|
22
|
+
def json_ui_url_options
|
|
23
|
+
options = {}
|
|
24
|
+
options[:_render] = params[:_render]
|
|
25
|
+
options[:_locale] = params[:_locale]
|
|
26
|
+
options[:format] = :json if request.format == :json
|
|
27
|
+
options
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def json_ui_activated?
|
|
31
|
+
@__json_ui_activated
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def __json_ui_start(options)
|
|
35
|
+
@__json_ui_activated = false
|
|
36
|
+
@__json_ui_rendering = nil
|
|
37
|
+
if options[:when] == :always || params[:_render] == 'v1'
|
|
38
|
+
@__json_ui_activated = true
|
|
39
|
+
request.variant = :ui
|
|
40
|
+
|
|
41
|
+
if request.format.html? && params[:_skip_render] != 'true'
|
|
42
|
+
@__json_ui_rendering = :vue
|
|
43
|
+
request.format = 'json'
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def __json_ui_commit(options)
|
|
49
|
+
return if response.status >= 300
|
|
50
|
+
|
|
51
|
+
case @__json_ui_rendering
|
|
52
|
+
when :vue
|
|
53
|
+
if (hash = json_transformation_start).is_a?(Hash)
|
|
54
|
+
__json_ui_vue(hash, options)
|
|
55
|
+
else
|
|
56
|
+
raise "Invalid JSON UI payload: #{hash}"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
def __json_ui_vue(hash, options)
|
|
64
|
+
renderer_path = options[:renderer_path]
|
|
65
|
+
@__json_ui_orig_page = response.body
|
|
66
|
+
response.body = render_to_string(template: renderer_path, layout: 'json_ui/renderer', content_type: 'text/html', locals: { page: hash, options: options })
|
|
67
|
+
|
|
68
|
+
# response.body = render_to_string(template: renderer_path, layout: false, content_type: 'text/html', locals: { page: hash, options: options })
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Glib::Json::Validation
|
|
2
|
+
def __json_validate_perform
|
|
3
|
+
if Rails.env.development? && params[:_validate] == 'true'
|
|
4
|
+
if (hash = json_transformation_start).is_a?(Hash)
|
|
5
|
+
json_validate = JSONValidate.new(hash)
|
|
6
|
+
response_message = json_validate.valid?
|
|
7
|
+
hash[:_json] = {
|
|
8
|
+
validationErrors: response_message
|
|
9
|
+
}
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Glib
|
|
2
|
+
class HomeController < ApplicationController
|
|
3
|
+
if try(:glib_auth_inited?)
|
|
4
|
+
skip_before_action :glib_load_resource
|
|
5
|
+
skip_before_action :glib_authorize_resource
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def json_ui_garage
|
|
9
|
+
@path_prefix = 'json_ui/garage'
|
|
10
|
+
|
|
11
|
+
# We can't use prepend_view_path because it affects the app, not the gem
|
|
12
|
+
path = "#{@path_prefix}/#{params[:path] || 'home/index'}"
|
|
13
|
+
render path
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Glib
|
|
2
|
+
module AppFeatureSupportHelper
|
|
3
|
+
def glib_app_feature_supported?(name, app_version, dictionary)
|
|
4
|
+
device = (app_device_os || :default).to_sym
|
|
5
|
+
|
|
6
|
+
version = dictionary[name.to_sym].try(:[], device)
|
|
7
|
+
except = dictionary[name.to_sym].try(:[], :except).try(:[], device)
|
|
8
|
+
|
|
9
|
+
!version.nil? && (version == :all || glib_app_version_gte(version, app_version)) && (except.nil? || except.to_s != app_version)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def glib_app_version_gte(feature_version, app_version)
|
|
13
|
+
app_version.blank? || Gem::Version.new(app_version) >= Gem::Version.new(feature_version)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module Glib
|
|
2
|
+
module DynamicImagesHelper
|
|
3
|
+
# NOTE: The bucket should probably be set as a parameter for json_libs
|
|
4
|
+
def dynamic_image_url(blob_key, width: 100, height: 100, fit: 'clip', bucket: Rails.application.config.try(:aws_s3_bucket))
|
|
5
|
+
return unless blob_key.present?
|
|
6
|
+
|
|
7
|
+
full_params_hash = {
|
|
8
|
+
bucket_name: bucket,
|
|
9
|
+
blob_key: blob_key,
|
|
10
|
+
w: width,
|
|
11
|
+
h: height,
|
|
12
|
+
fit: fit,
|
|
13
|
+
expires: 1.hours.from_now.to_i
|
|
14
|
+
}
|
|
15
|
+
request_params_hash = full_params_hash.except(:bucket_name, :blob_key)
|
|
16
|
+
|
|
17
|
+
if (private_key = ENV['PRIVATE_API_KEY'])
|
|
18
|
+
encryption_service = EncryptionService.new(bucket, private_key)
|
|
19
|
+
signature = encryption_service.encrypt(full_params_hash)
|
|
20
|
+
request_params_hash = request_params_hash.merge(signature: signature)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# TODO: This should probably be set as a parameter for json_libs
|
|
24
|
+
uri = URI::HTTPS.build(
|
|
25
|
+
host: 'imageserver-demo.herokuapp.com',
|
|
26
|
+
path: "/image/#{bucket}/#{blob_key}",
|
|
27
|
+
query: request_params_hash.to_param
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
uri.to_s
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
EncryptionService = Struct.new(:salt, :private_key) do
|
|
34
|
+
def encrypt(value)
|
|
35
|
+
encryptor.encrypt_and_sign(value)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def decrypt(value)
|
|
39
|
+
encryptor.decrypt_and_verify(value)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
def encryptor
|
|
44
|
+
@encryptor ||= begin
|
|
45
|
+
key_len = ActiveSupport::MessageEncryptor.key_len
|
|
46
|
+
key = ActiveSupport::KeyGenerator.new(private_key).generate_key(salt, key_len)
|
|
47
|
+
ActiveSupport::MessageEncryptor.new(key)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module Glib
|
|
2
|
+
module DynamicTextsHelper
|
|
3
|
+
def dt(key, default_value = '', **args)
|
|
4
|
+
new_key = key
|
|
5
|
+
options = {
|
|
6
|
+
scope: args.fetch(:scope, 'itinerarybuilder'),
|
|
7
|
+
lang: args.fetch(:lang, 'en')
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if key.starts_with?('.')
|
|
11
|
+
new_key = "#{controller_name}.#{action_name}#{key}"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
content, text_object = Glib::Text.get_content(new_key, default_value, options: options)
|
|
15
|
+
content = content.gsub(/\{\{(\w+)\}\}/) { args.fetch($1.to_sym, "{{#{$1}}}") }
|
|
16
|
+
|
|
17
|
+
if text_object.images.attached?
|
|
18
|
+
content = content.gsub(/\{\{image(\d)\}\}/) {
|
|
19
|
+
if image = text_object.images[$1.to_i - 1]
|
|
20
|
+
dynamic_image_url(image.blob.key)
|
|
21
|
+
else
|
|
22
|
+
"{{image#{$1}}}"
|
|
23
|
+
end
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
content
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def dt_json(key, default_value = '', **args)
|
|
31
|
+
new_key = key
|
|
32
|
+
|
|
33
|
+
if key.starts_with?('.')
|
|
34
|
+
new_key = "#{controller_name}.#{action_name}#{key}"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
{
|
|
38
|
+
dt_key: new_key
|
|
39
|
+
}.merge(args)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +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
|
|
@@ -0,0 +1,281 @@
|
|
|
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
|
+
|
|
72
|
+
def self.date(propName)
|
|
73
|
+
define_method(propName) do |value|
|
|
74
|
+
json.set! propName, value&.to_date
|
|
75
|
+
|
|
76
|
+
# if (value = value&.to_s)
|
|
77
|
+
# if !Rails.env.production?
|
|
78
|
+
# raise "Invalid date for #{propName}: #{value}" unless value =~ /^\d{4}-\d{2}-\d{2}$/
|
|
79
|
+
# end
|
|
80
|
+
|
|
81
|
+
# json.set! propName, value
|
|
82
|
+
# end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def self.date_time(propName)
|
|
87
|
+
define_method(propName) do |value|
|
|
88
|
+
json.set! propName, value&.to_datetime
|
|
89
|
+
|
|
90
|
+
# if (value = value&.to_s)
|
|
91
|
+
# if !Rails.env.production?
|
|
92
|
+
# try Date.parse(value) rescue raise "Invalid date: #{value}"
|
|
93
|
+
# end
|
|
94
|
+
|
|
95
|
+
# json.set! propName, value
|
|
96
|
+
# end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def self.color propName
|
|
101
|
+
define_method(propName) do |value|
|
|
102
|
+
if (value = value&.to_s)
|
|
103
|
+
if !Rails.env.production?
|
|
104
|
+
if !value.match /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/i
|
|
105
|
+
raise "Invalid color: #{value}"
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
json.set! propName, value
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def self.length propName
|
|
115
|
+
define_method(propName) do |value|
|
|
116
|
+
if value
|
|
117
|
+
if !Rails.env.production?
|
|
118
|
+
case value
|
|
119
|
+
when 'matchParent'
|
|
120
|
+
when 'wrapContent'
|
|
121
|
+
else
|
|
122
|
+
if !value.is_a? Integer
|
|
123
|
+
raise "Invalid length: #{value}"
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
json.set! propName, value
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def self.string propName, options = {}
|
|
134
|
+
define_method(propName) do |value|
|
|
135
|
+
str = value&.to_s
|
|
136
|
+
instance_variable_set("@#{propName}", str) if options[:cache]
|
|
137
|
+
json.set! propName, str
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Support either string or dynamic_text hash
|
|
142
|
+
def self.text propName, options = {}
|
|
143
|
+
define_method(propName) do |value|
|
|
144
|
+
if value.is_a?(Hash)
|
|
145
|
+
json.set! propName, value
|
|
146
|
+
else
|
|
147
|
+
json.set! propName, value&.to_s
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def self.int propName
|
|
153
|
+
define_method(propName) do |value|
|
|
154
|
+
json.set! propName, value&.to_i
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def self.float propName
|
|
159
|
+
define_method(propName) do |value|
|
|
160
|
+
json.set! propName, value&.to_f
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def self.bool propName, options = {}
|
|
165
|
+
define_method(propName) do |value|
|
|
166
|
+
bool = value == true
|
|
167
|
+
instance_variable_set("@#{propName}", bool) if options[:cache]
|
|
168
|
+
json.set! propName, bool
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def self.icon propName, options = {}
|
|
173
|
+
define_method(propName) do |value|
|
|
174
|
+
|
|
175
|
+
if value.is_a?(Hash)
|
|
176
|
+
data = value
|
|
177
|
+
name = data[:name]
|
|
178
|
+
else
|
|
179
|
+
data = {}
|
|
180
|
+
name = value
|
|
181
|
+
# data = { material: { name: value } }
|
|
182
|
+
|
|
183
|
+
# name = value
|
|
184
|
+
|
|
185
|
+
# TODO: deprecated
|
|
186
|
+
# json.set!(propName) do
|
|
187
|
+
# json.name name
|
|
188
|
+
# end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
json.set!(propName) do
|
|
192
|
+
if name
|
|
193
|
+
data[:material] ||= {}
|
|
194
|
+
data[:material][:name] = name
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
if (material = data[:material])
|
|
198
|
+
json.material do
|
|
199
|
+
json.name material[:name]
|
|
200
|
+
json.size material[:size] if material[:size]
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
if (fa = data[:fa])
|
|
205
|
+
json.fa do
|
|
206
|
+
json.name fa[:name]
|
|
207
|
+
json.size fa[:size] if fa[:size]
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
if (custom = data[:custom])
|
|
212
|
+
json.custom do
|
|
213
|
+
json.name custom[:name]
|
|
214
|
+
json.size custom[:size] if custom[:size]
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
if (badge = data[:badge])
|
|
219
|
+
if badge.is_a?(Hash)
|
|
220
|
+
json.badge badge
|
|
221
|
+
else
|
|
222
|
+
json.badge do
|
|
223
|
+
json.text badge
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# raise "Invalid properties: #{options.keys}" if options.size > 0
|
|
231
|
+
|
|
232
|
+
# instance_variable_set("@#{propName}", name) if options[:cache]
|
|
233
|
+
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def self.action propName
|
|
238
|
+
define_method(propName) do |value|
|
|
239
|
+
json.set!(propName) { value.call(page.action_builder) }
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def self.views propName
|
|
244
|
+
define_method(propName) do |value|
|
|
245
|
+
json.set!(propName) { value.call(page.view_builder) }
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
def self.array propName
|
|
250
|
+
define_method(propName) do |value|
|
|
251
|
+
json.set! propName, value&.to_a
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def self.hash propName
|
|
256
|
+
define_method(propName) do |value|
|
|
257
|
+
json.set! propName, value
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
def self.singleton_array singletonName, arrayName
|
|
262
|
+
array arrayName
|
|
263
|
+
|
|
264
|
+
define_method(singletonName) do |value|
|
|
265
|
+
json.set! arrayName, [value]
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
def self.panels_builder(propName, *panelNames)
|
|
270
|
+
define_method(propName) do |value|
|
|
271
|
+
value.call(page.content_builder(panelNames))
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def created
|
|
276
|
+
# To be overridden
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
end
|