tramway 0.5.0.1 → 0.5.1.1
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 +72 -0
- data/app/assets/javascripts/tramway/multiselect_controller.js +27 -4
- data/app/components/tailwinds/form/builder.rb +1 -1
- data/app/components/tailwinds/form/multiselect_component.rb +19 -2
- data/app/components/tailwinds/navbar_component.html.haml +4 -4
- data/app/components/tailwinds/pagination/first_page_component.html.haml +9 -2
- data/app/components/tailwinds/pagination/gap_component.html.haml +1 -1
- data/app/components/tailwinds/pagination/last_page_component.html.haml +9 -2
- data/app/components/tailwinds/pagination/next_page_component.html.haml +11 -2
- data/app/components/tailwinds/pagination/page_component.html.haml +5 -1
- data/app/components/tailwinds/pagination/prev_page_component.html.haml +11 -2
- data/app/components/tailwinds/table/header_component.html.haml +1 -1
- data/app/components/tailwinds/table/row_component.html.haml +5 -3
- data/app/components/tailwinds/table/row_component.rb +1 -1
- data/app/controllers/tramway/entities_controller.rb +4 -0
- data/app/views/tramway/entities/index.html.haml +12 -9
- data/app/views/tramway/layouts/application.html.haml +26 -0
- data/config/tailwind.config.js +52 -0
- data/lib/tramway/base_decorator.rb +19 -0
- data/lib/tramway/decorators/class_helper.rb +19 -9
- data/lib/tramway/version.rb +1 -1
- metadata +21 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f4ba049579087665a532f06011144ca74a591cb7704769c8a2c69c99aca81aad
|
4
|
+
data.tar.gz: 44b743f0aa80d9d6b074a325505b66a8c7a019f1c59103fd6ea79e5faf567ed8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 88a6ba5eda48febc6aec0c5c15915ee276161ddedbaa281fed6a65e68b0dc55e4d04e53a6505d68fb9e9a5871249ea2b565ac9d828dbf2b186d8bd11368b663c
|
7
|
+
data.tar.gz: 25ae018d2242c6adc460e1058489109c2fae3d151243b8240d925ed1a63e0d1e19beef90d3c23cf036d34d207816c316051c8db5d681628ea2bedb0743e1a33f
|
data/README.md
CHANGED
@@ -17,6 +17,8 @@ Add this line to your application's Gemfile:
|
|
17
17
|
|
18
18
|
```ruby
|
19
19
|
gem "tramway"
|
20
|
+
gem "haml-rails"
|
21
|
+
gem "kaminari"
|
20
22
|
gem "view_component"
|
21
23
|
```
|
22
24
|
|
@@ -26,8 +28,71 @@ OR
|
|
26
28
|
bundle add tramway view_component
|
27
29
|
```
|
28
30
|
|
31
|
+
## Getting Started
|
32
|
+
|
33
|
+
**Step 1**
|
34
|
+
|
35
|
+
*config/initializers/tramway.rb*
|
36
|
+
```ruby
|
37
|
+
Tramway.configure do |config|
|
38
|
+
config.entities = [
|
39
|
+
{
|
40
|
+
name: :user,
|
41
|
+
pages: [:index],
|
42
|
+
}
|
43
|
+
]
|
44
|
+
end
|
45
|
+
```
|
46
|
+
|
47
|
+
**Step 2**
|
48
|
+
|
49
|
+
*config/routes.rb*
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
Rails.application.routes.draw do
|
53
|
+
mount Tramway::Engine, at: '/'
|
54
|
+
end
|
55
|
+
```
|
56
|
+
|
57
|
+
**Step 3**
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
class UserDecorator < Tramway::BaseDecorator
|
61
|
+
def self.list_attributes
|
62
|
+
[:id, :email, :created_at]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
```
|
66
|
+
|
67
|
+
**Step 4**
|
68
|
+
|
69
|
+
Copy this [file](https://github.com/Purple-Magic/tramway/blob/main/config/tailwind.config.js) to config/tailwind.config.js
|
70
|
+
|
71
|
+
|
72
|
+
**Step 5**
|
73
|
+
|
74
|
+
Run tailwincss-rails compiler
|
75
|
+
|
76
|
+
|
77
|
+
```bash
|
78
|
+
bin/rails tailwindcss:build
|
79
|
+
```
|
80
|
+
|
81
|
+
**Step 6**
|
82
|
+
|
83
|
+
Run your server
|
84
|
+
|
85
|
+
```bash
|
86
|
+
bundle exec rails s
|
87
|
+
```
|
88
|
+
|
89
|
+
**Step 7**
|
90
|
+
|
91
|
+
Open [http://localhost:3000/users](http://localhost:3000/users)
|
92
|
+
|
29
93
|
## Usage
|
30
94
|
|
95
|
+
|
31
96
|
### Tramway Entities
|
32
97
|
|
33
98
|
Tramway is an entity-based framework. **Entity** is the class on whose objects actions be applied: _index, show, create, update, and destroy_. Tramway will support numerous classes as entities. For now, Entity could be only **ActiveRecord::Base** class.
|
@@ -486,6 +551,13 @@ eagerLoadControllersFrom("controllers", application)
|
|
486
551
|
application.register('multiselect', Multiselect) // register Multiselect controller class as `multiselect` stimulus controller
|
487
552
|
```
|
488
553
|
|
554
|
+
Use Stimulus `change` action with Tramway Multiselect
|
555
|
+
|
556
|
+
```ruby
|
557
|
+
= tramway_form_for @user do |f|
|
558
|
+
= f.multiselect :role, data: { action: 'change->user-form#updateForm' } # user-form is your Stimulus controller, updateForm is a method inside user-form Stimulus controller
|
559
|
+
```
|
560
|
+
|
489
561
|
### Tailwind-styled pagination for Kaminari
|
490
562
|
|
491
563
|
Tramway uses [Tailwind](https://tailwindcss.com/) by default. It has tailwind-styled pagination for [kaminari](https://github.com/kaminari/kaminari).
|
@@ -12,7 +12,8 @@ export default class Multiselect extends Controller {
|
|
12
12
|
selectedItems: Array,
|
13
13
|
placeholder: String,
|
14
14
|
selectAsInput: String,
|
15
|
-
value: Array
|
15
|
+
value: Array,
|
16
|
+
onChange: String
|
16
17
|
}
|
17
18
|
|
18
19
|
connect() {
|
@@ -26,9 +27,14 @@ export default class Multiselect extends Controller {
|
|
26
27
|
}
|
27
28
|
});
|
28
29
|
|
29
|
-
const initialValues = this.element.dataset.value === undefined ? [] : this.element.dataset.value
|
30
|
-
|
31
|
-
|
30
|
+
const initialValues = this.element.dataset.value === undefined ? [] : JSON.parse(this.element.dataset.value);
|
31
|
+
|
32
|
+
initialValues.map((value) => {
|
33
|
+
const itemIndex = this.items.findIndex(x => x.value.toString() === value.toString());
|
34
|
+
this.items[itemIndex].selected = true;
|
35
|
+
})
|
36
|
+
|
37
|
+
this.selectedItems = this.items.filter(item => item.selected);
|
32
38
|
|
33
39
|
this.renderSelectedItems();
|
34
40
|
}
|
@@ -84,6 +90,23 @@ export default class Multiselect extends Controller {
|
|
84
90
|
if (this.dropdown()) {
|
85
91
|
this.dropdown().remove();
|
86
92
|
}
|
93
|
+
|
94
|
+
const onChange = this.element.dataset.onChange;
|
95
|
+
|
96
|
+
if (onChange) {
|
97
|
+
const [controllerName, actionName] = onChange.split('#');
|
98
|
+
const controller = this.application.controllers.find(controller => controller.identifier === controllerName)
|
99
|
+
|
100
|
+
if (controller) {
|
101
|
+
if (typeof controller[actionName] === 'function') {
|
102
|
+
controller[actionName]({ target: this.element });
|
103
|
+
} else {
|
104
|
+
alert(`Action not found: ${actionName}`); // eslint-disable-line no-undef
|
105
|
+
}
|
106
|
+
} else {
|
107
|
+
alert(`Controller not found: ${controllerName}`); // eslint-disable-line no-undef
|
108
|
+
}
|
109
|
+
}
|
87
110
|
}
|
88
111
|
|
89
112
|
get template() {
|
@@ -38,7 +38,7 @@ module Tailwinds
|
|
38
38
|
def multiselect(attribute, collection, **options, &)
|
39
39
|
render(Tailwinds::Form::MultiselectComponent.new(
|
40
40
|
input: input(:text_field),
|
41
|
-
value: options[:value] || options[:selected] || object.public_send(attribute)
|
41
|
+
value: options[:value] || options[:selected] || object.public_send(attribute),
|
42
42
|
collection:,
|
43
43
|
**default_options(attribute, options)
|
44
44
|
), &)
|
@@ -15,12 +15,15 @@ module Tailwinds
|
|
15
15
|
def multiselect_hash
|
16
16
|
{
|
17
17
|
controller:, selected_item_template:, multiselect_selected_items_value:, dropdown_container:, item_container:,
|
18
|
-
items:, action:, select_as_input:, placeholder:, value:
|
18
|
+
items:, action:, select_as_input:, placeholder:, value:, on_change:
|
19
19
|
}.transform_keys { |key| key.to_s.gsub('_', '-') }
|
20
20
|
end
|
21
21
|
|
22
22
|
def controller
|
23
|
-
:multiselect
|
23
|
+
controllers = [:multiselect]
|
24
|
+
controllers << external_action.split('->').last.split('#').first if external_action
|
25
|
+
controllers += external_controllers
|
26
|
+
controllers.join(' ')
|
24
27
|
end
|
25
28
|
|
26
29
|
private
|
@@ -45,6 +48,20 @@ module Tailwinds
|
|
45
48
|
render(Tailwinds::Form::Multiselect::SelectAsInput.new(options:, attribute:, input:))
|
46
49
|
end
|
47
50
|
|
51
|
+
def on_change
|
52
|
+
return unless external_action&.start_with?('change')
|
53
|
+
|
54
|
+
external_action.split('->').last
|
55
|
+
end
|
56
|
+
|
57
|
+
def external_controllers
|
58
|
+
options[:controller]&.split || []
|
59
|
+
end
|
60
|
+
|
61
|
+
def external_action
|
62
|
+
options.dig(:data, :action)
|
63
|
+
end
|
64
|
+
|
48
65
|
def method_missing(method_name, *, &)
|
49
66
|
component = component_name(method_name)
|
50
67
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
%nav.py-
|
1
|
+
%nav.py-2.px-4.sm:px-8.flex.justify-between.items-center.dark:bg-gray-800{ class: "bg-#{@color}" }
|
2
2
|
.flex.justify-between.w-full
|
3
3
|
- if @title[:text].present? || @left_items.present?
|
4
4
|
.flex.items-center
|
@@ -7,16 +7,16 @@
|
|
7
7
|
.text-xl.text-white.font-bold
|
8
8
|
= @title[:text]
|
9
9
|
- if @left_items.present?
|
10
|
-
%ul.
|
10
|
+
%ul.block.flex.flex-row.items-center.space-x-4.ml-4
|
11
11
|
- @left_items.each do |item|
|
12
12
|
= item
|
13
13
|
|
14
|
-
.
|
14
|
+
.hidden.sm:block
|
15
15
|
%button#mobile-menu-button.text-white.focus:outline-none
|
16
16
|
☰
|
17
17
|
|
18
18
|
- if @right_items.present?
|
19
|
-
%ul.
|
19
|
+
%ul.block.sm:flex.items-center.space-x-4
|
20
20
|
- @right_items.each do |item|
|
21
21
|
= item
|
22
22
|
|
@@ -1,3 +1,10 @@
|
|
1
1
|
- unless current_page.first?
|
2
|
-
= link_to helpers.t('views.pagination.first').html_safe,
|
3
|
-
|
2
|
+
= link_to helpers.t('views.pagination.first').html_safe,
|
3
|
+
url,
|
4
|
+
remote:,
|
5
|
+
class: pagination_classes(klass: 'first sm:hidden flex')
|
6
|
+
|
7
|
+
= link_to '⭰',
|
8
|
+
url,
|
9
|
+
remote:,
|
10
|
+
class: pagination_classes(klass: 'first hidden sm:flex font-bold')
|
@@ -1,2 +1,2 @@
|
|
1
|
-
%span.page.gap.px-3.py-2.text-sm.font-medium.text-purple-700.dark:text-white.sm:
|
1
|
+
%span.page.gap.px-3.py-2.text-sm.font-medium.text-purple-700.dark:text-white.flex.sm:hidden
|
2
2
|
= helpers.t('views.pagination.truncate').html_safe
|
@@ -1,3 +1,10 @@
|
|
1
1
|
- unless current_page.last?
|
2
|
-
= link_to helpers.t('views.pagination.last').html_safe,
|
3
|
-
|
2
|
+
= link_to helpers.t('views.pagination.last').html_safe,
|
3
|
+
url,
|
4
|
+
remote:,
|
5
|
+
class: pagination_classes(klass: 'last sm:hidden flex')
|
6
|
+
|
7
|
+
= link_to '⭲',
|
8
|
+
url,
|
9
|
+
remote:,
|
10
|
+
class: pagination_classes(klass: 'last hidden sm:flex font-bold')
|
@@ -1,3 +1,12 @@
|
|
1
1
|
- unless current_page.last?
|
2
|
-
= link_to helpers.t('views.pagination.next').html_safe,
|
3
|
-
|
2
|
+
= link_to helpers.t('views.pagination.next').html_safe,
|
3
|
+
url,
|
4
|
+
rel: 'next',
|
5
|
+
remote:,
|
6
|
+
class: pagination_classes(klass: 'next sm:hidden flex')
|
7
|
+
|
8
|
+
= link_to '🠖',
|
9
|
+
url,
|
10
|
+
rel: 'next',
|
11
|
+
remote:,
|
12
|
+
class: pagination_classes(klass: 'next hidden sm:flex font-bold')
|
@@ -2,4 +2,8 @@
|
|
2
2
|
%span.px-3.py-2.font-medium.rounded-md.bg-purple-500.text-white.dark:text-gray-800.dark:bg-white
|
3
3
|
= page
|
4
4
|
- else
|
5
|
-
= link_to page,
|
5
|
+
= link_to page,
|
6
|
+
url,
|
7
|
+
remote:,
|
8
|
+
rel: page.rel,
|
9
|
+
class: pagination_classes(klass: 'sm:hidden flex')
|
@@ -1,3 +1,12 @@
|
|
1
1
|
- unless current_page.first?
|
2
|
-
= link_to helpers.t('views.pagination.previous').html_safe,
|
3
|
-
|
2
|
+
= link_to helpers.t('views.pagination.previous').html_safe,
|
3
|
+
url,
|
4
|
+
rel: 'prev',
|
5
|
+
remote:,
|
6
|
+
class: pagination_classes(klass: 'prev sm:hidden flex')
|
7
|
+
|
8
|
+
= link_to '🠔',
|
9
|
+
url,
|
10
|
+
rel: 'prev',
|
11
|
+
remote:,
|
12
|
+
class: pagination_classes(klass: 'prev hidden sm:flex font-bold')
|
@@ -1,6 +1,6 @@
|
|
1
1
|
- cols = headers.map { |item| "1fr" }.join(",")
|
2
2
|
|
3
|
-
.div-table-row.
|
3
|
+
.div-table-row.block.grid.text-white.text-small.gap-4.bg-purple-700.dark:bg-gray-700.dark:text-gray-400{ class: "grid-cols-[#{cols}]" }
|
4
4
|
- headers.each do |header|
|
5
5
|
.div-table-cell.py-4.px-6
|
6
6
|
= header
|
@@ -2,12 +2,14 @@
|
|
2
2
|
- if cells.any?
|
3
3
|
- cols = cells.count.times.map { |item| "1fr" }.join(",")
|
4
4
|
|
5
|
-
|
5
|
+
-# desktop view
|
6
|
+
= row_tag class: "div-table-row block grid gap-4 bg-white border-b dark:bg-gray-800 dark:border-gray-700 cursor-pointer hover:bg-purple-100 grid-cols-[#{cols}]" do
|
6
7
|
- cells.each do |(_, value)|
|
7
|
-
.div-table-cell.px-6.py-4.font-medium.text-gray-900.whitespace-nowrap.dark:text-white.text-xs.
|
8
|
+
.div-table-cell.px-6.py-4.font-medium.text-gray-900.whitespace-nowrap.dark:text-white.sm:text-xs.text-base
|
8
9
|
= value
|
9
10
|
|
10
|
-
|
11
|
+
-# mobile view
|
12
|
+
.div-table-row.xl:hidden.border-b.dark:bg-gray-800.dark:border-gray-700.mb-2{ "data-action" => "click->preview#toggle", "data-controller" => "preview", "data-items" => cells.to_json }
|
11
13
|
.w-full.p-4.bg-purple-100.text-gray-700.dark:bg-gray-700.dark:text-gray-400
|
12
14
|
= cells.values.first
|
13
15
|
|
@@ -9,7 +9,7 @@ module Tailwinds
|
|
9
9
|
|
10
10
|
def row_tag(**options, &)
|
11
11
|
if href.present?
|
12
|
-
klass = "#{options[:class] || ''} cursor-pointer hover:bg-gray-700"
|
12
|
+
klass = "#{options[:class] || ''} cursor-pointer dark:hover:bg-gray-700"
|
13
13
|
|
14
14
|
link_to(href, options.merge(class: klass)) do
|
15
15
|
yield if block_given?
|
@@ -3,6 +3,10 @@
|
|
3
3
|
module Tramway
|
4
4
|
# Main controller for entities pages
|
5
5
|
class EntitiesController < Tramway.config.application_controller.constantize
|
6
|
+
prepend_view_path "#{Gem::Specification.find_by_name('tramway').gem_dir}/app/views"
|
7
|
+
|
8
|
+
layout 'tramway/layouts/application'
|
9
|
+
|
6
10
|
helper Tramway::ApplicationHelper
|
7
11
|
include Rails.application.routes.url_helpers
|
8
12
|
|
@@ -1,4 +1,7 @@
|
|
1
|
-
.
|
1
|
+
- decorator = Tramway::Decorators::NameBuilder.default_decorator_class_name(@model_class)
|
2
|
+
- list_attributes = decorator.constantize.list_attributes
|
3
|
+
|
4
|
+
.mt-8{ class: 'w-2/3' }
|
2
5
|
- content_for :title, page_title
|
3
6
|
|
4
7
|
.flex.justify-between.items-center.md:mt-4.mt-2
|
@@ -8,15 +11,15 @@
|
|
8
11
|
- if Tramway.config.pagination[:enabled]
|
9
12
|
= paginate @entities
|
10
13
|
|
11
|
-
- if
|
14
|
+
- if list_attributes.empty?
|
12
15
|
%p.text-center.mt-10
|
13
16
|
You should fill class-level method `self.list_attributes` inside your
|
14
|
-
=
|
17
|
+
= decorator
|
15
18
|
|
16
|
-
= component 'tailwinds/table' do
|
17
|
-
|
18
|
-
|
19
|
-
|
19
|
+
= component 'tailwinds/table' do
|
20
|
+
= component 'tailwinds/table/header', headers: list_attributes.map { |attribute| @model_class.human_attribute_name(attribute) }
|
21
|
+
- @entities.each do |item|
|
22
|
+
= render 'entity', entity: item
|
20
23
|
|
21
|
-
|
22
|
-
|
24
|
+
.flex.mt-4
|
25
|
+
= paginate @entities
|
@@ -0,0 +1,26 @@
|
|
1
|
+
%html
|
2
|
+
%head
|
3
|
+
%title= content_for(:title) || "Tramway"
|
4
|
+
%meta{name: "viewport", content: "width=device-width,initial-scale=1"}
|
5
|
+
%meta{name: "apple-mobile-web-app-capable", content: "yes"}
|
6
|
+
%meta{name: "mobile-web-app-capable", content: "yes"}
|
7
|
+
= csrf_meta_tags
|
8
|
+
= csp_meta_tag
|
9
|
+
|
10
|
+
= yield :head
|
11
|
+
|
12
|
+
/ Enable PWA manifest for installable apps (make sure to enable in config/routes.rb too!)
|
13
|
+
/ = tag.link rel: "manifest", href: pwa_manifest_path(format: :json)
|
14
|
+
|
15
|
+
%link{rel: "icon", href: "/icon.png", type: "image/png"}
|
16
|
+
%link{rel: "icon", href: "/icon.svg", type: "image/svg+xml"}
|
17
|
+
%link{rel: "apple-touch-icon", href: "/icon.png"}
|
18
|
+
|
19
|
+
/ Includes all stylesheet files in app/assets/stylesheets
|
20
|
+
= stylesheet_link_tag "tailwind", "data-turbo-track": "reload"
|
21
|
+
|
22
|
+
%body.bg-gray-100
|
23
|
+
= tramway_navbar title: 'Tramway'
|
24
|
+
|
25
|
+
.container.mx-auto.p-4.flex.align-center.justify-center
|
26
|
+
= yield
|
@@ -0,0 +1,52 @@
|
|
1
|
+
const defaultTheme = require('tailwindcss/defaultTheme');
|
2
|
+
|
3
|
+
module.exports = {
|
4
|
+
darkMode: 'class',
|
5
|
+
content: [
|
6
|
+
'./public/*.html',
|
7
|
+
'./app/components/**/*.html.haml',
|
8
|
+
'./app/helpers/**/*.rb',
|
9
|
+
'./app/javascript/**/*.js',
|
10
|
+
'./app/views/**/*.{erb,haml,html,slim}'
|
11
|
+
],
|
12
|
+
theme: {
|
13
|
+
extend: {
|
14
|
+
screens: {
|
15
|
+
...defaultTheme.screens,
|
16
|
+
},
|
17
|
+
},
|
18
|
+
},
|
19
|
+
safelist: [
|
20
|
+
'div-table',
|
21
|
+
'div-table-row',
|
22
|
+
'div-table-cell',
|
23
|
+
'hidden',
|
24
|
+
'text-xl',
|
25
|
+
'text-4xl',
|
26
|
+
'font-bold',
|
27
|
+
'xl:hidden',
|
28
|
+
'grid-cols-[1fr,1fr,1fr]',
|
29
|
+
'text-right',
|
30
|
+
'w-2/3',
|
31
|
+
'flex',
|
32
|
+
// multiselect styles
|
33
|
+
'absolute', 'shadow', 'top-100', 'z-40', 'w-full', 'lef-0', 'rounded', 'max-h-select', 'overflow-y-auto', 'cursor-pointer', 'rounded-t', 'border-b', 'hover:bg-teal-100', 'items-center', 'border-transparent', 'border-l-2,', 'relative', 'hover:border-teal-100', 'leading-6', 'bg-transparent', 'appearance-none', 'outline-none', 'h-full' , 'justify-center', 'm-1', 'font-medium', 'rounded-full', 'text-teal-700', 'bg-teal-100', 'border', 'border-teal-300', 'text-xs', 'font-normal', 'leading-none', 'max-w-full', 'flex-initial', 'flex-auto', 'flex-row-reverse',, 'flex-col', 'min-w-96', 'w-fit', 'flex-wrap', 'w-8', 'border-l',
|
34
|
+
{
|
35
|
+
pattern: /(text|bg|border)-(purple|blue|gray|yellow|red|white|green)-\d+/,
|
36
|
+
variants: ['dark', 'focus', 'hover', 'dark:hover'],
|
37
|
+
},
|
38
|
+
{
|
39
|
+
pattern: /(text|bg)-(purple|blue|gray|yellow|red|white)/,
|
40
|
+
variants: ['dark', 'focus', 'hover', 'dark:hover'],
|
41
|
+
},
|
42
|
+
{
|
43
|
+
pattern: /(m|p)(l|r|b|t|x|y)-\d+/
|
44
|
+
},
|
45
|
+
],
|
46
|
+
plugins: [
|
47
|
+
require('@tailwindcss/forms'),
|
48
|
+
require('@tailwindcss/aspect-ratio'),
|
49
|
+
require('@tailwindcss/typography'),
|
50
|
+
require('@tailwindcss/container-queries'),
|
51
|
+
],
|
52
|
+
};
|
@@ -57,5 +57,24 @@ module Tramway
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def show_path = nil
|
60
|
+
|
61
|
+
# :reek:ManualDispatch { enabled: false } because there is the idea to manual dispatch
|
62
|
+
def method_missing(method_name, *, &)
|
63
|
+
url_helpers = Rails.application.routes.url_helpers
|
64
|
+
|
65
|
+
if method_name.to_s.end_with?('_path', '_url')
|
66
|
+
return url_helpers.public_send(method_name, *, &) if url_helpers.respond_to?(method_name)
|
67
|
+
|
68
|
+
raise NoMethodError, "undefined method `#{method_name}` for #{self}" unless respond_to_missing?(method_name)
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
super
|
73
|
+
end
|
74
|
+
|
75
|
+
# :reek:BooleanParameter { enabled: false } because it's a part of the duck-typing
|
76
|
+
def respond_to_missing?(method_name, include_private = false)
|
77
|
+
method_name.to_s.end_with?('_path', '_url') || super
|
78
|
+
end
|
60
79
|
end
|
61
80
|
end
|
@@ -7,15 +7,15 @@ module Tramway
|
|
7
7
|
module_function
|
8
8
|
|
9
9
|
def decorator_class(object_or_array, decorator = nil)
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
10
|
+
raise_error_if_object_empty object_or_array, decorator
|
11
|
+
|
12
|
+
return decorator if decorator.present?
|
13
|
+
|
14
|
+
begin
|
15
|
+
class_name = decorator_class_name(object_or_array)
|
16
|
+
class_name.constantize
|
17
|
+
rescue NameError
|
18
|
+
raise NameError, "You should define #{class_name} decorator class."
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -28,6 +28,16 @@ module Tramway
|
|
28
28
|
|
29
29
|
Tramway::Decorators::NameBuilder.default_decorator_class_name(klass)
|
30
30
|
end
|
31
|
+
|
32
|
+
# :reek:NilCheck { enabled: false }
|
33
|
+
def raise_error_if_object_empty(object_or_array, decorator)
|
34
|
+
return unless object_or_array.blank? && decorator.nil?
|
35
|
+
|
36
|
+
text = 'You should pass object or array that is not empty OR provide a decorator class as a second argument'
|
37
|
+
|
38
|
+
raise ArgumentError, text
|
39
|
+
end
|
40
|
+
# :reek:NilCheck { enabled: true }
|
31
41
|
end
|
32
42
|
end
|
33
43
|
end
|
data/lib/tramway/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tramway
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kalashnikovisme
|
8
8
|
- moshiaan
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2025-01-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: anyway_config
|
@@ -67,6 +67,20 @@ dependencies:
|
|
67
67
|
- - ">="
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: '0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: kaminari
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
70
84
|
- !ruby/object:Gem::Dependency
|
71
85
|
name: rails
|
72
86
|
requirement: !ruby/object:Gem::Requirement
|
@@ -177,7 +191,9 @@ files:
|
|
177
191
|
- app/views/kaminari/_prev_page.html.haml
|
178
192
|
- app/views/tramway/entities/_entity.html.haml
|
179
193
|
- app/views/tramway/entities/index.html.haml
|
194
|
+
- app/views/tramway/layouts/application.html.haml
|
180
195
|
- config/routes.rb
|
196
|
+
- config/tailwind.config.js
|
181
197
|
- lib/rules/turbo_html_attributes_rules.rb
|
182
198
|
- lib/tasks/tramway_tasks.rake
|
183
199
|
- lib/tramway.rb
|
@@ -213,7 +229,7 @@ metadata:
|
|
213
229
|
homepage_uri: https://github.com/purple-magic/tramway
|
214
230
|
source_code_uri: https://github.com/purple-magic/tramway
|
215
231
|
changelog_uri: https://github.com/purple-magic/tramway
|
216
|
-
post_install_message:
|
232
|
+
post_install_message:
|
217
233
|
rdoc_options: []
|
218
234
|
require_paths:
|
219
235
|
- lib
|
@@ -229,7 +245,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
229
245
|
version: '0'
|
230
246
|
requirements: []
|
231
247
|
rubygems_version: 3.4.6
|
232
|
-
signing_key:
|
248
|
+
signing_key:
|
233
249
|
specification_version: 4
|
234
250
|
summary: Tramway Rails Engine
|
235
251
|
test_files: []
|