tramway-admin 1.30 → 1.32
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 +37 -2
- data/app/assets/stylesheets/tramway/admin/application.sass +11 -0
- data/app/controllers/tramway/admin/application_controller.rb +20 -3
- data/app/controllers/tramway/admin/records_controller.rb +12 -0
- data/app/helpers/tramway/admin/application_helper.rb +1 -0
- data/app/helpers/tramway/admin/records_helper.rb +5 -0
- data/app/views/tramway/admin/records/_list.html.haml +6 -3
- data/app/views/tramway/admin/records/_search.html.haml +27 -11
- data/app/views/tramway/admin/records/index.html.haml +2 -1
- data/lib/tramway/admin/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: da3bc56fc776dfe427a596e31529b9f8c3c6f97db1db373931afb3e113c1ecdd
|
|
4
|
+
data.tar.gz: 4a8f36847d9ec84316bd18fa0633baf3c50177a9f29b4ef847a5c16bb683acfe
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ef3fceeab511ec3eea980f77ce39de35f6447c91e191f79563751704fbd45adb2949619b04eaad84516a952c21ad415a3fbe64efdc6c1540c82bd228ddfa4ff1
|
|
7
|
+
data.tar.gz: b73d51193a4ea7d0ed2810538146bc8154f29e7640a175356b4ab1dc71ef8ce8392908f77eabcf55ae5ad2453218b384d92c9b9336366ea44c31b7cefecedf0d
|
data/README.md
CHANGED
|
@@ -99,12 +99,23 @@ Tramway::Admin.navbar_structure(
|
|
|
99
99
|
|
|
100
100
|
#### 9. Create decorator for models
|
|
101
101
|
|
|
102
|
-
*app/decorators/your_model_decorator.rb
|
|
102
|
+
*app/decorators/your_model_decorator.rb*
|
|
103
103
|
```ruby
|
|
104
104
|
class YourModelDecorator < Tramway::Core::ApplicationDecorator
|
|
105
105
|
class << self
|
|
106
106
|
def collections
|
|
107
|
-
[ :all ]
|
|
107
|
+
[ :all, :scope1, :scope2 ]
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def list_filters
|
|
111
|
+
{
|
|
112
|
+
filter_name: {
|
|
113
|
+
select_collection: filter_collection,
|
|
114
|
+
query: lambda do |list, value|
|
|
115
|
+
list.where some_attribute: value
|
|
116
|
+
end
|
|
117
|
+
}
|
|
118
|
+
}
|
|
108
119
|
end
|
|
109
120
|
end
|
|
110
121
|
|
|
@@ -112,6 +123,12 @@ class YourModelDecorator < Tramway::Core::ApplicationDecorator
|
|
|
112
123
|
end
|
|
113
124
|
```
|
|
114
125
|
|
|
126
|
+
**NOTES:**
|
|
127
|
+
* `collections` method must return array of scopes of `YourModel`. Every collection will be a tab in a list of your model in admin panel
|
|
128
|
+
* `list_filters` method returns hash of filters where:
|
|
129
|
+
* select_collection - collection which will be in the select of filter. It must be compatible with [options_for_select](https://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/options_for_select) method
|
|
130
|
+
* query - some Active Record query which be used as a filter of records
|
|
131
|
+
|
|
115
132
|
#### 10. Add inheritance to YourModel
|
|
116
133
|
|
|
117
134
|
*app/models/your_model.rb*
|
|
@@ -138,6 +155,24 @@ class Admin::YourModelForm < Tramway::Core::ApplicationForm
|
|
|
138
155
|
end
|
|
139
156
|
end
|
|
140
157
|
```
|
|
158
|
+
|
|
159
|
+
### 12. You can add search to your index page
|
|
160
|
+
|
|
161
|
+
Tramway use gem [PgSearch](https://github.com/Casecommons/pg_search`) as search engine
|
|
162
|
+
|
|
163
|
+
Just add `search` method to `YourModel` like this
|
|
164
|
+
|
|
165
|
+
```ruby
|
|
166
|
+
search_by *attributes, **associations # `attributes` and `associations` should be the same syntax as in PgSearch
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Example:
|
|
170
|
+
|
|
171
|
+
```ruby
|
|
172
|
+
class YourModel < Tramway::Core::ApplicationRecord
|
|
173
|
+
search_by :my_attribute, :another_attribute, my_association: [ :my_association_attribute, :another_my_association_attribute ]
|
|
174
|
+
```
|
|
175
|
+
|
|
141
176
|
#### 12. Run server `rails s`
|
|
142
177
|
#### 13. Launch `localhost:3000/admin`
|
|
143
178
|
|
|
@@ -33,6 +33,18 @@ module Tramway
|
|
|
33
33
|
records = model_class.active.send(collection)
|
|
34
34
|
records = records.send "#{current_admin.role}_scope", current_admin.id
|
|
35
35
|
records = records.ransack(params[:filter]).result if params[:filter].present?
|
|
36
|
+
params[:list_filters]&.each do |filter, value|
|
|
37
|
+
case decorator_class.list_filters[filter.to_sym][:type]
|
|
38
|
+
when :select
|
|
39
|
+
records = decorator_class.list_filters[filter.to_sym][:query].call(records, value) if value.present?
|
|
40
|
+
when :dates
|
|
41
|
+
begin_date = params[:list_filters][filter.to_sym][:begin_date]
|
|
42
|
+
end_date = params[:list_filters][filter.to_sym][:end_date]
|
|
43
|
+
if begin_date.present? && end_date.present?
|
|
44
|
+
records = decorator_class.list_filters[filter.to_sym][:query].call(records, begin_date, end_date) if value.present?
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
36
48
|
hash.merge! collection => records.count
|
|
37
49
|
end
|
|
38
50
|
end
|
|
@@ -91,8 +103,10 @@ module Tramway
|
|
|
91
103
|
# :tramway, :admin, :application_controller, :form_given, :model_not_included_to_tramway_admin,
|
|
92
104
|
# model: params[:model]
|
|
93
105
|
# )
|
|
94
|
-
#raise "Looks like model #{params[:model]} is not included to tramway-admin for `#{current_admin.role}` role. Add it in the `config/initializers/tramway.rb`. This way `Tramway::Admin.set_available_models(#{params[:model]})`"
|
|
95
|
-
|
|
106
|
+
# raise "Looks like model #{params[:model]} is not included to tramway-admin for `#{current_admin.role}` role. Add it in the `config/initializers/tramway.rb`. This way `Tramway::Admin.set_available_models(#{params[:model]})`"
|
|
107
|
+
if params[:form].present?
|
|
108
|
+
Tramway::Admin.forms.include? params[:form].underscore.sub(%r{^admin/}, '').sub(/_form$/, '')
|
|
109
|
+
end
|
|
96
110
|
end
|
|
97
111
|
|
|
98
112
|
def available_scope_given?
|
|
@@ -110,6 +124,7 @@ module Tramway
|
|
|
110
124
|
def current_admin
|
|
111
125
|
user = Tramway::User::User.find_by id: session[:admin_id]
|
|
112
126
|
return false unless user
|
|
127
|
+
|
|
113
128
|
Tramway::User::UserDecorator.decorate user
|
|
114
129
|
end
|
|
115
130
|
|
|
@@ -121,7 +136,9 @@ module Tramway
|
|
|
121
136
|
end
|
|
122
137
|
|
|
123
138
|
def authenticate_admin!
|
|
124
|
-
|
|
139
|
+
if !current_admin && !request.path.in?(['/admin/session/new', '/admin/session'])
|
|
140
|
+
redirect_to '/admin/session/new'
|
|
141
|
+
end
|
|
125
142
|
end
|
|
126
143
|
end
|
|
127
144
|
end
|
|
@@ -6,6 +6,18 @@ class Tramway::Admin::RecordsController < ::Tramway::Admin::ApplicationControlle
|
|
|
6
6
|
records = model_class.active.order(id: :desc).send scope
|
|
7
7
|
records = records.full_text_search params[:search] if params[:search].present?
|
|
8
8
|
records = records.ransack(params[:filter]).result if params[:filter].present?
|
|
9
|
+
params[:list_filters]&.each do |filter, value|
|
|
10
|
+
case decorator_class.list_filters[filter.to_sym][:type]
|
|
11
|
+
when :select
|
|
12
|
+
records = decorator_class.list_filters[filter.to_sym][:query].call(records, value) if value.present?
|
|
13
|
+
when :dates
|
|
14
|
+
begin_date = params[:list_filters][filter.to_sym][:begin_date]
|
|
15
|
+
end_date = params[:list_filters][filter.to_sym][:end_date]
|
|
16
|
+
if begin_date.present? && end_date.present?
|
|
17
|
+
records = decorator_class.list_filters[filter.to_sym][:query].call(records, begin_date, end_date) if value.present?
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
9
21
|
records = records.send "#{current_admin.role}_scope", current_admin.id
|
|
10
22
|
@records = decorator_class.decorate records.page params[:page]
|
|
11
23
|
end
|
|
@@ -47,6 +47,11 @@ module Tramway::Admin
|
|
|
47
47
|
model_class.methods.include? :full_text_search
|
|
48
48
|
end
|
|
49
49
|
|
|
50
|
+
def build_options_for_select(name, collection)
|
|
51
|
+
selected_value = params[:list_filters].present? ? params[:list_filters][name] : nil
|
|
52
|
+
options_for_select(collection, selected_value)
|
|
53
|
+
end
|
|
54
|
+
|
|
50
55
|
def admin_index_path_of_model(model_class, tab, filter)
|
|
51
56
|
if tab
|
|
52
57
|
records_path model: model_class, filter: filter, scope: tab
|
|
@@ -18,9 +18,12 @@
|
|
|
18
18
|
%td
|
|
19
19
|
= record.send attribute
|
|
20
20
|
%td.actions
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
= fa_icon
|
|
21
|
+
.row
|
|
22
|
+
|
|
23
|
+
= link_to fa_icon('pencil-alt'), edit_current_model_record_path(record.id), class: 'btn btn-warning btn-xs'
|
|
24
|
+
|
|
25
|
+
= delete_button url: current_model_record_path(record.id), form_options: { class: :smart_button }, button_options: { class: 'btn btn-xs btn-danger' } do
|
|
26
|
+
= fa_icon 'trash-alt'
|
|
24
27
|
%br
|
|
25
28
|
%br
|
|
26
29
|
.btn-group{ data: { toggle: :buttons } }
|
|
@@ -1,12 +1,28 @@
|
|
|
1
|
-
- if searchable_model?(model_class)
|
|
2
|
-
.col-md-
|
|
1
|
+
- if searchable_model?(model_class) || decorator_class(model_class).list_filters.any?
|
|
2
|
+
.col-md-8
|
|
3
3
|
.search
|
|
4
|
-
= form_tag records_path, method: :get do |f|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
4
|
+
= form_tag records_path, class: 'form-inline', method: :get do |f|
|
|
5
|
+
- if searchable_model?(model_class)
|
|
6
|
+
= text_field_tag :search, params[:search], class: 'text form-control'
|
|
7
|
+
= hidden_field_tag :model, params[:model]
|
|
8
|
+
= hidden_field_tag :scope, params[:scope]
|
|
9
|
+
= hidden_field_tag :filter, params[:filter]
|
|
10
|
+
- decorator_class(model_class).list_filters.each_slice(3) do |slice|
|
|
11
|
+
.row-fluid.filters
|
|
12
|
+
- slice.each do |filter|
|
|
13
|
+
.col-md-4
|
|
14
|
+
= label_tag t("admin.filters.#{model_class.to_s.underscore}.#{filter[0]}")
|
|
15
|
+
- case filter[1][:type]
|
|
16
|
+
- when :select
|
|
17
|
+
= select_tag "list_filters[#{filter[0]}]", build_options_for_select(filter[0], filter[1][:select_collection]), include_blank: true, class: 'form-control'
|
|
18
|
+
- when :dates
|
|
19
|
+
= text_field_tag "list_filters[#{filter[0]}][begin_date]", '', class: 'form-control', id: 'filter_datepicker_begin_date', value: params[:list_filters][filter[0]][:begin_date]
|
|
20
|
+
= text_field_tag "list_filters[#{filter[0]}][end_date]", '', class: 'form-control', id: 'filter_datepicker_end_date', value: params[:list_filters][filter[0]][:end_date]
|
|
21
|
+
:javascript
|
|
22
|
+
$(function () {
|
|
23
|
+
$('#filter_datepicker_begin_date').datepicker();
|
|
24
|
+
$('#filter_datepicker_end_date').datepicker();
|
|
25
|
+
});
|
|
26
|
+
.row-fluid.filters
|
|
27
|
+
.col-md-4.offset-md-8.submit
|
|
28
|
+
= submit_tag t('helpers.actions.search'), class: 'btn btn-primary'
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
- tabs = get_collection
|
|
6
6
|
.page-header
|
|
7
7
|
.row
|
|
8
|
-
.
|
|
8
|
+
- search_render_show = searchable_model?(model_class) || decorator_class(model_class).list_filters.any?
|
|
9
|
+
%div{ class: "col-md-#{search_render_show ? 4 : 12}" }
|
|
9
10
|
%h1
|
|
10
11
|
= current_title
|
|
11
12
|
= link_to fa_icon(:plus), new_current_model_record_path, class: 'btn btn-primary'
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tramway-admin
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: '1.
|
|
4
|
+
version: '1.32'
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Pavel Kalashnikov
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-
|
|
11
|
+
date: 2020-06-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bootstrap-kaminari-views
|