tramway 2.1.3.2 → 2.2
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 +67 -1
- data/app/components/tailwinds/table/row_component.html.haml +2 -2
- data/app/components/tailwinds/table/row_component.rb +4 -2
- data/app/components/tramway/actions_buttons_container_component.html.haml +2 -0
- data/app/components/tramway/actions_buttons_container_component.rb +6 -0
- data/app/components/tramway/entity_component.html.haml +19 -1
- data/app/controllers/tramway/entities_controller.rb +24 -1
- data/app/views/tramway/entities/_form.html.haml +4 -1
- data/app/views/tramway/entities/_list.html.haml +2 -2
- data/app/views/tramway/entities/edit.html.haml +5 -0
- data/app/views/tramway/entities/show.html.haml +13 -2
- data/config/locales/en.yml +10 -0
- data/config/routes.rb +4 -25
- data/docs/AGENTS.md +1 -1
- data/lib/tramway/base_decorator.rb +10 -6
- data/lib/tramway/base_form.rb +1 -0
- data/lib/tramway/configs/entity.rb +24 -13
- data/lib/tramway/version.rb +1 -1
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 31f2e19d40c2dcccde24e3060fd4a735d10a8fd41634f7b633c09dfefe37b06a
|
|
4
|
+
data.tar.gz: 403c3df3f7b9dcdc4e458dabd26d00c438817bbfd89821fa4807aa2622b36490
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b1728c3e1eacff00ae976d376f6e7fa6d595cee42d7c5a7d2722bd9cd559f3d574a24ac83d53a825ab0008a357ce95bd8e8ceda1a461f7668f5d4ecfa0d10d95
|
|
7
|
+
data.tar.gz: 6ae4c7bda4c7c984683ebf8c44190bc1ec8177db68243f7d3401c4e0aa279451f860e01b69398b547b314587d0f994fbf110528fe9f4d9149431f5bf2f28cf66
|
data/README.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# Tramway
|
|
2
2
|
Unite Ruby on Rails brilliance. Streamline development with Tramway.
|
|
3
3
|
|
|
4
|
+
Tramway ships with full CRUD (index, show, create, update, destroy) out of the box, and it includes a great AGENTS.md guide
|
|
5
|
+
that helps you generate good, Tramway-native code with all the framework features.
|
|
6
|
+
|
|
4
7
|
[](https://rubygems.org/gems/tramway)
|
|
5
8
|
[](https://github.com/Purple-Magic/tramway/actions/workflows/test.yml)
|
|
6
9
|
[](https://github.com/Purple-Magic/tramway/actions/workflows/lint.yml)
|
|
@@ -60,7 +63,13 @@ Tramway.configure do |config|
|
|
|
60
63
|
config.entities = [
|
|
61
64
|
{
|
|
62
65
|
name: :user,
|
|
63
|
-
pages: [
|
|
66
|
+
pages: [
|
|
67
|
+
{ action: :index },
|
|
68
|
+
{ action: :show },
|
|
69
|
+
{ action: :create },
|
|
70
|
+
{ action: :update },
|
|
71
|
+
{ action: :destroy }
|
|
72
|
+
],
|
|
64
73
|
}
|
|
65
74
|
]
|
|
66
75
|
end
|
|
@@ -215,6 +224,63 @@ end
|
|
|
215
224
|
With this configuration in place, visiting the show page displays a two-column table where the left column contains the
|
|
216
225
|
localized attribute names and the right column renders their values.
|
|
217
226
|
|
|
227
|
+
**create page**
|
|
228
|
+
|
|
229
|
+
To render a create page for an entity, declare a `:create` action inside the `pages` array in
|
|
230
|
+
`config/initializers/tramway.rb`. Tramway will generate the route and render the form fields based on your form object.
|
|
231
|
+
|
|
232
|
+
```ruby
|
|
233
|
+
Tramway.configure do |config|
|
|
234
|
+
config.entities = [
|
|
235
|
+
{
|
|
236
|
+
name: :campaign,
|
|
237
|
+
pages: [
|
|
238
|
+
{ action: :index },
|
|
239
|
+
{ action: :create }
|
|
240
|
+
]
|
|
241
|
+
}
|
|
242
|
+
]
|
|
243
|
+
end
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
**update page**
|
|
247
|
+
|
|
248
|
+
To render an update page, declare an `:update` action inside the `pages` array in `config/initializers/tramway.rb`.
|
|
249
|
+
Tramway will generate the edit route and reuse the same form partial as create.
|
|
250
|
+
|
|
251
|
+
```ruby
|
|
252
|
+
Tramway.configure do |config|
|
|
253
|
+
config.entities = [
|
|
254
|
+
{
|
|
255
|
+
name: :campaign,
|
|
256
|
+
pages: [
|
|
257
|
+
{ action: :index },
|
|
258
|
+
{ action: :update }
|
|
259
|
+
]
|
|
260
|
+
}
|
|
261
|
+
]
|
|
262
|
+
end
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
**destroy page**
|
|
266
|
+
|
|
267
|
+
To render a destroy action, declare a `:destroy` action inside the `pages` array in `config/initializers/tramway.rb`.
|
|
268
|
+
Tramway will generate the destroy route and render the delete action button.
|
|
269
|
+
|
|
270
|
+
```ruby
|
|
271
|
+
Tramway.configure do |config|
|
|
272
|
+
config.entities = [
|
|
273
|
+
{
|
|
274
|
+
name: :campaign,
|
|
275
|
+
pages: [
|
|
276
|
+
{ action: :index },
|
|
277
|
+
{ action: :destroy }
|
|
278
|
+
]
|
|
279
|
+
}
|
|
280
|
+
]
|
|
281
|
+
end
|
|
282
|
+
```
|
|
283
|
+
|
|
218
284
|
**route_helper**
|
|
219
285
|
|
|
220
286
|
To get routes Tramway generated just Tramway::Engine.
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
- cells = Nokogiri::HTML.fragment(content).xpath('./*[@class and contains(concat(" ", normalize-space(@class), " "), " div-table-cell ")]')
|
|
9
9
|
|
|
10
10
|
- if href.present?
|
|
11
|
-
= tag.a href:, class: [desktop_row_classes(cells.count), link_row_classes].join(' '), **
|
|
11
|
+
= tag.a href:, class: [desktop_row_classes(cells.count), link_row_classes].join(' '), **default_attributes do
|
|
12
12
|
= content
|
|
13
13
|
- else
|
|
14
|
-
= tag.div class: desktop_row_classes(cells.count), **
|
|
14
|
+
= tag.div class: desktop_row_classes(cells.count), **default_attributes do
|
|
15
15
|
= content
|
|
@@ -8,9 +8,11 @@ module Tailwinds
|
|
|
8
8
|
option :href, optional: true
|
|
9
9
|
option :options, optional: true, default: -> { {} }
|
|
10
10
|
|
|
11
|
-
def
|
|
12
|
-
|
|
11
|
+
def default_attributes
|
|
12
|
+
{ role: :row }
|
|
13
|
+
end
|
|
13
14
|
|
|
15
|
+
def row_tag(**options, &)
|
|
14
16
|
if href.present?
|
|
15
17
|
link_to(href, options.merge(class: "#{options[:class] || ''} #{link_row_classes}", **default_attributes)) do
|
|
16
18
|
yield if block_given?
|
|
@@ -1 +1,19 @@
|
|
|
1
|
-
= tramway_row
|
|
1
|
+
= tramway_row href: do
|
|
2
|
+
- cells.each do |(attribute, value)|
|
|
3
|
+
= tramway_cell do
|
|
4
|
+
= value
|
|
5
|
+
- if @entity.page(:update).present? || @entity.page(:destroy).present?
|
|
6
|
+
= tramway_cell do
|
|
7
|
+
= component 'tramway/actions_buttons_container' do
|
|
8
|
+
- if @entity.page(:update).present?
|
|
9
|
+
= tramway_button text: t('tramway.actions.edit'),
|
|
10
|
+
path: Tramway::Engine.routes.url_helpers.public_send(entity.routes.edit, item.id),
|
|
11
|
+
type: :will,
|
|
12
|
+
size: :small
|
|
13
|
+
|
|
14
|
+
- if @entity.page(:destroy).present?
|
|
15
|
+
= tramway_button text: t('tramway.actions.destroy'),
|
|
16
|
+
path: Tramway::Engine.routes.url_helpers.public_send(entity.routes.destroy, item.id),
|
|
17
|
+
type: :rage,
|
|
18
|
+
method: :delete,
|
|
19
|
+
size: :small
|
|
@@ -35,6 +35,10 @@ module Tramway
|
|
|
35
35
|
@record = tramway_form model_class.new, namespace: entity.namespace
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
+
def edit
|
|
39
|
+
@record = tramway_form model_class.find(params[:id]), namespace: entity.namespace
|
|
40
|
+
end
|
|
41
|
+
|
|
38
42
|
# rubocop:disable Metrics/AbcSize
|
|
39
43
|
def create
|
|
40
44
|
@record = tramway_form model_class.new, namespace: entity.namespace
|
|
@@ -45,8 +49,26 @@ module Tramway
|
|
|
45
49
|
render :new
|
|
46
50
|
end
|
|
47
51
|
end
|
|
52
|
+
|
|
53
|
+
def update
|
|
54
|
+
@record = tramway_form model_class.find(params[:id]), namespace: entity.namespace
|
|
55
|
+
|
|
56
|
+
if @record.submit params[model_class.model_name.param_key]
|
|
57
|
+
redirect_to public_send(entity.show_helper_method, @record.id), notice: t('tramway.notices.updated')
|
|
58
|
+
else
|
|
59
|
+
render :edit
|
|
60
|
+
end
|
|
61
|
+
end
|
|
48
62
|
# rubocop:enable Metrics/AbcSize
|
|
49
63
|
|
|
64
|
+
def destroy
|
|
65
|
+
@record = model_class.find(params[:id])
|
|
66
|
+
|
|
67
|
+
@record.destroy
|
|
68
|
+
|
|
69
|
+
redirect_to public_send(entity.index_helper_method), notice: t('tramway.notices.deleted')
|
|
70
|
+
end
|
|
71
|
+
|
|
50
72
|
private
|
|
51
73
|
|
|
52
74
|
def model_class
|
|
@@ -70,7 +92,8 @@ module Tramway
|
|
|
70
92
|
{
|
|
71
93
|
name: association,
|
|
72
94
|
decorator: records.first.class,
|
|
73
|
-
records
|
|
95
|
+
records:,
|
|
96
|
+
model_class: records.first.object.class
|
|
74
97
|
}
|
|
75
98
|
end.compact
|
|
76
99
|
end
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
=
|
|
1
|
+
- url = @record.new_record? ? public_send(@entity.create_helper_method) : public_send(@entity.update_helper_method, @record.id)
|
|
2
|
+
- method = @record.new_record? ? :post : :patch
|
|
3
|
+
|
|
4
|
+
= tramway_form_for @record, local: true, url:, method: do |f|
|
|
2
5
|
- if @record.errors.any?
|
|
3
6
|
.alert.alert-danger
|
|
4
7
|
%h4= "#{pluralize(@record.errors.count, 'error')} prohibited this record from being saved:"
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
- if Tramway.config.pagination[:enabled]
|
|
14
14
|
= paginate @entities, custom_path_method:
|
|
15
|
-
|
|
15
|
+
= component 'tramway/actions_buttons_container' do
|
|
16
16
|
- if @entity.page(:create).present?
|
|
17
17
|
= tramway_button text: t('tramway.actions.new'),
|
|
18
18
|
path: Tramway::Engine.routes.url_helpers.public_send(@entity.routes.new),
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
= decorator
|
|
27
27
|
- else
|
|
28
28
|
= tramway_table class: 'mt-4' do
|
|
29
|
-
= tramway_header headers:
|
|
29
|
+
= tramway_header headers: decorator.constantize.table_headers(entity: @entity)
|
|
30
30
|
- @entities.each do |item|
|
|
31
31
|
= component 'tramway/entity', entity: @entity, item: item
|
|
32
32
|
|
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
%h1.text-4xl.font-bold.mb-4
|
|
4
4
|
= @record.title
|
|
5
5
|
|
|
6
|
+
= component 'tramway/actions_buttons_container' do
|
|
7
|
+
- if @entity.page(:update).present?
|
|
8
|
+
= tramway_button text: t('tramway.actions.edit'),
|
|
9
|
+
path: Tramway::Engine.routes.url_helpers.public_send(@entity.routes.edit, @record.id),
|
|
10
|
+
type: :will
|
|
11
|
+
|
|
12
|
+
- if @entity.page(:destroy).present?
|
|
13
|
+
= tramway_button text: t('tramway.actions.destroy'),
|
|
14
|
+
path: Tramway::Engine.routes.url_helpers.public_send(@entity.routes.destroy, @record.id),
|
|
15
|
+
type: :rage,
|
|
16
|
+
method: :delete
|
|
17
|
+
|
|
6
18
|
.flex.justify-end.mt-2
|
|
7
19
|
- if @record.show_header_content.present?
|
|
8
20
|
= @record.show_header_content
|
|
@@ -31,8 +43,7 @@
|
|
|
31
43
|
custom_path_arguments: [@record.id]
|
|
32
44
|
|
|
33
45
|
= tramway_table class: 'mt-4' do
|
|
34
|
-
|
|
35
|
-
= tramway_header headers: association[:records].first.table_headers
|
|
46
|
+
= tramway_header headers: association[:decorator].table_headers(model_class: association[:model_class])
|
|
36
47
|
|
|
37
48
|
- association[:records].each do |record|
|
|
38
49
|
= tramway_row do
|
data/config/locales/en.yml
CHANGED
|
@@ -3,5 +3,15 @@ en:
|
|
|
3
3
|
pages:
|
|
4
4
|
new:
|
|
5
5
|
title: "Create %{model_name}"
|
|
6
|
+
edit:
|
|
7
|
+
title: "Edit %{model_name}"
|
|
8
|
+
actions:
|
|
9
|
+
new: "New"
|
|
10
|
+
edit: "Edit"
|
|
11
|
+
destroy: "Destroy"
|
|
12
|
+
save: "Save"
|
|
13
|
+
cancel: "Cancel"
|
|
6
14
|
notices:
|
|
7
15
|
created: "The record is created"
|
|
16
|
+
updated: "The record is updated"
|
|
17
|
+
deleted: "The record is deleted"
|
data/config/routes.rb
CHANGED
|
@@ -22,6 +22,10 @@ Tramway::Engine.routes.draw do
|
|
|
22
22
|
acc << :show
|
|
23
23
|
when 'create'
|
|
24
24
|
acc + %i[create new]
|
|
25
|
+
when 'update'
|
|
26
|
+
acc + %i[edit update]
|
|
27
|
+
when 'destroy'
|
|
28
|
+
acc << :destroy
|
|
25
29
|
else
|
|
26
30
|
acc
|
|
27
31
|
end
|
|
@@ -31,31 +35,6 @@ Tramway::Engine.routes.draw do
|
|
|
31
35
|
only: actions.map(&:to_sym),
|
|
32
36
|
controller: '/tramway/entities',
|
|
33
37
|
defaults: { entity: }
|
|
34
|
-
|
|
35
|
-
# entity.pages.each do |page|
|
|
36
|
-
# case page.action
|
|
37
|
-
# when 'index'
|
|
38
|
-
# get resource_name.pluralize,
|
|
39
|
-
# to: '/tramway/entities#index',
|
|
40
|
-
# defaults: { entity: },
|
|
41
|
-
# as: resource_name.pluralize
|
|
42
|
-
|
|
43
|
-
# when 'show'
|
|
44
|
-
# get "#{resource_name.pluralize}/:id",
|
|
45
|
-
# to: '/tramway/entities#show',
|
|
46
|
-
# defaults: { entity: },
|
|
47
|
-
# as: resource_name.singularize
|
|
48
|
-
|
|
49
|
-
# when 'create'
|
|
50
|
-
# post resource_name.pluralize,
|
|
51
|
-
# to: '/tramway/entities#create',
|
|
52
|
-
# defaults: { entity: }
|
|
53
|
-
|
|
54
|
-
# get "#{resource_name.pluralize}/new",
|
|
55
|
-
# to: '/tramway/entities#new',
|
|
56
|
-
# defaults: { entity: }
|
|
57
|
-
# end
|
|
58
|
-
# end
|
|
59
38
|
end
|
|
60
39
|
|
|
61
40
|
if segments.empty?
|
data/docs/AGENTS.md
CHANGED
|
@@ -78,7 +78,7 @@ config/
|
|
|
78
78
|
|
|
79
79
|
## Rules
|
|
80
80
|
|
|
81
|
-
- Use Tramway Entities and Tramway actions (index, show, create) by default unless custom behavior is needed. Configure in `config/initializers/tramway.rb`.
|
|
81
|
+
- Use Tramway Entities and Tramway actions (index, show, create, update, destroy) by default unless custom behavior is needed. Configure in `config/initializers/tramway.rb`.
|
|
82
82
|
- Normalize input with `normalizes` (from Tramway) for attributes like email, phone, etc.
|
|
83
83
|
- Use Tramway Navbar for navigation
|
|
84
84
|
- Use Tramway Flash for user notifications.
|
|
@@ -63,6 +63,16 @@ module Tramway
|
|
|
63
63
|
nil
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
+
def table_headers(entity: nil, model_class: nil)
|
|
67
|
+
headers = index_attributes.map do |attribute|
|
|
68
|
+
(model_class || entity.model_class).human_attribute_name(attribute)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
headers += ['Actions'] if entity&.page(:update).present? || entity&.page(:destroy).present?
|
|
72
|
+
|
|
73
|
+
headers
|
|
74
|
+
end
|
|
75
|
+
|
|
66
76
|
include Tramway::Decorators::AssociationClassMethods
|
|
67
77
|
end
|
|
68
78
|
|
|
@@ -102,11 +112,5 @@ module Tramway
|
|
|
102
112
|
def respond_to_missing?(method_name, include_private = false)
|
|
103
113
|
method_name.to_s.end_with?('_path', '_url') || super
|
|
104
114
|
end
|
|
105
|
-
|
|
106
|
-
def table_headers
|
|
107
|
-
self.class.index_attributes.map do |attribute|
|
|
108
|
-
object.class.human_attribute_name(attribute)
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
115
|
end
|
|
112
116
|
end
|
data/lib/tramway/base_form.rb
CHANGED
|
@@ -13,7 +13,7 @@ module Tramway
|
|
|
13
13
|
attribute? :namespace, Types::Coercible::String
|
|
14
14
|
|
|
15
15
|
# Route Struct contains implemented in Tramway CRUD and helpful routes for the entity
|
|
16
|
-
ACTIONS = %i[index show new create].freeze
|
|
16
|
+
ACTIONS = %i[index show new create edit update destroy].freeze
|
|
17
17
|
RouteStruct = Struct.new(*ACTIONS)
|
|
18
18
|
|
|
19
19
|
# HumanName Struct contains human names forms for the entity
|
|
@@ -55,12 +55,16 @@ module Tramway
|
|
|
55
55
|
build_helper_method(name, route:, namespace:, plural: true)
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
def edit_helper_method
|
|
59
|
+
build_helper_method(name, route:, namespace:, plural: false, action: :edit)
|
|
60
|
+
end
|
|
59
61
|
|
|
60
|
-
def
|
|
61
|
-
|
|
62
|
+
def update_helper_method
|
|
63
|
+
build_helper_method(name, route:, namespace:, plural: false)
|
|
64
|
+
end
|
|
62
65
|
|
|
63
|
-
|
|
66
|
+
def destroy_helper_method
|
|
67
|
+
build_helper_method(name, route:, namespace:, plural: false)
|
|
64
68
|
end
|
|
65
69
|
|
|
66
70
|
def model_class
|
|
@@ -69,16 +73,23 @@ module Tramway
|
|
|
69
73
|
nil
|
|
70
74
|
end
|
|
71
75
|
|
|
76
|
+
private
|
|
77
|
+
|
|
78
|
+
def pluralized(model_name)
|
|
79
|
+
local_plural = I18n.t("#{name}.many", scope: 'activerecord.plural.models', default: nil)
|
|
80
|
+
|
|
81
|
+
local_plural.presence || model_name.pluralize
|
|
82
|
+
end
|
|
83
|
+
|
|
72
84
|
def route_helper_methods
|
|
73
85
|
ACTIONS.map do |action|
|
|
74
|
-
case action
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
send("#{action}_helper_method") if existing_condition
|
|
86
|
+
cond = case action
|
|
87
|
+
when :index, :show, :destroy then page(action).present?
|
|
88
|
+
when :new, :create then page(:create).present?
|
|
89
|
+
when :edit, :update then page(:update).present?
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
send("#{action}_helper_method") if cond
|
|
82
93
|
end
|
|
83
94
|
end
|
|
84
95
|
|
data/lib/tramway/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tramway
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: '2.2'
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- kalashnikovisme
|
|
@@ -213,6 +213,8 @@ files:
|
|
|
213
213
|
- app/components/tailwinds/table_component.rb
|
|
214
214
|
- app/components/tailwinds/title_component.html.haml
|
|
215
215
|
- app/components/tailwinds/title_component.rb
|
|
216
|
+
- app/components/tramway/actions_buttons_container_component.html.haml
|
|
217
|
+
- app/components/tramway/actions_buttons_container_component.rb
|
|
216
218
|
- app/components/tramway/base_component.rb
|
|
217
219
|
- app/components/tramway/entity_component.html.haml
|
|
218
220
|
- app/components/tramway/entity_component.rb
|
|
@@ -227,6 +229,7 @@ files:
|
|
|
227
229
|
- app/views/kaminari/_prev_page.html.haml
|
|
228
230
|
- app/views/tramway/entities/_form.html.haml
|
|
229
231
|
- app/views/tramway/entities/_list.html.haml
|
|
232
|
+
- app/views/tramway/entities/edit.html.haml
|
|
230
233
|
- app/views/tramway/entities/index.html.haml
|
|
231
234
|
- app/views/tramway/entities/new.html.haml
|
|
232
235
|
- app/views/tramway/entities/show.html.haml
|