Project

dash_kit

0.0
There's a lot of open issues
DashKit provides a presentation layer for building reusable dashboards. Register widgets, persist user configuration, and render dashboards without coupling to any specific data backend.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

 Project Readme

DashKit

What DashKit Is

DashKit is a Ruby / Rails UI engine for composing, configuring, and rendering dashboards. It provides a presentation and interaction layer that lets teams build reusable dashboards and widgets without tying the UI to any specific backend or data system.

What DashKit Is Not

DashKit does not:

  • Define metrics or their meaning.
  • Query databases or execute data retrieval logic.
  • Validate metric correctness or enforce business rules.
  • Assume any specific backend or analytics engine.

DashKit expects an external data provider to supply datasets. It focuses solely on rendering dashboards from those datasets.

High-Level Architecture

UI events → DataProvider → Dataset → Rendering

DashKit turns user intent (filters, time ranges, widget configs) into a request for a data provider, receives a dataset, and renders it into the dashboard UI.

Dashboards & Widgets

Dashboard

  • A container for layout, shared filters, and widget configuration.
  • Responsible for composition and reuse of dashboard layouts.

Widget

  • A visual unit (chart, table, single value) backed by a data request.
  • Each widget describes what it needs, but does not know how data is fetched.

Filters and Layouts

  • Filters are passed through as generic values.
  • Layout is a configuration concern (positions, sizes, grouping).
  • DashKit does not validate filter meaning or enforce data semantics.

Data Provider Interface

DashKit integrates with any backend through a pluggable data provider. The provider receives normalized requests and returns datasets in a generic structure.

Minimal interface sketch:

class MyProvider
  # request is a plain object or hash describing widget intent
  def fetch(request)
    # return a dataset hash
  end
end

DashKit does not care how data is fetched. It only requires that the provider responds to requests and returns datasets that match the contract.

Dataset Contract

DashKit renders datasets with a predictable structure, while leaving meaning and correctness to the provider.

Example dataset:

{
  "series": [
    { "name": "Revenue", "points": [ { "x": "2024-01", "y": 120 } ] }
  ],
  "rows": [ { "label": "Total", "value": 120 } ],
  "meta": { "unit": "USD" }
}

DashKit expects:

  • Consistent keys and array shapes per widget type.
  • Values that can be rendered without additional interpretation.

DashKit does not define:

  • What series or rows mean.
  • Which fields are required beyond a widget’s renderer.
  • How values are derived.

Installation

Add the gem to your Gemfile:

gem "dash_kit", github: "DYB-Development/dash_kit"

Run the install generator:

bundle install
rails generate dash_kit:install
rails db:migrate

The generator creates the migration, initializer, and engine route. You still need to complete these manual steps:

1. Add the association to your owner model

# app/models/account.rb (or whichever model owns dashboards)
has_many :dash_kit_configurations, class_name: "DashKit::Configuration",
         as: :owner, dependent: :destroy

2. Pin sortablejs for drag-and-drop reordering

# config/importmap.rb
pin "sortablejs"

3. Register Stimulus controllers

// app/javascript/controllers/index.js
import { registerControllers as registerDashKitControllers } from "dash_kit/index"
registerDashKitControllers(application)

4. Configure the initializer

# config/initializers/dash_kit.rb
DashKit.parent_controller = "ApplicationController"
DashKit.current_owner_method = :current_account

DashKit.configure do |config|
  config.register(:home) do |d|
    d.widget :on_deck, label: "On Deck", partial: "widgets/home/on_deck"
    d.widget :tasks,   label: "Tasks",   partial: "widgets/home/tasks"
  end
end
  • parent_controller — the controller DashKit inherits from (gives it access to authentication and helpers)
  • current_owner_method — the method DashKit calls to scope configurations to the current owner

5. Create a dashboard controller and view

# app/controllers/dashboard_controller.rb
class DashboardController < ApplicationController
  def show
    @dashboard_config = DashKit::Configuration.for_owner(current_account, :home)
    @dashboard_config.save! if @dashboard_config.new_record?
  end
end
<%# app/views/dashboard/show.html.erb %>
<%= dash_kit_settings_button_attributes %>
<%= dash_kit_settings_modal(config: @dashboard_config) %>

<div class="mt-4 space-y-6">
  <% @dashboard_config.ordered_visible_widgets.each do |widget_key| %>
    <%= render "widgets/widget_frame", widget_key: widget_key %>
  <% end %>
</div>

Design Philosophy

DashKit avoids data semantics by design. It treats datasets as opaque structures that can be rendered consistently, allowing teams to replace or evolve backends without rewriting dashboards. This deliberate decoupling keeps DashKit focused, composable, and stable over time.