Module: OpenLoam::Widgets
- Defined in:
- lib/open_loam/widgets.rb
Overview
A registry of dashboard widgets — small, module-provided tiles (a metric, a short list) shown on the admin home. A widget is a DATA PROVIDER plus a title and an optional role filter; it never renders arbitrary code:
OpenLoam::Widgets.register(key: "open_rentals", title: "Open rentals", roles: %w[manager]) do |actor|
{ kind: "count", value: Rental.where(status: "open").count } # tenant-scoped query
end
The provider returns a small data hash ({ kind: "count", value: } or
{ kind: "list", items: [...] }); the dashboard renders it generically.
Widgets run tenant-scoped (query through tenant-scoped models), the roles:
filter is enforced server-side (a hidden widget's data is NOT computed), and
a raising provider is isolated into an error tile — the dashboard never breaks.
Defined Under Namespace
Classes: Widget
Class Method Summary collapse
- .find(key) ⇒ Object
- .keys ⇒ Object
- .register(key:, title:, roles: nil, &block) ⇒ Object
-
.register_builtins! ⇒ Object
The widgets every OpenLoam app starts with — registered at boot from the engine, so a fresh install has a useful default dashboard.
- .registered ⇒ Object
- .reset! ⇒ Object
-
.resolve(key, actor:, role:) ⇒ Object
Resolve a widget for (actor, role): nil when it doesn't exist or the role can't see it (so its data is never computed), otherwise { key, title, data } — or { key, title, error: } when the provider raises.
Class Method Details
.find(key) ⇒ Object
30 |
# File 'lib/open_loam/widgets.rb', line 30 def find(key) = registry[key.to_s] |
.keys ⇒ Object
29 |
# File 'lib/open_loam/widgets.rb', line 29 def keys = registry.keys |
.register(key:, title:, roles: nil, &block) ⇒ Object
23 24 25 26 |
# File 'lib/open_loam/widgets.rb', line 23 def register(key:, title:, roles: nil, &block) registry[key.to_s] = Widget.new(key: key.to_s, title: title, roles: roles, provider: block) key.to_s end |
.register_builtins! ⇒ Object
The widgets every OpenLoam app starts with — registered at boot from the engine, so a fresh install has a useful default dashboard.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/open_loam/widgets.rb', line 53 def register_builtins! register(key: "audit_recent", title: "Recent activity") do |_actor| items = OpenLoam::AuditRecord.order(created_at: :desc).limit(8) .map { |a| "#{a.action} #{a.auditable_type} ##{a.auditable_id}" } { kind: "list", items: items } end register(key: "notifications_unread", title: "Unread notifications") do |actor| { kind: "count", value: OpenLoam::Notification.unread.where(user_id: actor&.id).count } end register(key: "pending_approvals", title: "Pending approvals", roles: %w[manager]) do |_actor| { kind: "count", value: OpenLoam::PendingAction.pending.count } end register(key: "open_progress", title: "Running tasks") do |_actor| { kind: "count", value: OpenLoam::ProgressJob.where(status: "running").count } end end |
.registered ⇒ Object
28 |
# File 'lib/open_loam/widgets.rb', line 28 def registered = registry.values |
.reset! ⇒ Object
32 33 34 |
# File 'lib/open_loam/widgets.rb', line 32 def reset! @registry = {} end |
.resolve(key, actor:, role:) ⇒ Object
Resolve a widget for (actor, role): nil when it doesn't exist or the role can't see it (so its data is never computed), otherwise { key, title, data } — or { key, title, error: } when the provider raises.
39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/open_loam/widgets.rb', line 39 def resolve(key, actor:, role:) return nil if OpenLoam::Overrides.disabled?(:widgets, key) # customization without forking = find(key) return nil unless &.visible_to?(role) provider = OpenLoam::Overrides.replacement(:widgets, key) || .provider { key: .key, title: .title, data: provider.call(actor) } rescue StandardError => error { key: &.key, title: &.title, error: error. } end |