dash_kit 2.1.0 → 2.2.0
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 +4 -4
- data/README.md +13 -0
- data/app/helpers/dash_kit/dashboard_helper.rb +10 -8
- data/lib/dash_kit/reference/guide.md +14 -9
- data/lib/dash_kit/the_local/agents/dash_kit-develop.md +14 -9
- data/lib/dash_kit/the_local/agents/dash_kit-info.md +14 -9
- data/lib/dash_kit/the_local/agents/dash_kit-install.md +14 -9
- data/lib/dash_kit/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 752a3c52f25de0472afd8d1143e5066c7e2d6bc62b31d4542417313cc94310e6
|
|
4
|
+
data.tar.gz: 783e9571276247d55b6bbcb779f475688b3b0897885b784135df0df81c179dfc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 74532c9d76d342563918d0b8542a2dc9c84b1ce7145162171f01564dc973b9e04184f4aaebc26423ad11d9b9db1c11aeb4f7e7b69038af1a9f7d125dc6956251
|
|
7
|
+
data.tar.gz: e6676dbc1e78d966e6a56f49189b010147fa4b4eaf414d7598a5332d976a59184e123a1683b5c4f0f0bb137a1762bfb15d1b05336b1ca14b501bd9260964f2a7
|
data/README.md
CHANGED
|
@@ -168,3 +168,16 @@ end
|
|
|
168
168
|
## Design Philosophy
|
|
169
169
|
|
|
170
170
|
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.
|
|
171
|
+
|
|
172
|
+
## Setting up to work on DashKit
|
|
173
|
+
|
|
174
|
+
After cloning, install the bundle and run the setup command:
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
bundle install
|
|
178
|
+
bundle exec dev_onboarder
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
It runs the test suite and checks the Claude Code tooling the repo expects, and records what it found
|
|
182
|
+
inside the clone's git directory, where nothing is committed. `bundle exec dev_onboarder status` lists what the repo
|
|
183
|
+
requires now that it did not at your last run. The requirements are declared in `Setupfile`.
|
|
@@ -39,11 +39,11 @@ module DashKit
|
|
|
39
39
|
config.available_widgets.dig(widget_key.to_sym, :label) || widget_key.to_s.humanize
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
def dash_kit_render_widgets(config
|
|
42
|
+
def dash_kit_render_widgets(config:, &draw)
|
|
43
43
|
return content_tag(:div, "", id: "dashboard-widgets") unless config
|
|
44
44
|
|
|
45
45
|
content_tag(:div, id: dash_kit_widgets_id(config)) do
|
|
46
|
-
dash_kit_arrangeable?(config) ? dash_kit_widget_grid(config) : dash_kit_drawn_widgets(config)
|
|
46
|
+
dash_kit_arrangeable?(config) ? dash_kit_widget_grid(config, &draw) : dash_kit_drawn_widgets(config, &draw)
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
49
|
|
|
@@ -55,10 +55,10 @@ module DashKit
|
|
|
55
55
|
DashKit.editable?(config, dash_kit_current_viewer)
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
def dash_kit_widget_grid(config)
|
|
58
|
+
def dash_kit_widget_grid(config, &draw)
|
|
59
59
|
safe_join([
|
|
60
60
|
react_ui("dash_kit/dashboard-grid", config.layout_data.merge(base: dash_kit.dashboard_path(config), token: dash_kit_form_token)),
|
|
61
|
-
block_contents(config.blocks) { |block| dash_kit_block_frame(config, block) }
|
|
61
|
+
block_contents(config.blocks) { |block| dash_kit_block_frame(config, block, &draw) }
|
|
62
62
|
])
|
|
63
63
|
end
|
|
64
64
|
|
|
@@ -66,14 +66,16 @@ module DashKit
|
|
|
66
66
|
controller.send(:form_authenticity_token) if controller.respond_to?(:form_authenticity_token, true)
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
-
def dash_kit_drawn_widgets(config)
|
|
69
|
+
def dash_kit_drawn_widgets(config, &draw)
|
|
70
70
|
block_layout(config.blocks, kind: config.dashboard_type.to_sym) do |block|
|
|
71
|
-
dash_kit_block_frame(config, block)
|
|
71
|
+
dash_kit_block_frame(config, block, &draw)
|
|
72
72
|
end
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
-
def dash_kit_block_frame(config, block)
|
|
76
|
-
|
|
75
|
+
def dash_kit_block_frame(config, block, &draw)
|
|
76
|
+
unless block["type"] == WidgetRegistry::BUILT_WIDGET.to_s
|
|
77
|
+
return draw ? capture(block["type"], &draw) : dash_kit_widget_frame(block["type"], dashboard_id: config.id)
|
|
78
|
+
end
|
|
77
79
|
|
|
78
80
|
definition = config.widget_definitions.find_by(id: block.dig("content", "definition_id"))
|
|
79
81
|
definition ? dash_kit_widget_definition_frame(definition) : dash_kit_loading_skeleton
|
|
@@ -12,8 +12,9 @@ coupling the UI to any specific data backend.
|
|
|
12
12
|
- A widget registry: dashboard types map to the widgets available on them.
|
|
13
13
|
- A persistence layer for user preferences (which widgets show, in what order,
|
|
14
14
|
with which filters) via an ActiveRecord `Dashboard` model.
|
|
15
|
-
- A rendering layer that lazy-loads each widget through a Turbo Frame
|
|
16
|
-
|
|
15
|
+
- A rendering layer that lazy-loads each widget through a Turbo Frame, or hands
|
|
16
|
+
each widget to a block the host passes so the host draws it inside the page,
|
|
17
|
+
and refreshes on configuration change.
|
|
17
18
|
|
|
18
19
|
A dashboard renders two kinds of widget side by side:
|
|
19
20
|
|
|
@@ -81,16 +82,19 @@ The layers, all under the `DashKit` namespace:
|
|
|
81
82
|
`dash_kit_available_sources`, `dash_kit_visualizations`, and
|
|
82
83
|
`dash_kit_widget_definition_frame(definition)`. `dash_kit_render_widgets`
|
|
83
84
|
renders the registered widgets in order, then appends one lazy Turbo Frame per
|
|
84
|
-
`widget_definition`.
|
|
85
|
+
`widget_definition`. Given a block, it calls the block with each shown
|
|
86
|
+
registered widget's key and draws what the block returns in that widget's
|
|
87
|
+
place, inside the page's own request and with no Turbo Frame.
|
|
85
88
|
|
|
86
89
|
### Data flow
|
|
87
90
|
|
|
88
91
|
UI events -> dashboard update -> Turbo refresh -> widgets re-render via
|
|
89
|
-
lazy-loaded Turbo Frames.
|
|
92
|
+
lazy-loaded Turbo Frames. Without a block, a widget loads through a
|
|
90
93
|
`<turbo-frame loading="lazy">` pointing at the widget's own route. The frame
|
|
91
94
|
carries its dashboard's id, so the widget partial is handed the dashboard's
|
|
92
95
|
`filter_state` to render against (DashKit passes the blob; the host interprets
|
|
93
|
-
it).
|
|
96
|
+
it). With a block, DashKit decides only which widgets show and where, and the
|
|
97
|
+
host draws each one from data it has already loaded for the page.
|
|
94
98
|
|
|
95
99
|
Built widgets follow the same flow. Each `widget_definition` lazy-loads through
|
|
96
100
|
its own `<turbo-frame>` at `/widget_definitions/:id`;
|
|
@@ -255,7 +259,7 @@ The following manual steps remain:
|
|
|
255
259
|
display order.
|
|
256
260
|
- **Supply the data yourself.** A widget's partial is responsible for fetching
|
|
257
261
|
and rendering its own data; DashKit only renders the partial inside a lazy
|
|
258
|
-
Turbo Frame. Keep partials self-contained around the owner DashKit scopes to.
|
|
262
|
+
Turbo Frame, or calls the host's block with the widget's key. Keep partials self-contained around the owner DashKit scopes to.
|
|
259
263
|
This holds for registered widgets and for built-widget renderer partials
|
|
260
264
|
alike — both receive `filter_state` and read it to shape their own request.
|
|
261
265
|
- **Register a renderer for every visualization the builder offers.** A built
|
|
@@ -274,9 +278,10 @@ The following manual steps remain:
|
|
|
274
278
|
`WidgetManagement` methods (`toggle_widget`, `move_widget_up`,
|
|
275
279
|
`move_widget_down`, `update_filter`) or the engine routes; do not write
|
|
276
280
|
`widget_order` / `hidden_widgets` / `filter_state` directly.
|
|
277
|
-
- **
|
|
278
|
-
|
|
279
|
-
|
|
281
|
+
- **Draw widgets through `dash_kit_render_widgets`.** Without a block, each
|
|
282
|
+
widget loads in its own Turbo Frame. Pass a block when the page already holds
|
|
283
|
+
the widgets' data, so every widget is drawn in the page's own request rather
|
|
284
|
+
than one request per widget.
|
|
280
285
|
- **Mobile-first, Tailwind, dark mode.** The shipped UI is styled with Tailwind
|
|
281
286
|
and supports dark mode; host styling should match. The primary surface is
|
|
282
287
|
often a native webview.
|
|
@@ -20,8 +20,9 @@ coupling the UI to any specific data backend.
|
|
|
20
20
|
- A widget registry: dashboard types map to the widgets available on them.
|
|
21
21
|
- A persistence layer for user preferences (which widgets show, in what order,
|
|
22
22
|
with which filters) via an ActiveRecord `Dashboard` model.
|
|
23
|
-
- A rendering layer that lazy-loads each widget through a Turbo Frame
|
|
24
|
-
|
|
23
|
+
- A rendering layer that lazy-loads each widget through a Turbo Frame, or hands
|
|
24
|
+
each widget to a block the host passes so the host draws it inside the page,
|
|
25
|
+
and refreshes on configuration change.
|
|
25
26
|
|
|
26
27
|
A dashboard renders two kinds of widget side by side:
|
|
27
28
|
|
|
@@ -89,16 +90,19 @@ The layers, all under the `DashKit` namespace:
|
|
|
89
90
|
`dash_kit_available_sources`, `dash_kit_visualizations`, and
|
|
90
91
|
`dash_kit_widget_definition_frame(definition)`. `dash_kit_render_widgets`
|
|
91
92
|
renders the registered widgets in order, then appends one lazy Turbo Frame per
|
|
92
|
-
`widget_definition`.
|
|
93
|
+
`widget_definition`. Given a block, it calls the block with each shown
|
|
94
|
+
registered widget's key and draws what the block returns in that widget's
|
|
95
|
+
place, inside the page's own request and with no Turbo Frame.
|
|
93
96
|
|
|
94
97
|
### Data flow
|
|
95
98
|
|
|
96
99
|
UI events -> dashboard update -> Turbo refresh -> widgets re-render via
|
|
97
|
-
lazy-loaded Turbo Frames.
|
|
100
|
+
lazy-loaded Turbo Frames. Without a block, a widget loads through a
|
|
98
101
|
`<turbo-frame loading="lazy">` pointing at the widget's own route. The frame
|
|
99
102
|
carries its dashboard's id, so the widget partial is handed the dashboard's
|
|
100
103
|
`filter_state` to render against (DashKit passes the blob; the host interprets
|
|
101
|
-
it).
|
|
104
|
+
it). With a block, DashKit decides only which widgets show and where, and the
|
|
105
|
+
host draws each one from data it has already loaded for the page.
|
|
102
106
|
|
|
103
107
|
Built widgets follow the same flow. Each `widget_definition` lazy-loads through
|
|
104
108
|
its own `<turbo-frame>` at `/widget_definitions/:id`;
|
|
@@ -263,7 +267,7 @@ The following manual steps remain:
|
|
|
263
267
|
display order.
|
|
264
268
|
- **Supply the data yourself.** A widget's partial is responsible for fetching
|
|
265
269
|
and rendering its own data; DashKit only renders the partial inside a lazy
|
|
266
|
-
Turbo Frame. Keep partials self-contained around the owner DashKit scopes to.
|
|
270
|
+
Turbo Frame, or calls the host's block with the widget's key. Keep partials self-contained around the owner DashKit scopes to.
|
|
267
271
|
This holds for registered widgets and for built-widget renderer partials
|
|
268
272
|
alike — both receive `filter_state` and read it to shape their own request.
|
|
269
273
|
- **Register a renderer for every visualization the builder offers.** A built
|
|
@@ -282,9 +286,10 @@ The following manual steps remain:
|
|
|
282
286
|
`WidgetManagement` methods (`toggle_widget`, `move_widget_up`,
|
|
283
287
|
`move_widget_down`, `update_filter`) or the engine routes; do not write
|
|
284
288
|
`widget_order` / `hidden_widgets` / `filter_state` directly.
|
|
285
|
-
- **
|
|
286
|
-
|
|
287
|
-
|
|
289
|
+
- **Draw widgets through `dash_kit_render_widgets`.** Without a block, each
|
|
290
|
+
widget loads in its own Turbo Frame. Pass a block when the page already holds
|
|
291
|
+
the widgets' data, so every widget is drawn in the page's own request rather
|
|
292
|
+
than one request per widget.
|
|
288
293
|
- **Mobile-first, Tailwind, dark mode.** The shipped UI is styled with Tailwind
|
|
289
294
|
and supports dark mode; host styling should match. The primary surface is
|
|
290
295
|
often a native webview.
|
|
@@ -20,8 +20,9 @@ coupling the UI to any specific data backend.
|
|
|
20
20
|
- A widget registry: dashboard types map to the widgets available on them.
|
|
21
21
|
- A persistence layer for user preferences (which widgets show, in what order,
|
|
22
22
|
with which filters) via an ActiveRecord `Dashboard` model.
|
|
23
|
-
- A rendering layer that lazy-loads each widget through a Turbo Frame
|
|
24
|
-
|
|
23
|
+
- A rendering layer that lazy-loads each widget through a Turbo Frame, or hands
|
|
24
|
+
each widget to a block the host passes so the host draws it inside the page,
|
|
25
|
+
and refreshes on configuration change.
|
|
25
26
|
|
|
26
27
|
A dashboard renders two kinds of widget side by side:
|
|
27
28
|
|
|
@@ -89,16 +90,19 @@ The layers, all under the `DashKit` namespace:
|
|
|
89
90
|
`dash_kit_available_sources`, `dash_kit_visualizations`, and
|
|
90
91
|
`dash_kit_widget_definition_frame(definition)`. `dash_kit_render_widgets`
|
|
91
92
|
renders the registered widgets in order, then appends one lazy Turbo Frame per
|
|
92
|
-
`widget_definition`.
|
|
93
|
+
`widget_definition`. Given a block, it calls the block with each shown
|
|
94
|
+
registered widget's key and draws what the block returns in that widget's
|
|
95
|
+
place, inside the page's own request and with no Turbo Frame.
|
|
93
96
|
|
|
94
97
|
### Data flow
|
|
95
98
|
|
|
96
99
|
UI events -> dashboard update -> Turbo refresh -> widgets re-render via
|
|
97
|
-
lazy-loaded Turbo Frames.
|
|
100
|
+
lazy-loaded Turbo Frames. Without a block, a widget loads through a
|
|
98
101
|
`<turbo-frame loading="lazy">` pointing at the widget's own route. The frame
|
|
99
102
|
carries its dashboard's id, so the widget partial is handed the dashboard's
|
|
100
103
|
`filter_state` to render against (DashKit passes the blob; the host interprets
|
|
101
|
-
it).
|
|
104
|
+
it). With a block, DashKit decides only which widgets show and where, and the
|
|
105
|
+
host draws each one from data it has already loaded for the page.
|
|
102
106
|
|
|
103
107
|
Built widgets follow the same flow. Each `widget_definition` lazy-loads through
|
|
104
108
|
its own `<turbo-frame>` at `/widget_definitions/:id`;
|
|
@@ -263,7 +267,7 @@ The following manual steps remain:
|
|
|
263
267
|
display order.
|
|
264
268
|
- **Supply the data yourself.** A widget's partial is responsible for fetching
|
|
265
269
|
and rendering its own data; DashKit only renders the partial inside a lazy
|
|
266
|
-
Turbo Frame. Keep partials self-contained around the owner DashKit scopes to.
|
|
270
|
+
Turbo Frame, or calls the host's block with the widget's key. Keep partials self-contained around the owner DashKit scopes to.
|
|
267
271
|
This holds for registered widgets and for built-widget renderer partials
|
|
268
272
|
alike — both receive `filter_state` and read it to shape their own request.
|
|
269
273
|
- **Register a renderer for every visualization the builder offers.** A built
|
|
@@ -282,9 +286,10 @@ The following manual steps remain:
|
|
|
282
286
|
`WidgetManagement` methods (`toggle_widget`, `move_widget_up`,
|
|
283
287
|
`move_widget_down`, `update_filter`) or the engine routes; do not write
|
|
284
288
|
`widget_order` / `hidden_widgets` / `filter_state` directly.
|
|
285
|
-
- **
|
|
286
|
-
|
|
287
|
-
|
|
289
|
+
- **Draw widgets through `dash_kit_render_widgets`.** Without a block, each
|
|
290
|
+
widget loads in its own Turbo Frame. Pass a block when the page already holds
|
|
291
|
+
the widgets' data, so every widget is drawn in the page's own request rather
|
|
292
|
+
than one request per widget.
|
|
288
293
|
- **Mobile-first, Tailwind, dark mode.** The shipped UI is styled with Tailwind
|
|
289
294
|
and supports dark mode; host styling should match. The primary surface is
|
|
290
295
|
often a native webview.
|
|
@@ -20,8 +20,9 @@ coupling the UI to any specific data backend.
|
|
|
20
20
|
- A widget registry: dashboard types map to the widgets available on them.
|
|
21
21
|
- A persistence layer for user preferences (which widgets show, in what order,
|
|
22
22
|
with which filters) via an ActiveRecord `Dashboard` model.
|
|
23
|
-
- A rendering layer that lazy-loads each widget through a Turbo Frame
|
|
24
|
-
|
|
23
|
+
- A rendering layer that lazy-loads each widget through a Turbo Frame, or hands
|
|
24
|
+
each widget to a block the host passes so the host draws it inside the page,
|
|
25
|
+
and refreshes on configuration change.
|
|
25
26
|
|
|
26
27
|
A dashboard renders two kinds of widget side by side:
|
|
27
28
|
|
|
@@ -89,16 +90,19 @@ The layers, all under the `DashKit` namespace:
|
|
|
89
90
|
`dash_kit_available_sources`, `dash_kit_visualizations`, and
|
|
90
91
|
`dash_kit_widget_definition_frame(definition)`. `dash_kit_render_widgets`
|
|
91
92
|
renders the registered widgets in order, then appends one lazy Turbo Frame per
|
|
92
|
-
`widget_definition`.
|
|
93
|
+
`widget_definition`. Given a block, it calls the block with each shown
|
|
94
|
+
registered widget's key and draws what the block returns in that widget's
|
|
95
|
+
place, inside the page's own request and with no Turbo Frame.
|
|
93
96
|
|
|
94
97
|
### Data flow
|
|
95
98
|
|
|
96
99
|
UI events -> dashboard update -> Turbo refresh -> widgets re-render via
|
|
97
|
-
lazy-loaded Turbo Frames.
|
|
100
|
+
lazy-loaded Turbo Frames. Without a block, a widget loads through a
|
|
98
101
|
`<turbo-frame loading="lazy">` pointing at the widget's own route. The frame
|
|
99
102
|
carries its dashboard's id, so the widget partial is handed the dashboard's
|
|
100
103
|
`filter_state` to render against (DashKit passes the blob; the host interprets
|
|
101
|
-
it).
|
|
104
|
+
it). With a block, DashKit decides only which widgets show and where, and the
|
|
105
|
+
host draws each one from data it has already loaded for the page.
|
|
102
106
|
|
|
103
107
|
Built widgets follow the same flow. Each `widget_definition` lazy-loads through
|
|
104
108
|
its own `<turbo-frame>` at `/widget_definitions/:id`;
|
|
@@ -263,7 +267,7 @@ The following manual steps remain:
|
|
|
263
267
|
display order.
|
|
264
268
|
- **Supply the data yourself.** A widget's partial is responsible for fetching
|
|
265
269
|
and rendering its own data; DashKit only renders the partial inside a lazy
|
|
266
|
-
Turbo Frame. Keep partials self-contained around the owner DashKit scopes to.
|
|
270
|
+
Turbo Frame, or calls the host's block with the widget's key. Keep partials self-contained around the owner DashKit scopes to.
|
|
267
271
|
This holds for registered widgets and for built-widget renderer partials
|
|
268
272
|
alike — both receive `filter_state` and read it to shape their own request.
|
|
269
273
|
- **Register a renderer for every visualization the builder offers.** A built
|
|
@@ -282,9 +286,10 @@ The following manual steps remain:
|
|
|
282
286
|
`WidgetManagement` methods (`toggle_widget`, `move_widget_up`,
|
|
283
287
|
`move_widget_down`, `update_filter`) or the engine routes; do not write
|
|
284
288
|
`widget_order` / `hidden_widgets` / `filter_state` directly.
|
|
285
|
-
- **
|
|
286
|
-
|
|
287
|
-
|
|
289
|
+
- **Draw widgets through `dash_kit_render_widgets`.** Without a block, each
|
|
290
|
+
widget loads in its own Turbo Frame. Pass a block when the page already holds
|
|
291
|
+
the widgets' data, so every widget is drawn in the page's own request rather
|
|
292
|
+
than one request per widget.
|
|
288
293
|
- **Mobile-first, Tailwind, dark mode.** The shipped UI is styled with Tailwind
|
|
289
294
|
and supports dark mode; host styling should match. The primary surface is
|
|
290
295
|
often a native webview.
|
data/lib/dash_kit/version.rb
CHANGED