elaine_crud 0.1.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 +7 -0
- data/.rspec +3 -0
- data/LICENSE +21 -0
- data/README.md +225 -0
- data/Rakefile +9 -0
- data/TODO.md +496 -0
- data/app/controllers/elaine_crud/base_controller.rb +228 -0
- data/app/helpers/elaine_crud/base_helper.rb +787 -0
- data/app/helpers/elaine_crud/search_helper.rb +132 -0
- data/app/javascript/controllers/dropdown_controller.js +18 -0
- data/app/views/elaine_crud/base/_edit_row.html.erb +60 -0
- data/app/views/elaine_crud/base/_export_button.html.erb +88 -0
- data/app/views/elaine_crud/base/_foreign_key_select_refresh.html.erb +52 -0
- data/app/views/elaine_crud/base/_form.html.erb +45 -0
- data/app/views/elaine_crud/base/_form_fields.html.erb +45 -0
- data/app/views/elaine_crud/base/_index_table.html.erb +58 -0
- data/app/views/elaine_crud/base/_modal.html.erb +71 -0
- data/app/views/elaine_crud/base/_pagination.html.erb +110 -0
- data/app/views/elaine_crud/base/_per_page_selector.html.erb +30 -0
- data/app/views/elaine_crud/base/_search_bar.html.erb +75 -0
- data/app/views/elaine_crud/base/_show_details.html.erb +29 -0
- data/app/views/elaine_crud/base/_view_row.html.erb +96 -0
- data/app/views/elaine_crud/base/edit.html.erb +51 -0
- data/app/views/elaine_crud/base/index.html.erb +74 -0
- data/app/views/elaine_crud/base/new.html.erb +12 -0
- data/app/views/elaine_crud/base/new_modal.html.erb +37 -0
- data/app/views/elaine_crud/base/not_found.html.erb +49 -0
- data/app/views/elaine_crud/base/show.html.erb +32 -0
- data/docs/ARCHITECTURE.md +410 -0
- data/docs/CSS_GRID_LAYOUT.md +126 -0
- data/docs/DEMO.md +693 -0
- data/docs/DSL_EXAMPLES.md +313 -0
- data/docs/FOREIGN_KEY_EXAMPLE.rb +100 -0
- data/docs/FOREIGN_KEY_SUPPORT.md +197 -0
- data/docs/HAS_MANY_IMPLEMENTATION.md +154 -0
- data/docs/LAYOUT_EXAMPLES.md +301 -0
- data/docs/TROUBLESHOOTING.md +170 -0
- data/elaine_crud.gemspec +46 -0
- data/lib/elaine_crud/dsl_methods.rb +348 -0
- data/lib/elaine_crud/engine.rb +37 -0
- data/lib/elaine_crud/export_handling.rb +164 -0
- data/lib/elaine_crud/field_configuration.rb +422 -0
- data/lib/elaine_crud/field_configuration_methods.rb +152 -0
- data/lib/elaine_crud/layout_calculation.rb +55 -0
- data/lib/elaine_crud/parameter_handling.rb +48 -0
- data/lib/elaine_crud/record_fetching.rb +150 -0
- data/lib/elaine_crud/relationship_handling.rb +220 -0
- data/lib/elaine_crud/routing.rb +33 -0
- data/lib/elaine_crud/search_and_filtering.rb +285 -0
- data/lib/elaine_crud/sorting_concern.rb +65 -0
- data/lib/elaine_crud/version.rb +5 -0
- data/lib/elaine_crud.rb +25 -0
- data/lib/tasks/demo.rake +111 -0
- data/lib/tasks/spec.rake +26 -0
- metadata +264 -0
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
# ElaineCrud Architecture Documentation
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
ElaineCrud is a Ruby gem that provides a Rails Engine for rapidly generating CRUD (Create, Read, Update, Delete) interfaces for ActiveRecord models. The gem follows Rails conventions and provides a minimal, ergonomic DSL for creating database admin interfaces with zero boilerplate.
|
|
6
|
+
|
|
7
|
+
## Design Goals
|
|
8
|
+
|
|
9
|
+
- **Minimal Configuration**: Developers should only need to specify the model and permitted attributes
|
|
10
|
+
- **Convention over Configuration**: Follow Rails patterns and conventions
|
|
11
|
+
- **Non-Mountable Engine**: Integrate seamlessly with host applications without namespace isolation
|
|
12
|
+
- **Zero External Dependencies**: Only depend on Rails itself
|
|
13
|
+
- **Customizable**: Allow host applications to override views and behavior
|
|
14
|
+
- **Modern UI**: Provide clean, responsive interfaces using TailwindCSS
|
|
15
|
+
|
|
16
|
+
## Architecture Overview
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
20
|
+
│ Host Rails App │
|
|
21
|
+
│ ┌───────────────────────────────────────────────────────────┐ │
|
|
22
|
+
│ │ Custom Controller │ │
|
|
23
|
+
│ │ class PeopleController < ElaineCrud::BaseController │ │
|
|
24
|
+
│ │ model Person │ │
|
|
25
|
+
│ │ permit_params :name, :email │ │
|
|
26
|
+
│ │ end │ │
|
|
27
|
+
│ └───────────────────────────────────────────────────────────┘ │
|
|
28
|
+
│ │ │
|
|
29
|
+
│ ▼ │
|
|
30
|
+
│ ┌───────────────────────────────────────────────────────────┐ │
|
|
31
|
+
│ │ Routes │ │
|
|
32
|
+
│ │ resources :people │ │
|
|
33
|
+
│ └───────────────────────────────────────────────────────────┘ │
|
|
34
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
35
|
+
│
|
|
36
|
+
▼
|
|
37
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
38
|
+
│ ElaineCrud Engine │
|
|
39
|
+
│ ┌───────────────────────────────────────────────────────────┐ │
|
|
40
|
+
│ │ BaseController │ │
|
|
41
|
+
│ │ • Model introspection │ │
|
|
42
|
+
│ │ • Standard CRUD actions │ │
|
|
43
|
+
│ │ • Strong parameters │ │
|
|
44
|
+
│ │ • Column detection │ │
|
|
45
|
+
│ └───────────────────────────────────────────────────────────┘ │
|
|
46
|
+
│ ┌───────────────────────────────────────────────────────────┐ │
|
|
47
|
+
│ │ Default Views │ │
|
|
48
|
+
│ │ • Index listing with table │ │
|
|
49
|
+
│ │ • Smart column formatting │ │
|
|
50
|
+
│ │ • Action buttons (Edit, Delete) │ │
|
|
51
|
+
│ │ • TailwindCSS styling │ │
|
|
52
|
+
│ └───────────────────────────────────────────────────────────┘ │
|
|
53
|
+
│ ┌───────────────────────────────────────────────────────────┐ │
|
|
54
|
+
│ │ Helpers │ │
|
|
55
|
+
│ │ • Column value formatting │ │
|
|
56
|
+
│ │ • Boolean/Date display logic │ │
|
|
57
|
+
│ │ • Truncation and styling │ │
|
|
58
|
+
│ └───────────────────────────────────────────────────────────┘ │
|
|
59
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## File Structure
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
elaine_crud/
|
|
66
|
+
├── elaine_crud.gemspec # Gem specification
|
|
67
|
+
├── Gemfile # Development dependencies
|
|
68
|
+
├── lib/
|
|
69
|
+
│ ├── elaine_crud.rb # Main gem entry point
|
|
70
|
+
│ └── elaine_crud/
|
|
71
|
+
│ ├── version.rb # Version constant
|
|
72
|
+
│ └── engine.rb # Rails Engine configuration
|
|
73
|
+
├── app/
|
|
74
|
+
│ ├── controllers/
|
|
75
|
+
│ │ └── elaine_crud/
|
|
76
|
+
│ │ └── base_controller.rb # Core CRUD controller logic
|
|
77
|
+
│ ├── helpers/
|
|
78
|
+
│ │ └── elaine_crud/
|
|
79
|
+
│ │ └── base_helper.rb # View helper methods
|
|
80
|
+
│ └── views/
|
|
81
|
+
│ └── elaine_crud/
|
|
82
|
+
│ └── base/
|
|
83
|
+
│ └── index.html.erb # Default index view template
|
|
84
|
+
└── docs/
|
|
85
|
+
└── ARCHITECTURE.md # This documentation file
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Core Components
|
|
89
|
+
|
|
90
|
+
### 1. Engine Configuration (`lib/elaine_crud/engine.rb`)
|
|
91
|
+
|
|
92
|
+
The Rails Engine is configured as **non-mountable** to integrate seamlessly with host applications:
|
|
93
|
+
|
|
94
|
+
```ruby
|
|
95
|
+
module ElaineCrud
|
|
96
|
+
class Engine < ::Rails::Engine
|
|
97
|
+
# Non-mountable engine - do not call isolate_namespace
|
|
98
|
+
|
|
99
|
+
# Make app directories available to autoloader
|
|
100
|
+
config.autoload_paths << File.expand_path('../../app/controllers', __dir__)
|
|
101
|
+
config.autoload_paths << File.expand_path('../../app/helpers', __dir__)
|
|
102
|
+
|
|
103
|
+
# Add views to Rails view path
|
|
104
|
+
initializer 'elaine_crud.append_view_paths' do |app|
|
|
105
|
+
ActiveSupport.on_load :action_controller do
|
|
106
|
+
append_view_path File.expand_path('../../app/views', __dir__)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Include helpers globally
|
|
111
|
+
initializer 'elaine_crud.include_helpers' do
|
|
112
|
+
ActiveSupport.on_load :action_controller do
|
|
113
|
+
include ElaineCrud::BaseHelper
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**Key Design Decisions:**
|
|
121
|
+
- No `isolate_namespace` call ensures classes are available in global namespace
|
|
122
|
+
- Autoload paths ensure proper class loading
|
|
123
|
+
- View paths are appended, allowing host app views to override engine views
|
|
124
|
+
- Helpers are included globally for maximum compatibility
|
|
125
|
+
|
|
126
|
+
### 2. BaseController (`app/controllers/elaine_crud/base_controller.rb`)
|
|
127
|
+
|
|
128
|
+
The heart of the gem, providing a DSL and CRUD functionality:
|
|
129
|
+
|
|
130
|
+
```ruby
|
|
131
|
+
class ElaineCrud::BaseController < ActionController::Base
|
|
132
|
+
# No layout specified - host app controllers set their own layout
|
|
133
|
+
|
|
134
|
+
# Class-level configuration
|
|
135
|
+
class_attribute :crud_model, :permitted_attributes, :column_configurations
|
|
136
|
+
|
|
137
|
+
# DSL Methods
|
|
138
|
+
class << self
|
|
139
|
+
def model(model_class)
|
|
140
|
+
self.crud_model = model_class
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def permit_params(*attrs)
|
|
144
|
+
self.permitted_attributes = attrs
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def columns(config = {})
|
|
148
|
+
self.column_configurations = config
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Standard CRUD actions: index, show, new, create, edit, update, destroy
|
|
153
|
+
end
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**Features:**
|
|
157
|
+
- **Layout Agnostic**: No layout specified, host app controls HTML structure
|
|
158
|
+
- **Model Introspection**: Automatically detects columns and relationships
|
|
159
|
+
- **Strong Parameters**: Uses configured permitted attributes
|
|
160
|
+
- **Column Detection**: Filters out ID and timestamp columns by default
|
|
161
|
+
- **Extensible**: Subclasses can override any method for custom behavior
|
|
162
|
+
|
|
163
|
+
### 3. View Helpers (`app/helpers/elaine_crud/base_helper.rb`)
|
|
164
|
+
|
|
165
|
+
Smart formatting for different data types:
|
|
166
|
+
|
|
167
|
+
```ruby
|
|
168
|
+
def display_column_value(record, column)
|
|
169
|
+
value = record.public_send(column)
|
|
170
|
+
|
|
171
|
+
case value
|
|
172
|
+
when nil
|
|
173
|
+
content_tag(:span, '—', class: 'text-gray-400')
|
|
174
|
+
when true
|
|
175
|
+
content_tag(:span, '✓', class: 'text-green-600 font-bold')
|
|
176
|
+
when false
|
|
177
|
+
content_tag(:span, '✗', class: 'text-red-600 font-bold')
|
|
178
|
+
when Date, DateTime, Time
|
|
179
|
+
value.strftime('%m/%d/%Y')
|
|
180
|
+
else
|
|
181
|
+
truncate(value.to_s, length: 50)
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**Features:**
|
|
187
|
+
- **Type-Aware Formatting**: Different display logic for booleans, dates, nil values
|
|
188
|
+
- **Consistent Styling**: Uses TailwindCSS classes for visual consistency
|
|
189
|
+
- **Truncation**: Prevents long text from breaking table layout
|
|
190
|
+
|
|
191
|
+
### 4. Default Views (`app/views/elaine_crud/base/index.html.erb`)
|
|
192
|
+
|
|
193
|
+
Modern, responsive table interface:
|
|
194
|
+
|
|
195
|
+
```erb
|
|
196
|
+
<div class="container mx-auto px-4 py-8">
|
|
197
|
+
<div class="flex justify-between items-center mb-6">
|
|
198
|
+
<h1 class="text-3xl font-bold text-gray-900"><%= @model_name.pluralize %></h1>
|
|
199
|
+
<%= link_to "New #{@model_name}", url_for(action: :new),
|
|
200
|
+
class: "bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" %>
|
|
201
|
+
</div>
|
|
202
|
+
|
|
203
|
+
<% if @records.any? %>
|
|
204
|
+
<!-- Responsive table with TailwindCSS styling -->
|
|
205
|
+
<% else %>
|
|
206
|
+
<!-- Empty state with call-to-action -->
|
|
207
|
+
<% end %>
|
|
208
|
+
</div>
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**Features:**
|
|
212
|
+
- **Responsive Design**: Works on mobile and desktop
|
|
213
|
+
- **TailwindCSS Styling**: Modern, clean appearance
|
|
214
|
+
- **Empty States**: Helpful messaging when no records exist
|
|
215
|
+
- **Action Buttons**: Edit and Delete functionality
|
|
216
|
+
|
|
217
|
+
## Usage Pattern
|
|
218
|
+
|
|
219
|
+
### 1. Host Application Setup
|
|
220
|
+
|
|
221
|
+
Add to `Gemfile`:
|
|
222
|
+
```ruby
|
|
223
|
+
gem "elaine_crud", path: "../elaine_crud"
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### 2. Controller Creation
|
|
227
|
+
|
|
228
|
+
Create a minimal controller:
|
|
229
|
+
```ruby
|
|
230
|
+
class PeopleController < ElaineCrud::BaseController
|
|
231
|
+
layout 'application' # Host app specifies layout (header/footer/styling)
|
|
232
|
+
|
|
233
|
+
model Person
|
|
234
|
+
permit_params :name, :email, :phone, :active
|
|
235
|
+
end
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### 3. Route Configuration
|
|
239
|
+
|
|
240
|
+
Add standard Rails routes:
|
|
241
|
+
```ruby
|
|
242
|
+
resources :people
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### 4. Instant CRUD Interface
|
|
246
|
+
|
|
247
|
+
Navigate to `/people` for a fully functional CRUD interface with:
|
|
248
|
+
- Table listing of all records
|
|
249
|
+
- Automatic column detection and formatting
|
|
250
|
+
- Edit and delete functionality
|
|
251
|
+
- Clean, modern styling
|
|
252
|
+
|
|
253
|
+
## TailwindCSS Integration
|
|
254
|
+
|
|
255
|
+
### The Challenge
|
|
256
|
+
|
|
257
|
+
ElaineCrud provides views with TailwindCSS classes, but the gem itself doesn't bundle CSS. The host application needs to include these classes in its TailwindCSS build process.
|
|
258
|
+
|
|
259
|
+
### Solution Options
|
|
260
|
+
|
|
261
|
+
#### 1. Update Host App TailwindCSS Config (Recommended)
|
|
262
|
+
|
|
263
|
+
Add the gem's files to `tailwind.config.js`:
|
|
264
|
+
|
|
265
|
+
```javascript
|
|
266
|
+
module.exports = {
|
|
267
|
+
content: [
|
|
268
|
+
'./app/views/**/*.html.erb',
|
|
269
|
+
'./app/helpers/**/*.rb',
|
|
270
|
+
'./app/assets/stylesheets/**/*.css',
|
|
271
|
+
'./app/javascript/**/*.js',
|
|
272
|
+
// Include elaine_crud gem views for TailwindCSS class detection
|
|
273
|
+
'../elaine_crud/app/views/**/*.html.erb',
|
|
274
|
+
'../elaine_crud/app/helpers/**/*.rb'
|
|
275
|
+
],
|
|
276
|
+
// ... rest of config
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
#### 2. Safelist Critical Classes
|
|
281
|
+
|
|
282
|
+
Alternatively, add commonly used classes to the safelist:
|
|
283
|
+
|
|
284
|
+
```javascript
|
|
285
|
+
module.exports = {
|
|
286
|
+
safelist: [
|
|
287
|
+
'container', 'mx-auto', 'px-4', 'py-8',
|
|
288
|
+
'bg-blue-500', 'hover:bg-blue-700', 'text-white',
|
|
289
|
+
'bg-white', 'shadow-md', 'rounded-lg',
|
|
290
|
+
'table', 'min-w-full', 'divide-y', 'divide-gray-200',
|
|
291
|
+
// ... other ElaineCrud classes
|
|
292
|
+
]
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
#### 3. Gem-Level Configuration (Future Enhancement)
|
|
297
|
+
|
|
298
|
+
Future versions could provide a TailwindCSS plugin or configuration helper:
|
|
299
|
+
|
|
300
|
+
```ruby
|
|
301
|
+
# Potential future API
|
|
302
|
+
ElaineCrud.configure_tailwind(Rails.root.join('tailwind.config.js'))
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Current Status
|
|
306
|
+
|
|
307
|
+
The implemented solution updates the host application's TailwindCSS configuration to scan the gem's view files. This ensures all TailwindCSS classes used by ElaineCrud are included in the final CSS bundle.
|
|
308
|
+
|
|
309
|
+
## Current Implementation Status
|
|
310
|
+
|
|
311
|
+
### ✅ Completed Features
|
|
312
|
+
|
|
313
|
+
1. **Basic Gem Structure**
|
|
314
|
+
- Proper gemspec with Rails dependency
|
|
315
|
+
- Non-mountable engine configuration
|
|
316
|
+
- Autoloading and view path setup
|
|
317
|
+
|
|
318
|
+
2. **Core Controller**
|
|
319
|
+
- DSL for model and parameter configuration
|
|
320
|
+
- Standard CRUD action implementations
|
|
321
|
+
- Strong parameter handling
|
|
322
|
+
- Automatic column detection
|
|
323
|
+
|
|
324
|
+
3. **View System**
|
|
325
|
+
- Responsive index view with TailwindCSS
|
|
326
|
+
- Smart column value formatting
|
|
327
|
+
- Action buttons for edit/delete operations
|
|
328
|
+
- Empty state handling
|
|
329
|
+
|
|
330
|
+
4. **Helper System**
|
|
331
|
+
- Type-aware value formatting
|
|
332
|
+
- Boolean, date, and nil value handling
|
|
333
|
+
- Text truncation for long content
|
|
334
|
+
|
|
335
|
+
5. **Integration Testing**
|
|
336
|
+
- Successfully integrated with kotirails app
|
|
337
|
+
- Working daycare_browser controller for DaycareEntry model
|
|
338
|
+
- Verified HTTP 200 responses and proper HTML rendering
|
|
339
|
+
|
|
340
|
+
### 🚧 Future Enhancements (Not Yet Implemented)
|
|
341
|
+
|
|
342
|
+
1. **Sorting**: Clickable column headers for sorting
|
|
343
|
+
2. **Pagination**: Built-in pagination for large datasets
|
|
344
|
+
3. **Search/Filtering**: Basic search functionality
|
|
345
|
+
4. **Form Views**: New and edit form templates
|
|
346
|
+
5. **Column Configuration**: Advanced column display customization
|
|
347
|
+
6. **Validation Handling**: Proper error display for form submissions
|
|
348
|
+
|
|
349
|
+
## Design Philosophy
|
|
350
|
+
|
|
351
|
+
### Separation of Concerns
|
|
352
|
+
|
|
353
|
+
The gem follows a clean separation between content and presentation:
|
|
354
|
+
- **Engine provides**: CRUD logic, data formatting, content templates
|
|
355
|
+
- **Host app provides**: Layout, styling, HTML structure, navigation
|
|
356
|
+
- **Host app controls**: Headers, footers, CSS frameworks, page structure
|
|
357
|
+
|
|
358
|
+
### Convention over Configuration
|
|
359
|
+
|
|
360
|
+
The gem follows Rails conventions wherever possible:
|
|
361
|
+
- Standard CRUD action names
|
|
362
|
+
- RESTful routing patterns
|
|
363
|
+
- ActiveRecord assumptions
|
|
364
|
+
- Rails view helper patterns
|
|
365
|
+
|
|
366
|
+
### Minimal API Surface
|
|
367
|
+
|
|
368
|
+
The DSL is intentionally small:
|
|
369
|
+
- `model` - specify the ActiveRecord class
|
|
370
|
+
- `permit_params` - define strong parameters
|
|
371
|
+
- `layout` - host app specifies which layout to use
|
|
372
|
+
- `columns` - (future) customize column display
|
|
373
|
+
|
|
374
|
+
### Extensibility
|
|
375
|
+
|
|
376
|
+
Host applications can override any behavior:
|
|
377
|
+
- Views override engine views by Rails precedence
|
|
378
|
+
- Controller methods can be overridden in subclasses
|
|
379
|
+
- Helpers can be customized or extended
|
|
380
|
+
- Layout and styling completely controlled by host app
|
|
381
|
+
|
|
382
|
+
### Zero Configuration Default
|
|
383
|
+
|
|
384
|
+
The gem works with zero configuration for basic use cases:
|
|
385
|
+
- Automatic column detection
|
|
386
|
+
- Sensible defaults for display formatting
|
|
387
|
+
- Standard CRUD operations out of the box
|
|
388
|
+
|
|
389
|
+
## Example: DaycareEntry Integration
|
|
390
|
+
|
|
391
|
+
The implemented example shows the gem in action:
|
|
392
|
+
|
|
393
|
+
```ruby
|
|
394
|
+
# Controller (10 lines)
|
|
395
|
+
class DaycareBrowserController < ElaineCrud::BaseController
|
|
396
|
+
model DaycareEntry
|
|
397
|
+
permit_params :date, :pupu_sleep, :pupu_eat, :pentu_sleep, :pentu_eat
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
# Route (1 line)
|
|
401
|
+
resources :daycare_browser, except: [:show]
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
This generates a complete CRUD interface for the DaycareEntry model with:
|
|
405
|
+
- Table showing date, sleep, and eating data
|
|
406
|
+
- Proper formatting for different field types
|
|
407
|
+
- Edit and delete buttons
|
|
408
|
+
- Clean, professional styling
|
|
409
|
+
|
|
410
|
+
The implementation demonstrates the gem's core value proposition: **maximum functionality with minimal code**.
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# CSS Grid Layout
|
|
2
|
+
|
|
3
|
+
ElaineCrud uses CSS Grid-based layouts for all CRUD views, providing flexible and responsive data display with support for field spanning similar to HTML table `colspan` and `rowspan` attributes.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The system automatically:
|
|
8
|
+
- Calculates optimal grid columns based on field span configurations
|
|
9
|
+
- Encapsulates each ActiveRecord item in a `<div class="record">` with unique ID
|
|
10
|
+
- Supports both column and row spanning for flexible layouts
|
|
11
|
+
- Maintains inline editing capabilities within the grid structure
|
|
12
|
+
|
|
13
|
+
## Grid Span Configuration
|
|
14
|
+
|
|
15
|
+
Fields can span multiple columns and rows using the new grid configuration options:
|
|
16
|
+
|
|
17
|
+
### Column Spanning (similar to `colspan`)
|
|
18
|
+
|
|
19
|
+
```ruby
|
|
20
|
+
field :description do |f|
|
|
21
|
+
f.title "Description"
|
|
22
|
+
f.grid_column_span 2 # This field will span 2 columns
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Or using hash syntax:
|
|
26
|
+
field :description,
|
|
27
|
+
title: "Description",
|
|
28
|
+
grid_column_span: 3 # This field will span 3 columns
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Row Spanning (similar to `rowspan`)
|
|
32
|
+
|
|
33
|
+
```ruby
|
|
34
|
+
field :large_content do |f|
|
|
35
|
+
f.title "Large Content"
|
|
36
|
+
f.grid_row_span 2 # This field will span 2 rows
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Or using hash syntax:
|
|
40
|
+
field :large_content,
|
|
41
|
+
title: "Large Content",
|
|
42
|
+
grid_row_span: 2
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Combined Column and Row Spanning
|
|
46
|
+
|
|
47
|
+
```ruby
|
|
48
|
+
field :big_field do |f|
|
|
49
|
+
f.title "Big Field"
|
|
50
|
+
f.grid_column_span 2
|
|
51
|
+
f.grid_row_span 2 # This field will span 2x2 grid cells
|
|
52
|
+
end
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Example Usage
|
|
56
|
+
|
|
57
|
+
```ruby
|
|
58
|
+
class DaycareBrowserController < ElaineCrud::BaseController
|
|
59
|
+
model DaycareEntry
|
|
60
|
+
|
|
61
|
+
field :date, title: "Entry Date"
|
|
62
|
+
|
|
63
|
+
field :pupu_sleep,
|
|
64
|
+
title: "Pupu's Sleep",
|
|
65
|
+
options: DaycareEntry::SLEEP_OPTIONS
|
|
66
|
+
|
|
67
|
+
field :pupu_eat,
|
|
68
|
+
title: "Pupu's Eating",
|
|
69
|
+
options: DaycareEntry::EAT_OPTIONS
|
|
70
|
+
|
|
71
|
+
# Comments span 2 columns for more space
|
|
72
|
+
field :pupu_comments do |f|
|
|
73
|
+
f.title "Pupu Comments"
|
|
74
|
+
f.grid_column_span 2
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
field :pentu_sleep,
|
|
78
|
+
title: "Pentu's Sleep",
|
|
79
|
+
options: DaycareEntry::SLEEP_OPTIONS
|
|
80
|
+
|
|
81
|
+
field :pentu_eat,
|
|
82
|
+
title: "Pentu's Eating",
|
|
83
|
+
options: DaycareEntry::EAT_OPTIONS
|
|
84
|
+
|
|
85
|
+
# Comments span 2 columns for more space
|
|
86
|
+
field :pentu_comments do |f|
|
|
87
|
+
f.title "Pentu Comments"
|
|
88
|
+
f.grid_column_span 2
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## How It Works
|
|
94
|
+
|
|
95
|
+
1. **Grid Container**: Each record is wrapped in a `<div class="record">` with a unique ID based on the ActiveRecord ID (`record_#{record.id}`)
|
|
96
|
+
|
|
97
|
+
2. **Dynamic Columns**: The grid automatically calculates the total number of columns needed based on field spans
|
|
98
|
+
|
|
99
|
+
3. **Responsive**: Uses CSS Grid with `minmax(0, 1fr)` for responsive behavior
|
|
100
|
+
|
|
101
|
+
4. **Inline Editing**: The grid layout supports inline editing just like the table layout
|
|
102
|
+
|
|
103
|
+
## Template Files
|
|
104
|
+
|
|
105
|
+
- `elaine_crud/base/index.html.erb` - Main grid-based index view
|
|
106
|
+
- `elaine_crud/base/_edit_row.html.erb` - Grid-based inline edit partial
|
|
107
|
+
|
|
108
|
+
## CSS Classes
|
|
109
|
+
|
|
110
|
+
The system automatically applies appropriate Tailwind CSS classes:
|
|
111
|
+
- `col-span-1` to `col-span-6` for column spanning
|
|
112
|
+
- `row-span-1` to `row-span-6` for row spanning
|
|
113
|
+
|
|
114
|
+
These classes are included in the Tailwind safelist to ensure they're available at runtime.
|
|
115
|
+
|
|
116
|
+
## Record Encapsulation
|
|
117
|
+
|
|
118
|
+
Each ActiveRecord item is encapsulated in a `<div class="record">` with a unique ID based on the ActiveRecord ID:
|
|
119
|
+
|
|
120
|
+
```html
|
|
121
|
+
<div class="record" id="record_123">
|
|
122
|
+
<!-- Field grid layout here -->
|
|
123
|
+
</div>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
This ensures proper isolation and targeting for JavaScript interactions or styling.
|