Class: Tiler::UserWidget
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- Tiler::UserWidget
- Defined in:
- app/models/tiler/user_widget.rb
Overview
Runtime, no-code widget definition. Each row builds an anonymous Tiler::Widget subclass on boot (and after_save) and registers it under its slug. The Widget renders a partial that evaluates the row’s Liquid template against ‘panel`/`data` — sandboxed, no Ruby execution.
Constant Summary collapse
- DATA_KINDS =
%w[config_only query].freeze
- SLUG_RE =
/\A[a-z][a-z0-9_]{2,39}\z/- TEMPLATE_MAX =
10_000- AGGS =
%w[count sum avg min max last].freeze
- SLUG_PREFIX =
"user_".freeze
Class Method Summary collapse
-
.register_all! ⇒ Object
Iterate every persisted row and (re-)register their widget classes.
Instance Method Summary collapse
- #parsed_default_config ⇒ Object
- #parsed_query_definition ⇒ Object
-
#register! ⇒ Object
Build + register the anonymous Widget subclass for this row.
-
#registry_slug ⇒ Object
Slug used inside Tiler.widgets — namespaced so it can’t collide with built-in Ruby widgets (e.g. “user_my_thing”, not “my_thing”).
-
#render_template(panel:, data:) ⇒ Object
Renders the Liquid template against the ‘data` hash + panel info.
- #unregister! ⇒ Object
Class Method Details
.register_all! ⇒ Object
Iterate every persisted row and (re-)register their widget classes. Called from the engine boot initializer.
95 96 97 98 99 100 |
# File 'app/models/tiler/user_widget.rb', line 95 def self.register_all! return unless table_exists? find_each(&:register!) rescue ActiveRecord::StatementInvalid # Table doesn't exist yet (pre-migration boot). Skip silently. end |
Instance Method Details
#parsed_default_config ⇒ Object
47 48 49 50 51 |
# File 'app/models/tiler/user_widget.rb', line 47 def parsed_default_config JSON.parse(default_config.presence || "{}") rescue JSON::ParserError {} end |
#parsed_query_definition ⇒ Object
41 42 43 44 45 |
# File 'app/models/tiler/user_widget.rb', line 41 def parsed_query_definition JSON.parse(query_definition.presence || "{}") rescue JSON::ParserError {} end |
#register! ⇒ Object
Build + register the anonymous Widget subclass for this row. Called on save and once at boot via .register_all!
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'app/models/tiler/user_widget.rb', line 69 def register! uw = self query_kls = build_query_class = Class.new(::Tiler::Widget) do self.type = uw.registry_slug self.partial = "tiler/widgets/user_widget" self.label = uw.label self.query_class = query_kls self.default_config = uw.parsed_default_config self.default_size = { w: uw.default_w, h: uw.default_h } self.min_size = { w: 1, h: 1 } self.max_size = { w: 12, h: 12 } end ::Tiler..register(uw.registry_slug, klass: ) uw.instance_variable_set(:@widget_class, ) end |
#registry_slug ⇒ Object
Slug used inside Tiler.widgets — namespaced so it can’t collide with built-in Ruby widgets (e.g. “user_my_thing”, not “my_thing”).
37 38 39 |
# File 'app/models/tiler/user_widget.rb', line 37 def registry_slug "#{SLUG_PREFIX}#{slug}" end |
#render_template(panel:, data:) ⇒ Object
Renders the Liquid template against the ‘data` hash + panel info. Returns the rendered HTML string. Errors are surfaced inline so a broken template doesn’t crash the whole dashboard.
56 57 58 59 60 61 62 63 64 65 |
# File 'app/models/tiler/user_widget.rb', line 56 def render_template(panel:, data:) tpl = Liquid::Template.parse(template, error_mode: :strict) tpl.render!( "panel" => liquid_panel(panel), "data" => stringify(data), "config" => panel ? stringify(panel.parsed_config) : {} ) rescue Liquid::Error, StandardError => e "<pre class=\"tiler-widget-error\">#{ERB::Util.h(e.)}</pre>".html_safe end |