cafe_car 0.2.1 → 0.3.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/.claude-plugin/marketplace.json +23 -0
- data/README.md +417 -29
- data/Rakefile +2 -2
- data/app/assets/stylesheets/cafe_car/chart.css +41 -0
- data/app/assets/stylesheets/cafe_car/dashboard.css +43 -0
- data/app/assets/stylesheets/cafe_car/filters.css +50 -0
- data/app/assets/stylesheets/cafe_car/themes/cool2.css +2 -0
- data/app/assets/stylesheets/cafe_car/themes/warm.css +30 -0
- data/app/assets/stylesheets/cafe_car/tooltips.css +1 -1
- data/app/assets/stylesheets/cafe_car.css +14 -4
- data/app/assets/stylesheets/tom-select.css +95 -0
- data/app/assets/stylesheets/ui/Button.css +7 -5
- data/app/assets/stylesheets/ui/Input.css +92 -1
- data/app/assets/stylesheets/ui/Page.css +7 -0
- data/app/assets/stylesheets/ui/Table.css +25 -0
- data/app/controllers/cafe_car/dashboards_controller.rb +29 -0
- data/app/javascript/cafe_car.js +68 -0
- data/app/javascript/tom-select.complete.min.js +444 -0
- data/app/policies/cafe_car/application_policy.rb +1 -1
- data/app/presenters/cafe_car/active_storage/attachment_presenter.rb +4 -1
- data/app/presenters/cafe_car/presenter.rb +2 -2
- data/app/views/application/_actions.html.haml +9 -0
- data/app/views/application/_active_filters.html.haml +15 -0
- data/app/views/application/_belongs_to_filter.html.haml +6 -0
- data/app/views/application/_boolean_filter.html.haml +4 -0
- data/app/views/application/_bulk_actions.html.haml +9 -0
- data/app/views/application/_chart.html.haml +18 -0
- data/app/views/application/_controls.html.haml +8 -0
- data/app/views/application/_enum_filter.html.haml +5 -0
- data/app/views/application/_filter.html.haml +4 -0
- data/app/views/application/_filters.html.haml +13 -4
- data/app/views/application/_has_many_filter.html.haml +7 -0
- data/app/views/application/_head.html.haml +1 -0
- data/app/views/application/_index.html.haml +3 -1
- data/app/views/application/_index_actions.html.haml +12 -3
- data/app/views/application/_navigation.html.haml +5 -0
- data/app/views/application/_nested_field.html.haml +1 -1
- data/app/views/application/_range_filter.html.haml +8 -0
- data/app/views/application/_scope_filter.html.haml +5 -0
- data/app/views/application/_string_filter.html.haml +4 -0
- data/app/views/application/_table.html.haml +8 -6
- data/app/views/application/_text_filter.html.haml +1 -0
- data/app/views/cafe_car/application/index.html.haml +5 -2
- data/app/views/cafe_car/dashboard/_chart.html.haml +11 -0
- data/app/views/cafe_car/dashboard/_metric.html.haml +4 -0
- data/config/brakeman.ignore +0 -48
- data/config/importmap.rb +1 -0
- data/config/locales/en.yml +60 -0
- data/config/routes.rb +15 -2
- data/lib/cafe_car/attributes.rb +40 -12
- data/lib/cafe_car/chart_builder.rb +217 -0
- data/lib/cafe_car/controller/filtering.rb +108 -6
- data/lib/cafe_car/controller.rb +220 -11
- data/lib/cafe_car/engine.rb +2 -2
- data/lib/cafe_car/field_info.rb +14 -4
- data/lib/cafe_car/filter/field_info.rb +56 -7
- data/lib/cafe_car/filter/form_builder.rb +57 -7
- data/lib/cafe_car/filter_builder.rb +14 -1
- data/lib/cafe_car/form_builder.rb +61 -6
- data/lib/cafe_car/helpers.rb +196 -0
- data/lib/cafe_car/inputs/association_input.rb +11 -0
- data/lib/cafe_car/inputs/base_input.rb +56 -7
- data/lib/cafe_car/inputs/boolean_input.rb +9 -0
- data/lib/cafe_car/inputs/date_input.rb +8 -0
- data/lib/cafe_car/inputs/datetime_input.rb +8 -0
- data/lib/cafe_car/inputs/file_input.rb +11 -0
- data/lib/cafe_car/inputs/nested_input.rb +10 -0
- data/lib/cafe_car/inputs/number_input.rb +9 -0
- data/lib/cafe_car/inputs/password_input.rb +4 -2
- data/lib/cafe_car/inputs/rich_text_input.rb +9 -0
- data/lib/cafe_car/inputs/select_input.rb +10 -0
- data/lib/cafe_car/inputs/string_input.rb +3 -1
- data/lib/cafe_car/inputs/text_area_input.rb +9 -0
- data/lib/cafe_car/link_builder.rb +11 -0
- data/lib/cafe_car/model.rb +37 -8
- data/lib/cafe_car/navigation.rb +10 -0
- data/lib/cafe_car/policy.rb +85 -15
- data/lib/cafe_car/query_builder.rb +22 -0
- data/lib/cafe_car/routing.rb +26 -2
- data/lib/cafe_car/table/builder.rb +1 -1
- data/lib/cafe_car/table/foot_builder.rb +1 -0
- data/lib/cafe_car/table/head_builder.rb +6 -0
- data/lib/cafe_car/table/row_builder.rb +7 -0
- data/lib/cafe_car/version.rb +1 -1
- data/lib/cafe_car.rb +32 -2
- data/lib/generators/cafe_car/agents/USAGE +13 -0
- data/lib/generators/cafe_car/agents/agents_generator.rb +49 -0
- data/lib/generators/cafe_car/resource/resource_generator.rb +12 -1
- data/lib/tasks/demo.rake +9 -0
- data/llms.txt +25 -0
- data/skills/cafe_car/SKILL.md +135 -0
- data/skills/cafe_car/references/components.md +93 -0
- data/skills/cafe_car/references/controllers.md +106 -0
- data/skills/cafe_car/references/filtering.md +102 -0
- data/skills/cafe_car/references/forms.md +84 -0
- data/skills/cafe_car/references/locales.md +74 -0
- data/skills/cafe_car/references/navigation.md +67 -0
- data/skills/cafe_car/references/policies.md +112 -0
- data/skills/cafe_car/references/presenters.md +76 -0
- data/skills/cafe_car/references/turbo.md +53 -0
- data/skills/cafe_car/references/views.md +96 -0
- metadata +59 -16
- data/app/assets/stylesheets/cafe_car/themes/warm-dark.css +0 -29
- data/app/views/application/_search.html.haml +0 -6
- data/lib/cafe_car/auto_resolver.rb +0 -49
- data/lib/cafe_car/inputs/association_builder.rb +0 -6
- data/lib/cafe_car/inputs/belongs_to_builder.rb +0 -6
- data/lib/tasks/holdco_tasks.rake +0 -532
- data/lib/tasks/templates/tasks_header.md +0 -37
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Presenters — how values render
|
|
2
|
+
|
|
3
|
+
Source: `app/presenters/cafe_car/presenter.rb` in the gem, plus per-type presenters
|
|
4
|
+
alongside it (`CurrencyPresenter`, `DatePresenter`, `RecordPresenter`,
|
|
5
|
+
`ActiveRecord::RelationPresenter`, `ActiveStorage::AttachmentPresenter`, …).
|
|
6
|
+
|
|
7
|
+
`present(value)` (aliased `p` in views) wraps anything in a presenter and returns
|
|
8
|
+
an html-safe object. Records render as a linked preview (logo + title); dates,
|
|
9
|
+
currency, rich text, attachments, and collections each render through their type's
|
|
10
|
+
presenter.
|
|
11
|
+
|
|
12
|
+
## How a presenter is chosen
|
|
13
|
+
|
|
14
|
+
The value's ancestor chain is walked and the first `<Ancestor>Presenter` constant
|
|
15
|
+
found wins — a host `InvoicePresenter` beats the gem's `RecordPresenter` by
|
|
16
|
+
existing; nothing is registered. Force a type with `as:`:
|
|
17
|
+
|
|
18
|
+
```ruby
|
|
19
|
+
present(@invoice) # InvoicePresenter, else RecordPresenter
|
|
20
|
+
present(record.total, as: :currency) # CurrencyPresenter
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Note: constants the gem defines under `CafeCar::` (e.g. `CafeCar::StringPresenter`)
|
|
24
|
+
resolve engine-first — a same-named top-level constant does *not* shadow them.
|
|
25
|
+
Override per model (`ProductPresenter`) or per ancestor the gem doesn't claim.
|
|
26
|
+
|
|
27
|
+
## Writing one
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
# app/presenters/invoice_presenter.rb
|
|
31
|
+
class InvoicePresenter < CafeCar::Presenter
|
|
32
|
+
show :total, as: :currency # render this attribute through a type
|
|
33
|
+
show :number, -> { "#%03d" % _1 } # or through a lambda
|
|
34
|
+
|
|
35
|
+
def title = show(:number) # what links/cards/breadcrumbs call this record
|
|
36
|
+
end
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`show` class macros set per-attribute rendering defaults used everywhere the
|
|
40
|
+
attribute appears — tables, show pages, cards.
|
|
41
|
+
|
|
42
|
+
## The instance API (used inside overridden views)
|
|
43
|
+
|
|
44
|
+
In view code, `present(@article)` (or the `object` local in `_grid_item`) gives:
|
|
45
|
+
|
|
46
|
+
```ruby
|
|
47
|
+
p = present(@article)
|
|
48
|
+
p.title # policy.title_attribute, rendered
|
|
49
|
+
p.logo(size: :icon) # policy.logo_attribute as an image
|
|
50
|
+
p.show(:author) # one attribute's value, presented
|
|
51
|
+
p.attribute(:author) # labeled Field (label + value)
|
|
52
|
+
p.attributes(:a, :b) # several labeled fields; no args = all displayable
|
|
53
|
+
p.remaining_attributes # displayable minus already-shown
|
|
54
|
+
p.associations # labeled fields for displayable associations
|
|
55
|
+
p.timestamps # created_at/updated_at etc.
|
|
56
|
+
p.controls # the show/edit/delete control links
|
|
57
|
+
p.href # canonical path, nil if not routable
|
|
58
|
+
p.object # the underlying record (for url helpers etc.)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Linking to related objects
|
|
62
|
+
|
|
63
|
+
`show`/`preview` of an associated record is already a link to it. For explicit
|
|
64
|
+
links use the helpers:
|
|
65
|
+
|
|
66
|
+
```ruby
|
|
67
|
+
href_for(record) # path to the record in the current namespace
|
|
68
|
+
link(record).show # LinkBuilder: policy-aware link (disabled when denied)
|
|
69
|
+
link(record).edit
|
|
70
|
+
link(record).destroy # turbo DELETE with locale-driven confirm
|
|
71
|
+
link(model).index
|
|
72
|
+
link(model.new).new
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
`link(...)` renders disabled-with-tooltip when the policy denies the action —
|
|
76
|
+
prefer it over hand-written `link_to` so authorization stays visible in the UI.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Turbo Streams and live sync
|
|
2
|
+
|
|
3
|
+
Source: `app/views/cafe_car/application/*.turbo_stream.haml` and
|
|
4
|
+
`app/views/application/_head.html.haml` (in the gem).
|
|
5
|
+
|
|
6
|
+
This is a big reason not to hand-roll admin pages: the defaults carry Turbo 8
|
|
7
|
+
morph behavior you'd otherwise rebuild.
|
|
8
|
+
|
|
9
|
+
## What ships by default
|
|
10
|
+
|
|
11
|
+
- Every CafeCar page sets `turbo-refresh-method: morph` and
|
|
12
|
+
`turbo-refresh-scroll: preserve` (the `_head` partial), so refreshes patch the
|
|
13
|
+
DOM in place — scroll position, open popovers, and form state survive.
|
|
14
|
+
- Create/update/destroy respond to `turbo_stream` with a page refresh
|
|
15
|
+
(`turbo_stream.refresh`), which morphs. Update also removes the record's modal
|
|
16
|
+
if it was edited in one.
|
|
17
|
+
- Every show page subscribes to its record: `turbo_stream_from(object)` is in the
|
|
18
|
+
default show template.
|
|
19
|
+
|
|
20
|
+
## Cross-client live sync is a one-line host opt-in
|
|
21
|
+
|
|
22
|
+
The subscription is only useful if the model broadcasts. Add Rails'
|
|
23
|
+
`broadcasts_refreshes` to the model:
|
|
24
|
+
|
|
25
|
+
```ruby
|
|
26
|
+
class Invoice < ApplicationRecord
|
|
27
|
+
broadcasts_refreshes
|
|
28
|
+
end
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Now any save/destroy — from another browser, a job, the console — morph-refreshes
|
|
32
|
+
every open show page for that record. Requires a working ActionCable/Solid Cable
|
|
33
|
+
setup in the host, as with any Turbo broadcast.
|
|
34
|
+
|
|
35
|
+
## Customizing
|
|
36
|
+
|
|
37
|
+
Override the turbo_stream response per resource like any view
|
|
38
|
+
([views.md](views.md)):
|
|
39
|
+
|
|
40
|
+
```haml
|
|
41
|
+
-# app/views/admin/products/update.turbo_stream.haml
|
|
42
|
+
= turbo_stream.refresh request_id: nil
|
|
43
|
+
= turbo_stream.append "audit_log", partial: "audit_entry", locals: { product: @product }
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Keep the `refresh` line unless you're deliberately replacing morphing with targeted
|
|
47
|
+
streams.
|
|
48
|
+
|
|
49
|
+
## Don't break it
|
|
50
|
+
|
|
51
|
+
When writing custom views for a CafeCar resource, keep `turbo_stream_from(object)`
|
|
52
|
+
on detail pages and don't strip the `_head` meta tags — hand-rolled pages that drop
|
|
53
|
+
these are how admins lose live updates.
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Views and the override system
|
|
2
|
+
|
|
3
|
+
This is the crux of CafeCar: the gem ships default templates; a host replaces any
|
|
4
|
+
one of them by dropping a same-named file. You delete view files, you don't write
|
|
5
|
+
folders of them.
|
|
6
|
+
|
|
7
|
+
## The two engine view roots
|
|
8
|
+
|
|
9
|
+
- `app/views/application/` (in the gem) — **shared partials**: `_table`, `_grid`,
|
|
10
|
+
`_form`, `_show`, `_search`, `_navigation`, … Resolved through normal controller
|
|
11
|
+
prefix fallback (every host controller inherits `ApplicationController`).
|
|
12
|
+
- `app/views/cafe_car/application/` (in the gem) — **action templates and
|
|
13
|
+
turbo_stream responses**: `index.html.haml`, `show.html.haml`, `new`, `edit`,
|
|
14
|
+
`create/update/destroy.turbo_stream.haml`.
|
|
15
|
+
|
|
16
|
+
## Precedence (first match wins)
|
|
17
|
+
|
|
18
|
+
1. `app/views/<controller_path>/…` in the host — one resource
|
|
19
|
+
(e.g. `app/views/admin/products/_grid_item.html.haml`)
|
|
20
|
+
2. `app/views/application/…` in the host — app-wide partial override
|
|
21
|
+
3. `app/views/cafe_car/application/…` in the host — app-wide action-template override
|
|
22
|
+
4. the gem's defaults
|
|
23
|
+
|
|
24
|
+
Start by copying the gem's default (`cd "$(bundle show cafe_car)"`) and trimming.
|
|
25
|
+
Most defaults are 1–10 lines — the composition happens in helpers and policies, so
|
|
26
|
+
overrides stay small.
|
|
27
|
+
|
|
28
|
+
## The key overridable partials
|
|
29
|
+
|
|
30
|
+
| Partial | Renders |
|
|
31
|
+
|---|---|
|
|
32
|
+
| `_index` | index body: toolbar (search + bulk bar), the current view, pagination |
|
|
33
|
+
| `_table` | the table: `table_for` with select/logo/title/remaining/timestamps/controls columns |
|
|
34
|
+
| `_grid` / `_grid_item` | card grid; `_grid_item` is one card |
|
|
35
|
+
| `_show` | show-page body: remaining attributes + associations |
|
|
36
|
+
| `_form` / `_fields` | the form card; `_fields` is just `f.remaining_fields` |
|
|
37
|
+
| `_field`, `_<type>_field` | one form field (see [forms.md](forms.md)) |
|
|
38
|
+
| `_controls` | the show/edit/delete link cluster on rows and cards |
|
|
39
|
+
| `_search` | the index search box |
|
|
40
|
+
| `_bulk_actions` | the bulk-action button bar (defaults to looping the policy's list) |
|
|
41
|
+
| `_navigation`, `_navigation_links` | the sidebar (see [navigation.md](navigation.md)) |
|
|
42
|
+
| `_index_actions` | index toolbar right side: view toggles, CSV, New button |
|
|
43
|
+
| `_head` | the `<head>`: meta, stylesheets, importmap |
|
|
44
|
+
| `_alerts`, `_errors`, `_empty`, `_submit` | flash messages, form errors, empty state, submit row |
|
|
45
|
+
|
|
46
|
+
## Worked example: buttons on the grid cards
|
|
47
|
+
|
|
48
|
+
The gem's whole `_grid_item.html.haml`:
|
|
49
|
+
|
|
50
|
+
```haml
|
|
51
|
+
= Card title: object.title, image: object.logo(href: object), actions: object.controls
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`object` is a presenter. To add a field and a custom button for one resource:
|
|
55
|
+
|
|
56
|
+
```haml
|
|
57
|
+
-# app/views/admin/products/_grid_item.html.haml
|
|
58
|
+
= Card title: object.title, image: object.logo(href: object), actions: object.controls do |card|
|
|
59
|
+
= card.Section object.show(:price)
|
|
60
|
+
= card.Foot do
|
|
61
|
+
= button_to t(:restock), restock_admin_product_path(object.object), class: ui.Button(:primary).class_name
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
(`object.object` is the record; a custom member action needs its own route +
|
|
65
|
+
controller action today. The button label goes in the locale.) Drop the same file
|
|
66
|
+
in `app/views/application/` to change every resource's card.
|
|
67
|
+
|
|
68
|
+
## Worked example: a bespoke index
|
|
69
|
+
|
|
70
|
+
```haml
|
|
71
|
+
-# app/views/articles/index.html.haml — replaces the whole action template
|
|
72
|
+
= Page :slim, :center do |page|
|
|
73
|
+
= page.Body do
|
|
74
|
+
- @articles.each do |article|
|
|
75
|
+
%article
|
|
76
|
+
%h2= p article
|
|
77
|
+
%p= article.summary
|
|
78
|
+
= paginate @articles
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Full control, and you keep the layout, filtering, pagination, and helpers. Prefer
|
|
82
|
+
overriding the smallest partial that's wrong (`_grid_item`, not `index`).
|
|
83
|
+
|
|
84
|
+
## Turbo_stream templates
|
|
85
|
+
|
|
86
|
+
Per-resource turbo responses override the same way:
|
|
87
|
+
`app/views/admin/products/update.turbo_stream.haml` replaces the default
|
|
88
|
+
morph-refresh response for that resource. See [turbo.md](turbo.md).
|
|
89
|
+
|
|
90
|
+
## Design rules (owner-set, hold to them)
|
|
91
|
+
|
|
92
|
+
- Configuration happens **in views and partials** (plus the policy) — never invent
|
|
93
|
+
a config DSL or initializer registry.
|
|
94
|
+
- **All copy in locales** — no hardcoded UI strings in templates
|
|
95
|
+
([locales.md](locales.md)).
|
|
96
|
+
- **No global CSS** — styles belong to components ([components.md](components.md)).
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cafe_car
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jeff Peterson
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-07-
|
|
11
|
+
date: 2026-07-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -192,17 +192,20 @@ dependencies:
|
|
|
192
192
|
- - ">="
|
|
193
193
|
- !ruby/object:Gem::Version
|
|
194
194
|
version: '4.0'
|
|
195
|
-
description: CafeCar is a
|
|
196
|
-
index, show, new, and edit interfaces straight from your models, with no
|
|
197
|
-
|
|
198
|
-
pagination, and
|
|
199
|
-
|
|
195
|
+
description: 'CafeCar is a composable view extension for Rails: it renders complete
|
|
196
|
+
index, show, new, and edit interfaces straight from your models, with no DSL and
|
|
197
|
+
no boilerplate. Every index ships with keyword search, URL-based filtering and sorting,
|
|
198
|
+
pagination, and one-click CSV export. Authorization runs on Pundit with attribute-level
|
|
199
|
+
permissions; forms and Turbo Stream (Hotwire) responses render automatically. Every
|
|
200
|
+
default can be overridden application-wide or per model with ordinary Rails. It
|
|
201
|
+
makes admin panels, internal tools, and back-office apps on Rails 8 trivial.'
|
|
200
202
|
email:
|
|
201
203
|
- jeff@yak.sh
|
|
202
204
|
executables: []
|
|
203
205
|
extensions: []
|
|
204
206
|
extra_rdoc_files: []
|
|
205
207
|
files:
|
|
208
|
+
- ".claude-plugin/marketplace.json"
|
|
206
209
|
- MIT-LICENSE
|
|
207
210
|
- README.md
|
|
208
211
|
- Rakefile
|
|
@@ -212,18 +215,21 @@ files:
|
|
|
212
215
|
- app/assets/stylesheets/actiontext.css
|
|
213
216
|
- app/assets/stylesheets/application.css
|
|
214
217
|
- app/assets/stylesheets/cafe_car.css
|
|
218
|
+
- app/assets/stylesheets/cafe_car/chart.css
|
|
215
219
|
- app/assets/stylesheets/cafe_car/code/base16-dark.css
|
|
216
220
|
- app/assets/stylesheets/cafe_car/code/base16-light.css
|
|
221
|
+
- app/assets/stylesheets/cafe_car/dashboard.css
|
|
222
|
+
- app/assets/stylesheets/cafe_car/filters.css
|
|
217
223
|
- app/assets/stylesheets/cafe_car/pagination.css
|
|
218
224
|
- app/assets/stylesheets/cafe_car/themes/cool.css
|
|
219
225
|
- app/assets/stylesheets/cafe_car/themes/cool2.css
|
|
220
226
|
- app/assets/stylesheets/cafe_car/themes/defaults.css
|
|
221
|
-
- app/assets/stylesheets/cafe_car/themes/warm-dark.css
|
|
222
227
|
- app/assets/stylesheets/cafe_car/themes/warm.css
|
|
223
228
|
- app/assets/stylesheets/cafe_car/tooltips.css
|
|
224
229
|
- app/assets/stylesheets/cafe_car/trix.css
|
|
225
230
|
- app/assets/stylesheets/cafe_car/utility.css
|
|
226
231
|
- app/assets/stylesheets/iconoir.css
|
|
232
|
+
- app/assets/stylesheets/tom-select.css
|
|
227
233
|
- app/assets/stylesheets/ui/Alert.css
|
|
228
234
|
- app/assets/stylesheets/ui/Article.css
|
|
229
235
|
- app/assets/stylesheets/ui/Button.css
|
|
@@ -250,11 +256,13 @@ files:
|
|
|
250
256
|
- app/assets/stylesheets/ui/Table.css
|
|
251
257
|
- app/assets/stylesheets/ui/components.css
|
|
252
258
|
- app/controllers/cafe_car/application_controller.rb
|
|
259
|
+
- app/controllers/cafe_car/dashboards_controller.rb
|
|
253
260
|
- app/controllers/cafe_car/examples_controller.rb
|
|
254
261
|
- app/controllers/cafe_car/sessions_controller.rb
|
|
255
262
|
- app/controllers/concerns/cafe_car/authentication.rb
|
|
256
263
|
- app/javascript/application.js
|
|
257
264
|
- app/javascript/cafe_car.js
|
|
265
|
+
- app/javascript/tom-select.complete.min.js
|
|
258
266
|
- app/models/cafe_car/session.rb
|
|
259
267
|
- app/policies/cafe_car/application_policy.rb
|
|
260
268
|
- app/policies/cafe_car/session_policy.rb
|
|
@@ -286,20 +294,28 @@ files:
|
|
|
286
294
|
- app/ui/cafe_car/ui/layout.rb
|
|
287
295
|
- app/ui/cafe_car/ui/page.rb
|
|
288
296
|
- app/views/application/_actions.html.haml
|
|
297
|
+
- app/views/application/_active_filters.html.haml
|
|
289
298
|
- app/views/application/_alerts.html.haml
|
|
290
299
|
- app/views/application/_aside.html.haml
|
|
300
|
+
- app/views/application/_belongs_to_filter.html.haml
|
|
291
301
|
- app/views/application/_body.html.haml
|
|
302
|
+
- app/views/application/_boolean_filter.html.haml
|
|
303
|
+
- app/views/application/_bulk_actions.html.haml
|
|
304
|
+
- app/views/application/_chart.html.haml
|
|
292
305
|
- app/views/application/_controls.html.haml
|
|
293
306
|
- app/views/application/_debug.html.haml
|
|
294
307
|
- app/views/application/_empty.html.haml
|
|
308
|
+
- app/views/application/_enum_filter.html.haml
|
|
295
309
|
- app/views/application/_errors.html.haml
|
|
296
310
|
- app/views/application/_field.html.haml
|
|
297
311
|
- app/views/application/_fields.html.haml
|
|
312
|
+
- app/views/application/_filter.html.haml
|
|
298
313
|
- app/views/application/_filters.html.haml
|
|
299
314
|
- app/views/application/_footer.html.haml
|
|
300
315
|
- app/views/application/_form.html.haml
|
|
301
316
|
- app/views/application/_grid.html.haml
|
|
302
317
|
- app/views/application/_grid_item.html.haml
|
|
318
|
+
- app/views/application/_has_many_filter.html.haml
|
|
303
319
|
- app/views/application/_head.html.haml
|
|
304
320
|
- app/views/application/_index.html.haml
|
|
305
321
|
- app/views/application/_index_actions.html.haml
|
|
@@ -308,10 +324,13 @@ files:
|
|
|
308
324
|
- app/views/application/_nested_field.html.haml
|
|
309
325
|
- app/views/application/_notes.html.haml
|
|
310
326
|
- app/views/application/_popup.html.haml
|
|
311
|
-
- app/views/application/
|
|
327
|
+
- app/views/application/_range_filter.html.haml
|
|
328
|
+
- app/views/application/_scope_filter.html.haml
|
|
312
329
|
- app/views/application/_show.html.haml
|
|
330
|
+
- app/views/application/_string_filter.html.haml
|
|
313
331
|
- app/views/application/_submit.html.haml
|
|
314
332
|
- app/views/application/_table.html.haml
|
|
333
|
+
- app/views/application/_text_filter.html.haml
|
|
315
334
|
- app/views/cafe_car/application/create.turbo_stream.haml
|
|
316
335
|
- app/views/cafe_car/application/destroy.turbo_stream.haml
|
|
317
336
|
- app/views/cafe_car/application/edit.html.haml
|
|
@@ -321,6 +340,8 @@ files:
|
|
|
321
340
|
- app/views/cafe_car/application/new.turbo_stream.haml
|
|
322
341
|
- app/views/cafe_car/application/show.html.haml
|
|
323
342
|
- app/views/cafe_car/application/update.turbo_stream.haml
|
|
343
|
+
- app/views/cafe_car/dashboard/_chart.html.haml
|
|
344
|
+
- app/views/cafe_car/dashboard/_metric.html.haml
|
|
324
345
|
- app/views/cafe_car/examples/_example.html.haml
|
|
325
346
|
- app/views/cafe_car/examples/_index.html.haml
|
|
326
347
|
- app/views/cafe_car/examples/_index_actions.html.haml
|
|
@@ -362,8 +383,8 @@ files:
|
|
|
362
383
|
- lib/cafe_car/active_record.rb
|
|
363
384
|
- lib/cafe_car/application_responder.rb
|
|
364
385
|
- lib/cafe_car/attributes.rb
|
|
365
|
-
- lib/cafe_car/auto_resolver.rb
|
|
366
386
|
- lib/cafe_car/caching.rb
|
|
387
|
+
- lib/cafe_car/chart_builder.rb
|
|
367
388
|
- lib/cafe_car/component.rb
|
|
368
389
|
- lib/cafe_car/context.rb
|
|
369
390
|
- lib/cafe_car/controller.rb
|
|
@@ -388,11 +409,19 @@ files:
|
|
|
388
409
|
- lib/cafe_car/href_builder.rb
|
|
389
410
|
- lib/cafe_car/informable.rb
|
|
390
411
|
- lib/cafe_car/input_builder.rb
|
|
391
|
-
- lib/cafe_car/inputs/
|
|
412
|
+
- lib/cafe_car/inputs/association_input.rb
|
|
392
413
|
- lib/cafe_car/inputs/base_input.rb
|
|
393
|
-
- lib/cafe_car/inputs/
|
|
414
|
+
- lib/cafe_car/inputs/boolean_input.rb
|
|
415
|
+
- lib/cafe_car/inputs/date_input.rb
|
|
416
|
+
- lib/cafe_car/inputs/datetime_input.rb
|
|
417
|
+
- lib/cafe_car/inputs/file_input.rb
|
|
418
|
+
- lib/cafe_car/inputs/nested_input.rb
|
|
419
|
+
- lib/cafe_car/inputs/number_input.rb
|
|
394
420
|
- lib/cafe_car/inputs/password_input.rb
|
|
421
|
+
- lib/cafe_car/inputs/rich_text_input.rb
|
|
422
|
+
- lib/cafe_car/inputs/select_input.rb
|
|
395
423
|
- lib/cafe_car/inputs/string_input.rb
|
|
424
|
+
- lib/cafe_car/inputs/text_area_input.rb
|
|
396
425
|
- lib/cafe_car/link_builder.rb
|
|
397
426
|
- lib/cafe_car/model.rb
|
|
398
427
|
- lib/cafe_car/model_info.rb
|
|
@@ -419,6 +448,8 @@ files:
|
|
|
419
448
|
- lib/cafe_car/ui.rb
|
|
420
449
|
- lib/cafe_car/version.rb
|
|
421
450
|
- lib/cafe_car/visitors.rb
|
|
451
|
+
- lib/generators/cafe_car/agents/USAGE
|
|
452
|
+
- lib/generators/cafe_car/agents/agents_generator.rb
|
|
422
453
|
- lib/generators/cafe_car/controller/USAGE
|
|
423
454
|
- lib/generators/cafe_car/controller/controller_generator.rb
|
|
424
455
|
- lib/generators/cafe_car/controller/templates/controller.rb.tt
|
|
@@ -439,8 +470,19 @@ files:
|
|
|
439
470
|
- lib/generators/cafe_car/sessions/sessions_generator.rb
|
|
440
471
|
- lib/generators/cafe_car/sessions/templates/create_sessions.rb.tt
|
|
441
472
|
- lib/tasks/cafe_car_tasks.rake
|
|
442
|
-
- lib/tasks/
|
|
443
|
-
-
|
|
473
|
+
- lib/tasks/demo.rake
|
|
474
|
+
- llms.txt
|
|
475
|
+
- skills/cafe_car/SKILL.md
|
|
476
|
+
- skills/cafe_car/references/components.md
|
|
477
|
+
- skills/cafe_car/references/controllers.md
|
|
478
|
+
- skills/cafe_car/references/filtering.md
|
|
479
|
+
- skills/cafe_car/references/forms.md
|
|
480
|
+
- skills/cafe_car/references/locales.md
|
|
481
|
+
- skills/cafe_car/references/navigation.md
|
|
482
|
+
- skills/cafe_car/references/policies.md
|
|
483
|
+
- skills/cafe_car/references/presenters.md
|
|
484
|
+
- skills/cafe_car/references/turbo.md
|
|
485
|
+
- skills/cafe_car/references/views.md
|
|
444
486
|
homepage: https://craft-concept.github.io/cafe_car
|
|
445
487
|
licenses:
|
|
446
488
|
- MIT
|
|
@@ -468,6 +510,7 @@ requirements: []
|
|
|
468
510
|
rubygems_version: 3.5.22
|
|
469
511
|
signing_key:
|
|
470
512
|
specification_version: 4
|
|
471
|
-
summary:
|
|
472
|
-
|
|
513
|
+
summary: A composable view extension for Rails — render index, show, new, and edit
|
|
514
|
+
straight from your models, with keyword search, filtering, CSV export, and Pundit
|
|
515
|
+
authorization, then override any default with ordinary Rails.
|
|
473
516
|
test_files: []
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
@import url(defaults.css);
|
|
2
|
-
|
|
3
|
-
:root {
|
|
4
|
-
--blue: rgb(35, 175, 208);
|
|
5
|
-
|
|
6
|
-
--input: #1e1e1d;
|
|
7
|
-
--background: #191918;
|
|
8
|
-
--button: #333;
|
|
9
|
-
|
|
10
|
-
--color: #e7e3dc;
|
|
11
|
-
--dim: #6c7a91;
|
|
12
|
-
|
|
13
|
-
--card: #222221;
|
|
14
|
-
--border: #2A2A28;
|
|
15
|
-
--hover: rgb(42, 42, 40);
|
|
16
|
-
--shadow: rgba(0, 0, 0, 0.2);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
body {
|
|
20
|
-
scrollbar-color: rgb(73, 72, 70) rgb(25, 25, 24);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
.Card, .Table {
|
|
24
|
-
border: 0;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
.Table_Head {
|
|
28
|
-
background-color: var(--card);
|
|
29
|
-
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
= form_with url: "", method: :get, class: "search" do |f|
|
|
2
|
-
- dot_params.each do |key, value|
|
|
3
|
-
= hidden_field_tag key, value
|
|
4
|
-
= hidden_field_tag :sort, params[:sort] if params[:sort].present?
|
|
5
|
-
= f.search_field :q, value: search_term, placeholder: t(:search, scope: :helpers, default: "Search")
|
|
6
|
-
= f.button "Search", name: nil
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
module CafeCar
|
|
2
|
-
module AutoResolver
|
|
3
|
-
def auto_resolve!(mod)
|
|
4
|
-
mod.instance_eval <<~RUBY, __FILE__, __LINE__
|
|
5
|
-
def const_missing(name)
|
|
6
|
-
super
|
|
7
|
-
rescue NameError
|
|
8
|
-
CafeCar.define(self, name) or raise
|
|
9
|
-
end
|
|
10
|
-
RUBY
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def define(mod, name)
|
|
14
|
-
case name.to_s
|
|
15
|
-
when /^\w+Controller$/
|
|
16
|
-
TOPLEVEL_BINDING.eval <<~RUBY, __FILE__, __LINE__
|
|
17
|
-
class #{mod.name}::#{name} < CafeCar[:ApplicationController]
|
|
18
|
-
include CafeCar::Controller
|
|
19
|
-
cafe_car
|
|
20
|
-
self
|
|
21
|
-
end
|
|
22
|
-
RUBY
|
|
23
|
-
when /^\w+Policy$/
|
|
24
|
-
TOPLEVEL_BINDING.eval <<~RUBY, __FILE__, __LINE__
|
|
25
|
-
class #{mod.name}::#{name} < CafeCar[:ApplicationPolicy]
|
|
26
|
-
def admin? = Rails.env.development?
|
|
27
|
-
|
|
28
|
-
def index? = admin?
|
|
29
|
-
def show? = admin?
|
|
30
|
-
def create? = admin?
|
|
31
|
-
def update? = admin?
|
|
32
|
-
def destroy? = admin?
|
|
33
|
-
|
|
34
|
-
def permitted_attributes
|
|
35
|
-
model.info.fields.names.then do |names|
|
|
36
|
-
[*model.primary_key].reverse.map(&:to_sym) & names | names
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
class Scope < Scope
|
|
41
|
-
def resolve = scope.all
|
|
42
|
-
end
|
|
43
|
-
self
|
|
44
|
-
end
|
|
45
|
-
RUBY
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|