plutonium 0.23.4 → 0.23.5

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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/plutonium.css +2 -2
  3. data/config/initializers/sqlite_json_alias.rb +1 -1
  4. data/docs/.vitepress/config.ts +60 -19
  5. data/docs/guide/cursor-rules.md +75 -0
  6. data/docs/guide/deep-dive/authorization.md +189 -0
  7. data/docs/guide/{getting-started → deep-dive}/resources.md +137 -0
  8. data/docs/guide/getting-started/{installation.md → 01-installation.md} +0 -105
  9. data/docs/guide/index.md +28 -0
  10. data/docs/guide/introduction/02-core-concepts.md +440 -0
  11. data/docs/guide/tutorial/01-project-setup.md +75 -0
  12. data/docs/guide/tutorial/02-creating-a-feature-package.md +45 -0
  13. data/docs/guide/tutorial/03-defining-resources.md +90 -0
  14. data/docs/guide/tutorial/04-creating-a-portal.md +101 -0
  15. data/docs/guide/tutorial/05-customizing-the-ui.md +128 -0
  16. data/docs/guide/tutorial/06-adding-custom-actions.md +101 -0
  17. data/docs/guide/tutorial/07-implementing-authorization.md +90 -0
  18. data/docs/index.md +24 -31
  19. data/docs/modules/action.md +190 -0
  20. data/docs/modules/authentication.md +236 -0
  21. data/docs/modules/configuration.md +599 -0
  22. data/docs/modules/controller.md +398 -0
  23. data/docs/modules/core.md +316 -0
  24. data/docs/modules/definition.md +876 -0
  25. data/docs/modules/display.md +759 -0
  26. data/docs/modules/form.md +605 -0
  27. data/docs/modules/generator.md +288 -0
  28. data/docs/modules/index.md +167 -0
  29. data/docs/modules/interaction.md +470 -0
  30. data/docs/modules/package.md +151 -0
  31. data/docs/modules/policy.md +176 -0
  32. data/docs/modules/portal.md +710 -0
  33. data/docs/modules/query.md +287 -0
  34. data/docs/modules/resource_record.md +618 -0
  35. data/docs/modules/routing.md +641 -0
  36. data/docs/modules/table.md +293 -0
  37. data/docs/modules/ui.md +631 -0
  38. data/docs/public/plutonium.mdc +667 -0
  39. data/lib/generators/pu/core/assets/assets_generator.rb +0 -5
  40. data/lib/plutonium/ui/display/resource.rb +7 -2
  41. data/lib/plutonium/ui/table/resource.rb +8 -3
  42. data/lib/plutonium/version.rb +1 -1
  43. metadata +36 -9
  44. data/docs/guide/getting-started/authorization.md +0 -296
  45. data/docs/guide/getting-started/core-concepts.md +0 -432
  46. data/docs/guide/getting-started/index.md +0 -21
  47. data/docs/guide/tutorial.md +0 -401
  48. /data/docs/guide/{what-is-plutonium.md → introduction/01-what-is-plutonium.md} +0 -0
@@ -0,0 +1,293 @@
1
+ ---
2
+ title: Table Module
3
+ ---
4
+
5
+ # Table Module
6
+
7
+ The Table module is a powerful system for creating data tables in Plutonium. It leverages `Phlexi::Table` to provide a rich set of features including smart column rendering, pagination, sorting, filtering, and search. It's designed to work seamlessly with Plutonium's resource definitions to help you build complex data displays with minimal effort.
8
+
9
+ ::: tip Architecture
10
+ The Table module lives in `lib/plutonium/ui/table/` and is composed of several key parts:
11
+ - **`Plutonium::UI::Table::Resource`**: The primary component for rendering resource-based tables.
12
+ - **Components**: UI elements like search bars, scope selectors, and pagination controls.
13
+ - **Themes**: Centralized styling for a consistent look and feel.
14
+ :::
15
+
16
+ ## Getting Started: Defining a Table
17
+
18
+ Everything about a table—its columns, filters, and behaviors—is defined within a resource definition file. You can use `display`, `column`, or `field` to define what data to show.
19
+
20
+ Here's a basic example for a `Post` resource:
21
+
22
+ ```ruby
23
+ # app/definitions/post_definition.rb
24
+ class PostDefinition < Plutonium::Resource::Definition
25
+ # Use `display` or `column` to define table columns.
26
+ display :author, as: :association
27
+ display :published_at, as: :datetime
28
+ display :status, as: :badge
29
+ display :actions, as: :actions, align: :right
30
+
31
+ # Define sorting
32
+ sort :title
33
+ sort :published_at
34
+
35
+ # Enable search
36
+ search do |scope, query|
37
+ scope.where("title ILIKE ?", "%#{query}%")
38
+ end
39
+
40
+ # Define filters
41
+ filter :published, with: Plutonium::Query::Filters::Text, predicate: :eq
42
+ filter :author, with: Plutonium::Query::Filters::Text, predicate: :eq
43
+
44
+ # Define query scopes
45
+ scope :published
46
+ scope :draft
47
+ end
48
+ ```
49
+
50
+ This configuration is all you need to render a feature-rich table for your posts.
51
+
52
+ ## Configuring Columns
53
+
54
+ Columns are the heart of your table. Plutonium offers flexible ways to configure them.
55
+
56
+ ### Column Types
57
+
58
+ You can render data in various formats using the `as:` option:
59
+
60
+ ```ruby
61
+ column :name, as: :string
62
+ column :email, as: :email
63
+ column :website, as: :link
64
+ column :published_at, as: :datetime
65
+ column :is_active, as: :boolean
66
+ column :priority, as: :badge
67
+ column :profile_picture, as: :attachment
68
+ column :metadata, as: :json
69
+ ```
70
+
71
+ ### Alignment
72
+
73
+ Control column alignment with the `align:` option.
74
+
75
+ ```ruby
76
+ column :title, align: :start # Left-aligned (default)
77
+ column :price, align: :end # Right-aligned
78
+ column :status, align: :center # Center-aligned
79
+ ```
80
+
81
+ ### Custom Column Rendering
82
+
83
+ For complete control over a column's output, provide a block. The block receives a wrapped record object.
84
+
85
+ ```ruby
86
+ class PostDefinition < Plutonium::Resource::Definition
87
+ # Basic custom rendering with a block
88
+ column :full_name do |wrapped_record|
89
+ # `unwrapped` gives you the original AR record
90
+ record = wrapped_record.unwrapped
91
+ "#{record.first_name} #{record.last_name}"
92
+ end
93
+
94
+ # Render a custom component for more complex UI
95
+ column :status do |wrapped_record|
96
+ # The `field` method provides access to the field's value and definition
97
+ field = wrapped_record.field(:status)
98
+ render StatusBadgeComponent.new(field.value)
99
+ end
100
+ end
101
+ ```
102
+
103
+ ### Conditional Columns
104
+
105
+ You can show or hide columns dynamically using the `condition` option. It accepts a lambda that is evaluated in the view context.
106
+
107
+ ```ruby
108
+ # Show a column only in the development environment
109
+ column :debug_info, condition: -> { Rails.env.development? }
110
+
111
+ # Show a column based on user permissions
112
+ column :admin_notes, condition: -> { current_user.admin? }
113
+ ```
114
+
115
+ ::: warning Security
116
+ Use `condition` for display logic, not for security. To control data visibility, you should filter `permitted_attributes_for_read` within your authorization policies.
117
+ :::
118
+
119
+ ## Searching and Filtering
120
+
121
+ Plutonium makes it easy to add powerful search and filtering capabilities to your tables.
122
+
123
+ ### Search
124
+
125
+ Define your search logic with the `search` method in your resource definition. The search bar will appear automatically.
126
+
127
+ ```ruby
128
+ class PostDefinition < Plutonium::Resource::Definition
129
+ # Simple search on a single field
130
+ search do |scope, search_term|
131
+ scope.where("title ILIKE ?", "%#{search_term}%")
132
+ end
133
+
134
+ # More complex search across multiple fields and associations
135
+ search do |scope, search_term|
136
+ scope.joins(:author)
137
+ .where(
138
+ "posts.title ILIKE :q OR posts.content ILIKE :q OR users.name ILIKE :q",
139
+ q: "%#{search_term}%"
140
+ )
141
+ end
142
+ end
143
+ ```
144
+
145
+ ### Filters
146
+
147
+ Declare filters using the `filter` method. Currently, Plutonium provides the Text filter with various predicates.
148
+
149
+ ```ruby
150
+ class PostDefinition < Plutonium::Resource::Definition
151
+ # Text filter with exact match
152
+ filter :status, with: Plutonium::Query::Filters::Text, predicate: :eq
153
+
154
+ # Text filter with contains matching
155
+ filter :title, with: Plutonium::Query::Filters::Text, predicate: :contains
156
+
157
+ # Text filter with starts_with matching
158
+ filter :category, with: Plutonium::Query::Filters::Text, predicate: :starts_with
159
+
160
+ # Custom filter with lambda
161
+ filter :published, with: ->(scope, value) {
162
+ value ? scope.where.not(published_at: nil) : scope.where(published_at: nil)
163
+ }
164
+ end
165
+ ```
166
+
167
+ Available Text filter predicates include: `:eq`, `:not_eq`, `:matches`, `:not_matches`, `:starts_with`, `:ends_with`, `:contains`, `:not_contains`.
168
+
169
+ ## Query Scopes
170
+
171
+ Scopes allow users to apply predefined queries with a single click. Define them using the `scope` method, which can reference an existing model scope or a new lambda.
172
+
173
+ ```ruby
174
+ class PostDefinition < Plutonium::Resource::Definition
175
+ # Reference existing scopes from the Post model
176
+ scope :published
177
+ scope :featured
178
+
179
+ # Define a custom scope with a lambda
180
+ scope :recent, -> { where("created_at > ?", 1.week.ago) }
181
+
182
+ # Set a default scope
183
+ scope :active, default: true
184
+ end
185
+ ```
186
+ A scopes bar will automatically be displayed above the table.
187
+
188
+ ## Sorting
189
+
190
+ Enable sorting on columns by defining a `sort` rule. Columns automatically become sortable when a sort definition exists for them.
191
+
192
+ ```ruby
193
+ class PostDefinition < Plutonium::Resource::Definition
194
+ # Define sort rules for columns
195
+ sort :title
196
+ sort :created_at
197
+ sort :updated_at
198
+
199
+ # Custom sorting logic
200
+ sort :author_name, using: "users.name" do |scope, direction:|
201
+ scope.joins(:author).order("users.name #{direction}")
202
+ end
203
+ end
204
+ ```
205
+
206
+ Plutonium's tables support both tri-state and multi-column sorting, providing flexible data exploration.
207
+
208
+ * **Tri-state Sorting**: Clicking a column header cycles through ascending (`ASC`), descending (`DESC`), and unsorted states for that column.
209
+ * **Multi-column Sorting**: You can apply sorting to multiple columns. Simply click on the headers of the columns you wish to sort by. The order in which you select them determines their priority. An indicator next to the column title shows the sort order and priority.
210
+
211
+ ## Pagination
212
+
213
+ Pagination is handled automatically by the excellent [Pagy](https://github.com/ddnexus/pagy) gem. In your controller, the `pagy` helper method prepares your records for pagination.
214
+
215
+ ```ruby
216
+ # In your controller (usually handled by Plutonium::Controller::CrudActions)
217
+ @pagy, @resource_records = pagy(current_authorized_scope)
218
+ ```
219
+
220
+ The table component renders pagination controls and an info bar, allowing users to navigate through pages and change the number of items per page.
221
+
222
+ ## Actions
223
+
224
+ Actions defined on your resource will automatically appear in the `actions` column for each row.
225
+
226
+ ```ruby
227
+ class PostDefinition < Plutonium::Resource::Definition
228
+ # Standard CRUD actions are available by default
229
+ # action :show
230
+ # action :edit
231
+ # action :destroy
232
+
233
+ # Add custom actions
234
+ action :publish, interaction: PublishPostInteraction
235
+ action :archive, interaction: ArchivePostInteraction
236
+ end
237
+ ```
238
+
239
+ Plutonium checks the user's permissions for each action and only displays the ones they are allowed to perform.
240
+
241
+ ## Customization
242
+
243
+ ### Overriding the Table View
244
+
245
+ For deep customization, you can define a nested `Table` class within your resource definition. This allows you to override any part of the table rendering process.
246
+
247
+ ```ruby
248
+ class PostDefinition < Plutonium::Resource::Definition
249
+ # Define a custom table class
250
+ class Table < Plutonium::UI::Table::Resource
251
+ private
252
+
253
+ # Customize the footer
254
+ def render_footer
255
+ div(class: "custom-footer") do
256
+ super # Render the original footer (pagination, etc.)
257
+ render_custom_stats
258
+ end
259
+ end
260
+
261
+ def render_custom_stats
262
+ div(class: "mt-4 text-sm text-gray-500") do
263
+ "Total Posts: #{collection.size}"
264
+ end
265
+ end
266
+ end
267
+ end
268
+ ```
269
+
270
+ ### Empty State
271
+
272
+ When a query returns no results, the table displays a helpful message. You can customize this by overriding `render_empty_card`.
273
+
274
+ ```ruby
275
+ class PostDefinition < Plutonium::Resource::Definition
276
+ class Table < Plutonium::UI::Table::Resource
277
+ private
278
+
279
+ def render_empty_card
280
+ EmptyCard("No posts were found.") {
281
+ # Optionally, add a call to action
282
+ if current_policy.allowed_to?(:create?)
283
+ # ... render a "Create Post" button
284
+ end
285
+ }
286
+ end
287
+ end
288
+ end
289
+ ```
290
+
291
+ ### Theming
292
+
293
+ The table's appearance is controlled by a central theme. You can inspect `lib/plutonium/ui/table/theme.rb` and `lib/plutonium/ui/table/display_theme.rb` to see the default Tailwind CSS classes and override them if needed.