tramway 0.6 → 0.6.0.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 +201 -74
- data/app/views/tramway/entities/_list.html.haml +8 -8
- data/app/views/tramway/entities/index.html.haml +2 -1
- data/lib/tramway/helpers/views_helper.rb +8 -0
- data/lib/tramway/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c3ac70ce33de0d7c3fbfd61650ff031137d8961713e9db94b93f0758ef2eba32
|
|
4
|
+
data.tar.gz: c8853c8169ac8821acafb3d47de20112400bd0e2d3e4c6390c3aec61917978a1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 485ff69148ae02c0967fa8d5bb75674b10a515a88c195ab86c7d6346b3710594bc3fb710e7d861d40f29287998c6f9a95ff2ddc63f4c0a14a8c69381179d12d6
|
|
7
|
+
data.tar.gz: ea7258f63f8adab1936e0f71e6a554857a8b650e3fb9182fe481a885a1823dee3ef5008280a849af141cffcfc10ed9324e9c01fd27106097df1af5938d6e57a4
|
data/README.md
CHANGED
|
@@ -133,13 +133,56 @@ Tramway Entity supports several options that are used in different features.
|
|
|
133
133
|
```ruby
|
|
134
134
|
Tramway.configure do |config|
|
|
135
135
|
config.entities = [
|
|
136
|
-
{
|
|
137
|
-
|
|
138
|
-
|
|
136
|
+
{
|
|
137
|
+
name: :user,
|
|
138
|
+
route: { namespace: :admin }
|
|
139
|
+
}, # `/admin/users` link in the Tramway Navbar
|
|
140
|
+
{
|
|
141
|
+
name: :episodes,
|
|
142
|
+
route: {
|
|
143
|
+
namespace: :podcasts,
|
|
144
|
+
route_method: :episodes
|
|
145
|
+
}
|
|
146
|
+
}, # `/podcasts/episodes` link in the Tramway Navbar
|
|
139
147
|
]
|
|
140
148
|
end
|
|
141
149
|
```
|
|
142
150
|
|
|
151
|
+
**scope**
|
|
152
|
+
|
|
153
|
+
By default, Tramway lists all records for an entity on the index page. You can narrow the records displayed by providing a
|
|
154
|
+
`scope`. When set, Tramway will call the named scope on the entity before rendering the index view.
|
|
155
|
+
|
|
156
|
+
*config/initializers/tramway.rb*
|
|
157
|
+
```ruby
|
|
158
|
+
Tramway.configure do |config|
|
|
159
|
+
config.entities = [
|
|
160
|
+
{
|
|
161
|
+
name: :campaign,
|
|
162
|
+
route: { namespace: :admin },
|
|
163
|
+
pages: [
|
|
164
|
+
{
|
|
165
|
+
action: :index,
|
|
166
|
+
scope: :active
|
|
167
|
+
}
|
|
168
|
+
]
|
|
169
|
+
}
|
|
170
|
+
]
|
|
171
|
+
end
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
In this example, the `Campaign` entity will display only records returned by the `active` scope on its index page, while all
|
|
175
|
+
other pages continue to show every record unless another scope is specified.
|
|
176
|
+
|
|
177
|
+
**route_helper**
|
|
178
|
+
|
|
179
|
+
To get routes Tramway generated just Tramway::Engine.
|
|
180
|
+
|
|
181
|
+
```ruby
|
|
182
|
+
Tramway::Engine.routes.url_helpers.users_path => '/admin/users'
|
|
183
|
+
Tramway::Engine.routes.url_helpers.podcasts_episodes_path => '/podcasts/episodes'
|
|
184
|
+
```
|
|
185
|
+
|
|
143
186
|
### Tramway Decorators
|
|
144
187
|
|
|
145
188
|
Tramway provides convenient decorators for your objects. **NOTE:** This is not the decorator pattern in its usual representation.
|
|
@@ -455,15 +498,19 @@ tramway_navbar title: 'Purple Magic', background: { color: :red, intensity: 500
|
|
|
455
498
|
end
|
|
456
499
|
```
|
|
457
500
|
|
|
458
|
-
#
|
|
501
|
+
# ERB example
|
|
502
|
+
|
|
503
|
+
```erb
|
|
504
|
+
<%= tramway_navbar title: 'Purple Magic', background: { color: :red, intensity: 500 } do |nav| %>
|
|
505
|
+
<% nav.left do %>
|
|
506
|
+
<%= nav.item 'Users', '/users' %>
|
|
507
|
+
<%= nav.item 'Podcasts', '/podcasts' %>
|
|
508
|
+
<% end %>
|
|
459
509
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
- nav.item 'Podcasts', '/podcasts'
|
|
465
|
-
- nav.right do
|
|
466
|
-
- nav.item 'Sign out', '/users/sessions', method: :delete, confirm: 'Wanna quit?'
|
|
510
|
+
<% nav.right do %>
|
|
511
|
+
<%= nav.item 'Sign out', '/users/sessions', method: :delete, confirm: 'Wanna quit?' %>
|
|
512
|
+
<% end %>
|
|
513
|
+
<% end %>
|
|
467
514
|
```
|
|
468
515
|
|
|
469
516
|
will render [this](https://play.tailwindcss.com/UZPTCudFw5)
|
|
@@ -485,13 +532,16 @@ with_entities: Show Tramway Entities index page links to navbar. Default: true
|
|
|
485
532
|
|
|
486
533
|
In case you want to hide entity links you can pass `with_entities: false`.
|
|
487
534
|
|
|
488
|
-
```
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
535
|
+
```erb
|
|
536
|
+
<% if current_user.present? %>
|
|
537
|
+
<%= tramway_navbar title: 'WaiWai' do |nav| %>
|
|
538
|
+
<% nav.left do %>
|
|
539
|
+
<%= nav.item 'Board', admin_board_path %>
|
|
540
|
+
<% end %>
|
|
541
|
+
<% end %>
|
|
542
|
+
<% else %>
|
|
543
|
+
<%= tramway_navbar title: 'WaiWai', with_entities: false %>
|
|
544
|
+
<% end %>
|
|
495
545
|
```
|
|
496
546
|
|
|
497
547
|
#### nav.left and nav.right
|
|
@@ -529,31 +579,43 @@ end
|
|
|
529
579
|
|
|
530
580
|
### Tramway Table Component
|
|
531
581
|
|
|
532
|
-
Tramway provides a responsive, tailwind-styled table with light and dark themes.
|
|
582
|
+
Tramway provides a responsive, tailwind-styled table with light and dark themes. Use the `tramway_table`, `tramway_row`, and
|
|
583
|
+
`tramway_cell` helpers to build tables with readable ERB templates while still leveraging the underlying ViewComponent
|
|
584
|
+
implementations.
|
|
533
585
|
|
|
534
|
-
```
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
586
|
+
```erb
|
|
587
|
+
<%= tramway_table do %>
|
|
588
|
+
<%= tramway_header headers: ['Column 1', 'Column 2'] %>
|
|
589
|
+
|
|
590
|
+
<%= tramway_row do %>
|
|
591
|
+
<%= tramway_cell do %>
|
|
539
592
|
Something
|
|
540
|
-
|
|
593
|
+
<% end %>
|
|
594
|
+
<%= tramway_cell do %>
|
|
541
595
|
Another
|
|
596
|
+
<% end %>
|
|
597
|
+
<% end %>
|
|
598
|
+
<% end %>
|
|
542
599
|
```
|
|
543
600
|
|
|
544
|
-
`
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
601
|
+
`tramway_table` accepts the same optional `options` hash as `Tailwinds::TableComponent`. The hash is forwarded as HTML
|
|
602
|
+
attributes, so you can pass things like `id`, `data` attributes, or additional classes. If you do not supply your own width
|
|
603
|
+
utility (e.g. a class that starts with `w-`), the component automatically appends `w-full` to keep the table responsive. This
|
|
604
|
+
allows you to extend the default styling without losing the sensible defaults provided by the component.
|
|
605
|
+
|
|
606
|
+
```erb
|
|
607
|
+
<%= tramway_table class: 'max-w-3xl border border-gray-200', data: { controller: 'table' } do %>
|
|
608
|
+
<%= tramway_header', headers: ['Name', 'Email'] %>
|
|
548
609
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
610
|
+
<%= tramway_row do %>
|
|
611
|
+
<%= tramway_cell do %>
|
|
612
|
+
<%= user.name %>
|
|
613
|
+
<% end %>
|
|
614
|
+
<%= tramway_cell do %>
|
|
615
|
+
<%= user.email %>
|
|
616
|
+
<% end %>
|
|
617
|
+
<% end %>
|
|
618
|
+
<% end %>
|
|
557
619
|
```
|
|
558
620
|
|
|
559
621
|
When you render a header you can either pass the `headers:` array, as in the examples above, or render custom header content in
|
|
@@ -561,18 +623,48 @@ the block. `Tailwinds::Table::HeaderComponent` uses the length of the `headers`
|
|
|
561
623
|
If you omit the array and provide custom content, pass the `columns:` argument so the component knows how many grid columns to
|
|
562
624
|
generate.
|
|
563
625
|
|
|
564
|
-
```
|
|
565
|
-
|
|
566
|
-
|
|
626
|
+
```erb
|
|
627
|
+
<%= component 'tailwinds/table/header', columns: 4 do %>
|
|
628
|
+
<%= tramway_cell do %>
|
|
567
629
|
Custom header cell
|
|
568
|
-
|
|
630
|
+
<% end %>
|
|
631
|
+
<%= tramway_cell do %>
|
|
569
632
|
Another header cell
|
|
570
|
-
|
|
633
|
+
<% end %>
|
|
634
|
+
<!-- ... -->
|
|
635
|
+
<% end %>
|
|
571
636
|
```
|
|
572
637
|
|
|
573
638
|
With this approach you control the header layout while still benefiting from the default Tailwind grid classes that the header
|
|
574
639
|
component applies.
|
|
575
640
|
|
|
641
|
+
### Tramway Buttons and Containers
|
|
642
|
+
|
|
643
|
+
Tramway ships with helpers for common UI patterns built on top of Tailwind components.
|
|
644
|
+
|
|
645
|
+
* `tramway_button` renders a button-styled link and accepts `path`, optional `text`, HTTP `method`, and styling options such as
|
|
646
|
+
`color`, `type`, and `size`. All additional keyword arguments are forwarded to the underlying component as HTML attributes.
|
|
647
|
+
|
|
648
|
+
```erb
|
|
649
|
+
<%= tramway_button path: user_path(user), text: 'View profile', color: :emerald, data: { turbo: false } %>
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
* `tramway_back_button` renders a standardized "Back" link.
|
|
653
|
+
|
|
654
|
+
```erb
|
|
655
|
+
<%= tramway_back_button %>
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
* `tramway_container` wraps content in a responsive, narrow layout container. Pass an `id` if you need to target the container
|
|
659
|
+
with JavaScript or CSS.
|
|
660
|
+
|
|
661
|
+
```erb
|
|
662
|
+
<%= tramway_container id: 'user-settings' do %>
|
|
663
|
+
<h2 class="text-xl font-semibold">Settings</h2>
|
|
664
|
+
<p class="mt-2 text-gray-600">Update your preferences below.</p>
|
|
665
|
+
<% end %>
|
|
666
|
+
```
|
|
667
|
+
|
|
576
668
|
### Tailwind-styled forms
|
|
577
669
|
|
|
578
670
|
Tramway uses [Tailwind](https://tailwindcss.com/) by default. All UI helpers are implemented with [ViewComponent](https://github.com/viewcomponent/view_component).
|
|
@@ -581,15 +673,16 @@ Tramway uses [Tailwind](https://tailwindcss.com/) by default. All UI helpers are
|
|
|
581
673
|
|
|
582
674
|
Tramway provides `tramway_form_for` helper that renders Tailwind-styled forms by default.
|
|
583
675
|
|
|
584
|
-
```
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
676
|
+
```erb
|
|
677
|
+
<%= tramway_form_for @user do |f| %>
|
|
678
|
+
<%= f.text_field :text %>
|
|
679
|
+
<%= f.email_field :email %>
|
|
680
|
+
<%= f.password_field :password %>
|
|
681
|
+
<%= f.select :role, [:admin, :user] %>
|
|
682
|
+
<%= f.multiselect :permissions, [['Create User', 'create_user'], ['Update user', 'update_user']] %>
|
|
683
|
+
<%= f.file_field :file %>
|
|
684
|
+
<%= f.submit 'Create User' %>
|
|
685
|
+
<% end %>
|
|
593
686
|
```
|
|
594
687
|
|
|
595
688
|
will render [this](https://play.tailwindcss.com/xho3LfjKkK)
|
|
@@ -607,25 +700,27 @@ Available form helpers:
|
|
|
607
700
|
|
|
608
701
|
1. Sign In Form for `devise` authentication
|
|
609
702
|
|
|
610
|
-
*app/views/devise/sessions/new.html.
|
|
611
|
-
```
|
|
612
|
-
|
|
613
|
-
|
|
703
|
+
*app/views/devise/sessions/new.html.erb*
|
|
704
|
+
```erb
|
|
705
|
+
<%= tramway_form_for(resource, as: resource_name, url: session_path(resource_name), class: 'bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4') do |f| %>
|
|
706
|
+
<%= component 'forms/errors', record: resource %>
|
|
614
707
|
|
|
615
|
-
|
|
616
|
-
|
|
708
|
+
<%= f.text_field :email, placeholder: 'Your email' %>
|
|
709
|
+
<%= f.password_field :password, placeholder: 'Your password' %>
|
|
617
710
|
|
|
618
|
-
|
|
711
|
+
<%= f.submit 'Sign In' %>
|
|
712
|
+
<% end %>
|
|
619
713
|
```
|
|
620
714
|
|
|
621
715
|
2. Sign In Form for Rails authorization
|
|
622
716
|
|
|
623
|
-
*app/views/sessions/new.html.
|
|
624
|
-
```
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
717
|
+
*app/views/sessions/new.html.erb*
|
|
718
|
+
```erb
|
|
719
|
+
<%= form_with url: login_path, scope: :session, local: true, builder: Tailwinds::Form::Builder do |form| %>
|
|
720
|
+
<%= form.email_field :email %>
|
|
721
|
+
<%= form.password_field :password %>
|
|
722
|
+
<%= form.submit 'Log in' %>
|
|
723
|
+
<% end %>
|
|
629
724
|
```
|
|
630
725
|
|
|
631
726
|
#### Stimulus-based inputs
|
|
@@ -636,10 +731,11 @@ Available form helpers:
|
|
|
636
731
|
|
|
637
732
|
In case you want to use tailwind-styled multiselect this way
|
|
638
733
|
|
|
639
|
-
```
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
734
|
+
```erb
|
|
735
|
+
<%= tramway_form_for @user do |f| %>
|
|
736
|
+
<%= f.multiselect :permissions, [['Create User', 'create_user'], ['Update user', 'update_user']] %>
|
|
737
|
+
<%# ... %>
|
|
738
|
+
<% end %>
|
|
643
739
|
```
|
|
644
740
|
|
|
645
741
|
you should add Tramway Multiselect Stimulus controller to your application.
|
|
@@ -663,9 +759,10 @@ application.register('multiselect', Multiselect) // register Multiselect control
|
|
|
663
759
|
|
|
664
760
|
Use Stimulus `change` action with Tramway Multiselect
|
|
665
761
|
|
|
666
|
-
```
|
|
667
|
-
|
|
668
|
-
|
|
762
|
+
```erb
|
|
763
|
+
<%= tramway_form_for @user do |f| %>
|
|
764
|
+
<%= f.multiselect :role, data: { action: 'change->user-form#updateForm' } %>
|
|
765
|
+
<% end %>
|
|
669
766
|
```
|
|
670
767
|
|
|
671
768
|
### Tailwind-styled pagination for Kaminari
|
|
@@ -687,9 +784,9 @@ Tramway.configure do |config|
|
|
|
687
784
|
end
|
|
688
785
|
```
|
|
689
786
|
|
|
690
|
-
*app/views/users/index.html.
|
|
691
|
-
```
|
|
692
|
-
|
|
787
|
+
*app/views/users/index.html.erb*
|
|
788
|
+
```erb
|
|
789
|
+
<%= paginate @users %> <%# it will render tailwind-styled pagination buttons by default %>
|
|
693
790
|
```
|
|
694
791
|
|
|
695
792
|
Pagination buttons looks like [this](https://play.tailwindcss.com/mqgDS5l9oY)
|
|
@@ -710,11 +807,41 @@ user_2 = tramway_form User.first
|
|
|
710
807
|
user_2.object #=> returns pure user object
|
|
711
808
|
```
|
|
712
809
|
|
|
810
|
+
## Configuration
|
|
811
|
+
|
|
812
|
+
### Custom layout
|
|
813
|
+
|
|
814
|
+
In case you wanna use a custom layout:
|
|
815
|
+
|
|
816
|
+
1. Create a controller
|
|
817
|
+
2. Set the layout there
|
|
818
|
+
3. Set this controller as `application_controller` in Tramway initializer
|
|
819
|
+
4. Reload your server
|
|
820
|
+
|
|
821
|
+
**Example**
|
|
822
|
+
|
|
823
|
+
*app/controllers/admin/application_controller.rb*
|
|
824
|
+
```ruby
|
|
825
|
+
class Admin::ApplicationController < ApplicationController
|
|
826
|
+
layout 'admin/application'
|
|
827
|
+
end
|
|
828
|
+
```
|
|
829
|
+
|
|
830
|
+
*config/initializers/tramway.rb*
|
|
831
|
+
```ruby
|
|
832
|
+
Tramway.configure do |config|
|
|
833
|
+
config.application_controller = 'Admin::ApplicationController'
|
|
834
|
+
end
|
|
835
|
+
```
|
|
836
|
+
|
|
713
837
|
## Articles
|
|
714
838
|
* [Tramway on Rails](https://kalashnikovisme.medium.com/tramway-on-rails-32158c35ed68)
|
|
839
|
+
* [Tramway is the way to deal with little things for Rails developers](https://medium.com/@kalashnikovisme/tramway-is-the-way-to-deal-with-little-things-for-rails-developers-4f502172a18c)
|
|
715
840
|
* [Delegating ActiveRecord methods to decorators in Rails](https://kalashnikovisme.medium.com/delegating-activerecord-methods-to-decorators-in-rails-4e4ec1c6b3a6)
|
|
716
841
|
* [Behave as ActiveRecord. Why do we want objects to be AR lookalikes?](https://kalashnikovisme.medium.com/behave-as-activerecord-why-do-we-want-objects-to-be-ar-lookalikes-d494d692e1d3)
|
|
717
842
|
* [Decorating associations in Rails with Tramway](https://kalashnikovisme.medium.com/decorating-associations-in-rails-with-tramway-b46a28392f9e)
|
|
843
|
+
* [Easy-to-use Tailwind-styled multi-select built with Stimulus](https://medium.com/@kalashnikovisme/easy-to-use-tailwind-styled-multi-select-built-with-stimulus-b3daa9e307aa)
|
|
844
|
+
*
|
|
718
845
|
|
|
719
846
|
## Contributing
|
|
720
847
|
|
|
@@ -17,12 +17,12 @@
|
|
|
17
17
|
%p.text-center.mt-10
|
|
18
18
|
You should fill class-level method `self.list_attributes` inside your
|
|
19
19
|
= decorator
|
|
20
|
+
- else
|
|
21
|
+
= component 'tailwinds/table' do
|
|
22
|
+
= component 'tailwinds/table/header', headers: list_attributes.map { |attribute| @model_class.human_attribute_name(attribute) }
|
|
23
|
+
- @entities.each do |item|
|
|
24
|
+
= render 'tramway/entities/entity', entity: item
|
|
20
25
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
= render 'tramway/entities/entity', entity: item
|
|
25
|
-
|
|
26
|
-
- if Tramway.config.pagination[:enabled]
|
|
27
|
-
.flex.mt-4
|
|
28
|
-
= paginate @entities, custom_path_method: "#{@model_class.model_name.plural}_path"
|
|
26
|
+
- if Tramway.config.pagination[:enabled]
|
|
27
|
+
.flex.mt-4
|
|
28
|
+
= paginate @entities, custom_path_method: "#{@model_class.model_name.plural}_path"
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
=
|
|
1
|
+
= tramway_container do
|
|
2
|
+
= render 'tramway/entities/list'
|
|
@@ -17,6 +17,14 @@ module Tramway
|
|
|
17
17
|
component 'tailwinds/table', options:, &
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
+
def tramway_header(headers: nil, columns: nil, &)
|
|
21
|
+
component 'tailwinds/table/header',
|
|
22
|
+
headers:,
|
|
23
|
+
columns:,
|
|
24
|
+
options:,
|
|
25
|
+
&
|
|
26
|
+
end
|
|
27
|
+
|
|
20
28
|
def tramway_row(**options, &)
|
|
21
29
|
component 'tailwinds/table/row',
|
|
22
30
|
cells: options.delete(:cells),
|
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:
|
|
4
|
+
version: 0.6.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- kalashnikovisme
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2025-10-
|
|
12
|
+
date: 2025-10-27 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: anyway_config
|