elaine_crud 0.1.3 → 0.1.4
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 +242 -178
- data/app/controllers/elaine_crud/base_controller.rb +2 -2
- data/app/views/elaine_crud/base/edit_standalone.html.erb +12 -0
- data/docs/screenshots/departments.png +0 -0
- data/docs/screenshots/employees.png +0 -0
- data/docs/screenshots/screenshot1.png +0 -0
- data/lib/elaine_crud/version.rb +1 -1
- metadata +5 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6790f924718c05bea415357a3ace073990743e5e8c0014ea5380d674adbbc4f7
|
|
4
|
+
data.tar.gz: d1b352c734dbd526047a6503cdaed192dfa30daa05c3f92577f84f302d44e970
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1cdcb91a0a27cbb97a1d9db7cab2588263933a99d46f81423a18c447c9bd58b6bf0d478d81a53403f0f31249768fcfdd383207542dc23a7d29f239600cfd9dcc
|
|
7
|
+
data.tar.gz: '085b69b219b226dd5d2c1cbced974603c5da07833113f5eca33f6311d9f3febf10d4e91c0c592f751efd9bb61c23239a1ef03b23ad213dd0a6cc15893faccaa5'
|
data/README.md
CHANGED
|
@@ -1,14 +1,26 @@
|
|
|
1
1
|
# ElaineCrud
|
|
2
2
|
|
|
3
|
-
A Rails engine for rapidly generating CRUD interfaces for ActiveRecord models with minimal configuration.
|
|
3
|
+
A Rails engine for rapidly generating CRUD interfaces for ActiveRecord models with minimal configuration. This controller will create you the following CRUD interface:
|
|
4
|
+
```ruby
|
|
5
|
+
class TaskController < ElaineCrud::BaseController
|
|
6
|
+
layout 'application'
|
|
7
|
+
|
|
8
|
+
model Task # Your ActiveRecord model
|
|
9
|
+
permit_params :title, :description, :priority, :completed, :due_date
|
|
10
|
+
end
|
|
11
|
+
```
|
|
12
|
+

|
|
4
13
|
|
|
5
14
|
## Features
|
|
6
15
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
16
|
+
- **Zero Configuration**: Works out of the box with any ActiveRecord model
|
|
17
|
+
- **Rails Conventions**: Follows standard Rails patterns
|
|
18
|
+
- **Minimal Code**: Just specify model and permitted params
|
|
19
|
+
- **Search & Filter**: Built-in search across text fields
|
|
20
|
+
- **Sortable Columns**: Click column headers to sort
|
|
21
|
+
- **Pagination**: Automatic pagination with configurable page size
|
|
22
|
+
- **Export**: Download data as CSV, Excel, or JSON
|
|
23
|
+
- **Extensible**: Override any view or behavior in your host app
|
|
12
24
|
|
|
13
25
|
## Installation
|
|
14
26
|
|
|
@@ -25,7 +37,43 @@ bundle install
|
|
|
25
37
|
|
|
26
38
|
## Quick Start
|
|
27
39
|
|
|
28
|
-
### 1. Ensure
|
|
40
|
+
### 1. Ensure you have ActiveRecord model representing your data.
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
bin/rails generate model Task title:string description:text priority:integer completed:boolean due_date:date
|
|
44
|
+
bin/rails db:migrate
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 2. Create a Controller for your ActiveRecord Model
|
|
48
|
+
|
|
49
|
+
This controller handles one ActiveRecord model and presents a CRUD interface to the user. It derives from the ElaineCrud::BaseController, which provides good defaults for how the CRUD view should operate. The controller requires a working layout (see step 4).
|
|
50
|
+
|
|
51
|
+
The main configuration is setting the ActiveRecord model using the `model Task` keyword, where Task is an ActiveRecord model. You also need to explicitly specify which model fields are permitted using the `permit_params` command.
|
|
52
|
+
|
|
53
|
+
The following example controller provides a fully working CRUD view for the ActiveRecord with pagination, sorting, filtering and exporting. You can customise the behaviour, which is explained in more details later.
|
|
54
|
+
|
|
55
|
+
```ruby
|
|
56
|
+
class TaskController < ElaineCrud::BaseController
|
|
57
|
+
layout 'application' # Use your app's layout (wraps ElaineCrud's content)
|
|
58
|
+
|
|
59
|
+
model Task
|
|
60
|
+
permit_params :title, :description, :priority, :completed, :due_date
|
|
61
|
+
end
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 3. Add Routes
|
|
65
|
+
|
|
66
|
+
You need to add the created Controller to the Rails routes.rb. In this example you simply declare `resources :tasks` where `:tasks` maps to the TaskController.
|
|
67
|
+
|
|
68
|
+
```ruby
|
|
69
|
+
# config/routes.rb
|
|
70
|
+
Rails.application.routes.draw do
|
|
71
|
+
resources :tasks
|
|
72
|
+
root "tasks#index"
|
|
73
|
+
end
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 4. Ensure Your Application Has a Layout
|
|
29
77
|
|
|
30
78
|
ElaineCrud is a **content-only engine** - it provides CRUD views but relies on your application to provide the HTML structure (layout, navigation, styling).
|
|
31
79
|
|
|
@@ -35,256 +83,272 @@ Your Rails app should have a layout file (typically `app/views/layouts/applicati
|
|
|
35
83
|
- JavaScript imports (including Turbo)
|
|
36
84
|
- Navigation/header/footer (optional, your choice)
|
|
37
85
|
|
|
38
|
-
|
|
86
|
+
Here's an example layout file, which contains the critical stylesheet_link_tag for elaine_crud:
|
|
39
87
|
|
|
40
88
|
```erb
|
|
41
|
-
<!-- app/views/layouts/application.html.erb -->
|
|
42
89
|
<!DOCTYPE html>
|
|
43
90
|
<html>
|
|
44
91
|
<head>
|
|
45
|
-
<title
|
|
92
|
+
<title><%= content_for(:title) || "Taskmanager" %></title>
|
|
93
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
46
94
|
<%= csrf_meta_tags %>
|
|
47
95
|
<%= csp_meta_tag %>
|
|
48
|
-
|
|
96
|
+
|
|
97
|
+
<%= stylesheet_link_tag "elaine_crud", "data-turbo-track": "reload" %>
|
|
98
|
+
<%= stylesheet_link_tag :app, "data-turbo-track": "reload" %>
|
|
49
99
|
<%= javascript_importmap_tags %>
|
|
50
100
|
</head>
|
|
51
|
-
|
|
52
|
-
|
|
101
|
+
|
|
102
|
+
<body class="bg-gray-100">
|
|
103
|
+
<main class="w-full px-4 py-6">
|
|
104
|
+
<%= yield %>
|
|
105
|
+
</main>
|
|
53
106
|
</body>
|
|
54
107
|
</html>
|
|
55
108
|
```
|
|
56
109
|
|
|
57
|
-
###
|
|
110
|
+
### 5. Start Your Server
|
|
58
111
|
|
|
59
|
-
|
|
112
|
+
```bash
|
|
113
|
+
bin/dev
|
|
114
|
+
```
|
|
60
115
|
|
|
61
|
-
|
|
62
|
-
class PeopleController < ElaineCrud::BaseController
|
|
63
|
-
layout 'application' # Use your app's layout (wraps ElaineCrud's content)
|
|
116
|
+
## Usage
|
|
64
117
|
|
|
65
|
-
|
|
66
|
-
permit_params :name, :email, :phone, :active
|
|
67
|
-
end
|
|
68
|
-
```
|
|
118
|
+
### Extending the default Controller
|
|
69
119
|
|
|
70
|
-
|
|
120
|
+
As described earlier, this example controller uses a lot of default from the `ElaineCrud::BaseController`.
|
|
71
121
|
|
|
72
|
-
|
|
122
|
+
One of the first things user usually wants to customise is how a certain ActiveRecord property is rendered to the user.
|
|
73
123
|
|
|
74
124
|
```ruby
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
```
|
|
125
|
+
class TaskController < ElaineCrud::BaseController
|
|
126
|
+
layout 'application' # Use your app's layout (wraps ElaineCrud's content)
|
|
78
127
|
|
|
79
|
-
|
|
128
|
+
model Task
|
|
129
|
+
permit_params :title, :description, :priority, :completed, :due_date
|
|
80
130
|
|
|
81
|
-
|
|
131
|
+
# Configures the ActiveRecord field :title
|
|
132
|
+
field :title do
|
|
82
133
|
|
|
83
|
-
|
|
134
|
+
# Human readable name for the field, shown in the column header.
|
|
135
|
+
title "Task title"
|
|
84
136
|
|
|
85
|
-
|
|
137
|
+
# Description is shown in the edit form
|
|
138
|
+
description "Write a short title for your task, so that it's easily understandable"
|
|
86
139
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
<!DOCTYPE html>
|
|
90
|
-
<html>
|
|
91
|
-
<head>
|
|
92
|
-
<title>Your App</title>
|
|
93
|
-
<%= stylesheet_link_tag "elaine_crud", "data-turbo-track": "reload" %>
|
|
94
|
-
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
|
|
95
|
-
</head>
|
|
96
|
-
<body>
|
|
97
|
-
<%= yield %>
|
|
98
|
-
</body>
|
|
99
|
-
</html>
|
|
100
|
-
```
|
|
140
|
+
# Custom rendering. `value` is the raw value of the field and `record` is the entire ActiveRecord
|
|
141
|
+
display_as { |value, record| "<b>#{value}</b>" if value.present? }
|
|
101
142
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
#### Option B: Scan ElaineCrud Sources (For Customization)
|
|
106
|
-
|
|
107
|
-
If you want to customize the Tailwind theme, add ElaineCrud's views to your `tailwind.config.js`:
|
|
108
|
-
|
|
109
|
-
```javascript
|
|
110
|
-
const path = require('path')
|
|
111
|
-
const execSync = require('child_process').execSync
|
|
112
|
-
|
|
113
|
-
// Get the gem path from bundler
|
|
114
|
-
const gemPath = execSync('bundle show elaine_crud', { encoding: 'utf-8' }).trim()
|
|
115
|
-
|
|
116
|
-
module.exports = {
|
|
117
|
-
content: [
|
|
118
|
-
'./app/views/**/*.html.erb',
|
|
119
|
-
'./app/helpers/**/*.rb',
|
|
120
|
-
'./app/assets/stylesheets/**/*.css',
|
|
121
|
-
'./app/javascript/**/*.js',
|
|
122
|
-
// Add ElaineCrud gem views and helpers
|
|
123
|
-
path.join(gemPath, 'app/views/**/*.html.erb'),
|
|
124
|
-
path.join(gemPath, 'app/helpers/**/*.rb')
|
|
125
|
-
],
|
|
126
|
-
theme: {
|
|
127
|
-
extend: {
|
|
128
|
-
// Your custom theme here
|
|
129
|
-
},
|
|
130
|
-
},
|
|
131
|
-
}
|
|
132
|
-
```
|
|
143
|
+
# By default text columns are searchable but not filterable. You can set a field to be filterable
|
|
144
|
+
# so that it shows in Advanced Filters section, but then it's no longer searchable
|
|
145
|
+
filterable true
|
|
133
146
|
|
|
134
|
-
|
|
135
|
-
|
|
147
|
+
# By default text columns are searchable and other columns are not
|
|
148
|
+
searchable false
|
|
149
|
+
end
|
|
136
150
|
|
|
137
|
-
|
|
151
|
+
field :priority do
|
|
152
|
+
# Gives a html dropdown for available options
|
|
153
|
+
options [1,2,3,4,5]
|
|
154
|
+
end
|
|
138
155
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
156
|
+
# `read_only` can be used prevent field from being edited
|
|
157
|
+
field :modified_at do
|
|
158
|
+
read_only true
|
|
159
|
+
end
|
|
142
160
|
|
|
143
|
-
|
|
161
|
+
# We can also hide a field completely
|
|
162
|
+
field :created_at do
|
|
163
|
+
hidden true
|
|
164
|
+
end
|
|
144
165
|
|
|
145
|
-
|
|
166
|
+
end
|
|
167
|
+
```
|
|
146
168
|
|
|
147
|
-
###
|
|
169
|
+
### Virtual fields
|
|
148
170
|
|
|
149
|
-
|
|
171
|
+
It is possible to create a virtual column which is not backed by any actual field in the ActiveRecord, but instead its contents is calculated based on other fields. For example if your Order has `amount` and `price_per_unit` fields, you could have a `total_cost` virtual field:
|
|
150
172
|
|
|
151
173
|
```ruby
|
|
152
|
-
class
|
|
153
|
-
layout 'application' #
|
|
154
|
-
|
|
155
|
-
model
|
|
156
|
-
permit_params :
|
|
174
|
+
class OrderController < ElaineCrud::BaseController
|
|
175
|
+
layout 'application' # Use your app's layout (wraps ElaineCrud's content)
|
|
176
|
+
|
|
177
|
+
model Order
|
|
178
|
+
permit_params :product, :amount, :price_per_unit
|
|
179
|
+
|
|
180
|
+
# The field `total_cost` simply does not exists in the ActiveRecord model
|
|
181
|
+
field :total_cost do
|
|
182
|
+
readonly true
|
|
183
|
+
display_as { |value,record|
|
|
184
|
+
# The `value` parameter will be nil as it does not exists.
|
|
185
|
+
record.amount * record.price_per_unit
|
|
186
|
+
}
|
|
187
|
+
end
|
|
157
188
|
end
|
|
158
189
|
```
|
|
159
190
|
|
|
160
|
-
###
|
|
191
|
+
### Relations
|
|
192
|
+
|
|
193
|
+
ElaineCrud supports ActiveRecord relations automatically, if they are configured in the underlying ActiveRecords. Lets assume these models:
|
|
194
|
+
```
|
|
195
|
+
bin/rails generate model Department name:string
|
|
196
|
+
bin/rails generate model Employee name:string email:string department:references
|
|
197
|
+
bin/rails db:migrate
|
|
161
198
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
199
|
+
# app/models/department.rb
|
|
200
|
+
class Department < ApplicationRecord
|
|
201
|
+
has_many :employees
|
|
202
|
+
end
|
|
165
203
|
|
|
166
|
-
|
|
204
|
+
# app/models/employee.rb
|
|
205
|
+
class Employee < ApplicationRecord
|
|
206
|
+
belongs_to :department
|
|
207
|
+
end
|
|
208
|
+
```
|
|
167
209
|
|
|
168
|
-
|
|
210
|
+
We can then have a simple EmployeesController and DepartmentsController
|
|
211
|
+
```ruby
|
|
212
|
+
# app/controllers/employees_controller.rb
|
|
213
|
+
class EmployeesController < ElaineCrud::BaseController
|
|
214
|
+
layout 'application'
|
|
169
215
|
|
|
170
|
-
|
|
216
|
+
model Employee
|
|
217
|
+
permit_params :name, :email, :department_id
|
|
218
|
+
end
|
|
171
219
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
220
|
+
# app/controllers/departments_controller.rb
|
|
221
|
+
class DepartmentsController < ElaineCrud::BaseController
|
|
222
|
+
layout 'application'
|
|
175
223
|
|
|
176
|
-
|
|
224
|
+
model Department
|
|
225
|
+
permit_params :name
|
|
177
226
|
|
|
178
|
-
```ruby
|
|
179
|
-
class ArticlesController < ElaineCrud::BaseController
|
|
180
|
-
model Article
|
|
181
|
-
permit_params :title, :content, :published
|
|
182
|
-
|
|
183
|
-
private
|
|
184
|
-
|
|
185
|
-
# Custom record fetching with scoping
|
|
186
|
-
def fetch_records
|
|
187
|
-
Article.published.order(:title)
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
# Custom column selection
|
|
191
|
-
def determine_columns
|
|
192
|
-
%w[title published created_at]
|
|
193
|
-
end
|
|
194
227
|
end
|
|
195
228
|
```
|
|
196
229
|
|
|
197
|
-
|
|
230
|
+
This will automatically create a relation to the Departments in the EmployeesController field like this:
|
|
231
|
+

|
|
198
232
|
|
|
199
|
-
|
|
233
|
+
Also the Departments controller will have a back reference to show how many Employees are boudn to the Department.
|
|
234
|
+

|
|
200
235
|
|
|
236
|
+
|
|
237
|
+
### Misc options
|
|
201
238
|
```ruby
|
|
202
|
-
# app/
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
239
|
+
# app/controllers/employees_controller.rb
|
|
240
|
+
class EmployeesController < ElaineCrud::BaseController
|
|
241
|
+
layout 'application'
|
|
242
|
+
|
|
243
|
+
model Employee
|
|
244
|
+
permit_params :name, :email, :department_id
|
|
245
|
+
|
|
246
|
+
# Sets default sorting when the controller is opened
|
|
247
|
+
default_sort column: :email, direction: :asc
|
|
248
|
+
|
|
249
|
+
# Instead of editing a row in the inline editor using turbo, the Edit button
|
|
250
|
+
# opens /controller/#{id}/edit page
|
|
251
|
+
disable_turbo
|
|
252
|
+
|
|
253
|
+
# This adds a View button next to Edit and Delete buttons, which links to
|
|
254
|
+
# /controller/#{id}
|
|
255
|
+
show_view_button
|
|
256
|
+
|
|
257
|
+
# Limit how many rows the export functionality will be exporting. The default is 10000
|
|
258
|
+
max_export(5000)
|
|
210
259
|
end
|
|
211
260
|
```
|
|
212
261
|
|
|
213
262
|
## Requirements
|
|
214
263
|
|
|
215
|
-
- Rails
|
|
216
|
-
- TailwindCSS (
|
|
264
|
+
- Rails 7.0+
|
|
265
|
+
- TailwindCSS (included via precompiled CSS)
|
|
217
266
|
|
|
218
267
|
## Examples
|
|
219
268
|
|
|
220
|
-
###
|
|
269
|
+
### More detailed example with customisations
|
|
270
|
+
|
|
271
|
+
A more comprehensive example showing custom field formatting, sorting, and relationships. This example uses the more verbose block syntax with fields. Both approaches work and are valid.
|
|
221
272
|
|
|
222
273
|
```ruby
|
|
223
|
-
# app/controllers/
|
|
224
|
-
class
|
|
225
|
-
layout 'application'
|
|
226
|
-
|
|
227
|
-
model
|
|
228
|
-
permit_params :
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
274
|
+
# app/controllers/products_controller.rb
|
|
275
|
+
class ProductsController < ElaineCrud::BaseController
|
|
276
|
+
layout 'application'
|
|
277
|
+
|
|
278
|
+
model Product
|
|
279
|
+
permit_params :name, :description, :price, :stock_quantity, :category_id, :active
|
|
280
|
+
|
|
281
|
+
# Sort by name alphabetically by default
|
|
282
|
+
default_sort column: :name, direction: :asc
|
|
283
|
+
|
|
284
|
+
# Show the View button in actions column
|
|
285
|
+
show_view_button
|
|
286
|
+
|
|
287
|
+
# Format price as currency
|
|
288
|
+
field :price do |f|
|
|
289
|
+
f.title "Price"
|
|
290
|
+
f.display_as { |value, record| number_to_currency(value) if value.present? }
|
|
234
291
|
end
|
|
235
|
-
end
|
|
236
292
|
|
|
237
|
-
#
|
|
238
|
-
|
|
293
|
+
# Custom display for stock status
|
|
294
|
+
field :stock_quantity do |f|
|
|
295
|
+
f.title "Stock"
|
|
296
|
+
f.display_as { |value, record|
|
|
297
|
+
if value.to_i > 10
|
|
298
|
+
content_tag(:span, "#{value} in stock", class: "text-green-600")
|
|
299
|
+
elsif value.to_i > 0
|
|
300
|
+
content_tag(:span, "Low: #{value}", class: "text-yellow-600 font-semibold")
|
|
301
|
+
else
|
|
302
|
+
content_tag(:span, "Out of stock", class: "text-red-600 font-semibold")
|
|
303
|
+
end
|
|
304
|
+
}
|
|
305
|
+
end
|
|
239
306
|
|
|
240
|
-
#
|
|
307
|
+
# Boolean with badge display
|
|
308
|
+
field :active do |f|
|
|
309
|
+
f.title "Status"
|
|
310
|
+
f.display_as { |value, record|
|
|
311
|
+
if value
|
|
312
|
+
content_tag(:span, "Active", class: "px-2 py-1 text-xs rounded bg-green-100 text-green-800")
|
|
313
|
+
else
|
|
314
|
+
content_tag(:span, "Inactive", class: "px-2 py-1 text-xs rounded bg-gray-100 text-gray-600")
|
|
315
|
+
end
|
|
316
|
+
}
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
# Foreign key - automatically renders as dropdown in forms
|
|
320
|
+
field :category_id do |f|
|
|
321
|
+
f.foreign_key model: Category, display: :name
|
|
322
|
+
end
|
|
323
|
+
end
|
|
241
324
|
```
|
|
242
325
|
|
|
243
326
|
### Example Output
|
|
244
327
|
|
|
245
328
|
The generated interface includes:
|
|
246
|
-
- **Index Page**: Responsive table with all records
|
|
329
|
+
- **Index Page**: Responsive grid-based table with all records
|
|
330
|
+
- **Inline Editing**: Click Edit to modify records in place (Turbo Frames)
|
|
331
|
+
- **Sortable Columns**: Click headers to sort ascending/descending
|
|
332
|
+
- **Search**: Filter records by text across searchable columns
|
|
333
|
+
- **Pagination**: Navigate through large datasets with configurable page size
|
|
334
|
+
- **Export**: Download as CSV, Excel (.xlsx), or JSON
|
|
247
335
|
- **Smart Formatting**: Dates, booleans, and nil values formatted nicely
|
|
248
336
|
- **Action Buttons**: Edit and Delete functionality
|
|
249
337
|
- **Empty States**: Helpful messages when no records exist
|
|
250
|
-
- **
|
|
338
|
+
- **Visual Feedback**: Row highlights after saving changes
|
|
251
339
|
|
|
252
340
|
## Architecture
|
|
253
341
|
|
|
254
|
-
ElaineCrud follows a **separation of concerns** approach:
|
|
255
|
-
|
|
256
|
-
- **Engine provides**: CRUD logic, data formatting, content templates
|
|
257
|
-
- **Host app provides**: Layout, styling, HTML structure, navigation
|
|
258
|
-
|
|
259
|
-
### Layout Control
|
|
260
|
-
|
|
261
|
-
The gem doesn't impose any layout - your app controls the HTML structure:
|
|
262
|
-
|
|
263
|
-
```ruby
|
|
264
|
-
class UsersController < ElaineCrud::BaseController
|
|
265
|
-
layout 'admin' # Use admin layout
|
|
266
|
-
# or layout 'public' # Use public layout
|
|
267
|
-
# or layout false # No layout (API mode)
|
|
268
|
-
|
|
269
|
-
model User
|
|
270
|
-
permit_params :name, :email
|
|
271
|
-
end
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
This means:
|
|
275
|
-
- ✅ **Your app controls**: Headers, footers, navigation, CSS frameworks
|
|
276
|
-
- ✅ **Engine provides**: Table content, buttons, data formatting
|
|
277
|
-
- ✅ **Zero view files needed**: No templates to create in your app
|
|
278
|
-
|
|
279
342
|
See [ARCHITECTURE.md](docs/ARCHITECTURE.md) for detailed technical documentation.
|
|
280
343
|
|
|
281
344
|
## Contributing
|
|
282
345
|
|
|
283
|
-
1.
|
|
284
|
-
2.
|
|
285
|
-
3.
|
|
286
|
-
4.
|
|
287
|
-
5.
|
|
346
|
+
1. Open a new issue and suggest a feature
|
|
347
|
+
2. Fork the repository
|
|
348
|
+
3. Create a feature branch
|
|
349
|
+
4. Make your changes
|
|
350
|
+
5. Add tests
|
|
351
|
+
6. Submit a pull request
|
|
288
352
|
|
|
289
353
|
## License
|
|
290
354
|
|
|
@@ -133,9 +133,9 @@ module ElaineCrud
|
|
|
133
133
|
@filterable_columns = determine_filterable_columns
|
|
134
134
|
@total_count = total_unfiltered_count if search_active?
|
|
135
135
|
|
|
136
|
-
# If Turbo is disabled,
|
|
136
|
+
# If Turbo is disabled, render standalone edit form (no table context)
|
|
137
137
|
if turbo_disabled?
|
|
138
|
-
render 'elaine_crud/base/
|
|
138
|
+
render 'elaine_crud/base/edit_standalone'
|
|
139
139
|
elsif turbo_frame_request?
|
|
140
140
|
# For Turbo Frame requests, return just the edit row partial
|
|
141
141
|
render partial: 'elaine_crud/base/edit_row', locals: { record: @record, columns: @columns }
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<div class="container mx-auto px-4 py-8">
|
|
2
|
+
<div class="flex justify-between items-center mb-6">
|
|
3
|
+
<h1 class="text-3xl font-bold text-gray-900">Edit <%= @model_name %></h1>
|
|
4
|
+
<%= link_to "Back to #{@model_name.pluralize}",
|
|
5
|
+
url_for(action: :index),
|
|
6
|
+
class: "text-gray-600 hover:text-gray-900" %>
|
|
7
|
+
</div>
|
|
8
|
+
|
|
9
|
+
<div class="bg-white shadow-md rounded-lg p-6">
|
|
10
|
+
<%= render 'form', record: @record, submit_text: "Update #{@model_name}" %>
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/lib/elaine_crud/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: elaine_crud
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Garo
|
|
@@ -209,6 +209,7 @@ files:
|
|
|
209
209
|
- app/views/elaine_crud/base/_show_details.html.erb
|
|
210
210
|
- app/views/elaine_crud/base/_view_row.html.erb
|
|
211
211
|
- app/views/elaine_crud/base/edit.html.erb
|
|
212
|
+
- app/views/elaine_crud/base/edit_standalone.html.erb
|
|
212
213
|
- app/views/elaine_crud/base/index.html.erb
|
|
213
214
|
- app/views/elaine_crud/base/new.html.erb
|
|
214
215
|
- app/views/elaine_crud/base/new_modal.html.erb
|
|
@@ -223,6 +224,9 @@ files:
|
|
|
223
224
|
- docs/HAS_MANY_IMPLEMENTATION.md
|
|
224
225
|
- docs/LAYOUT_EXAMPLES.md
|
|
225
226
|
- docs/TROUBLESHOOTING.md
|
|
227
|
+
- docs/screenshots/departments.png
|
|
228
|
+
- docs/screenshots/employees.png
|
|
229
|
+
- docs/screenshots/screenshot1.png
|
|
226
230
|
- elaine_crud.gemspec
|
|
227
231
|
- lib/elaine_crud.rb
|
|
228
232
|
- lib/elaine_crud/dsl_methods.rb
|