tramway-admin 1.29.1.5 → 1.31.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 684985c2ee2576e0240cdf2a35308044f98cbac2cf03d68ac45f6c986b7042ea
4
- data.tar.gz: 3c009c10ec87984dea44de3193f37d2bb494f7ffa26e1ecb29e7f0e7fe50cad7
3
+ metadata.gz: 8e527df685599efb7b14fa1ff445ae7f61aea669a1edd406d7a5d127fe2026f6
4
+ data.tar.gz: 41a7ee8ab8836d19122a094784fa3fa3c162e469a005b5f2b7a174f178bc3897
5
5
  SHA512:
6
- metadata.gz: 6cc5247ac2bd3006c58aaf0e3eba492d96a2b95478fe199fe2561e62e25aba4b2aa3fd87a05afd06f93707da3a83616675e6f3f7d2f543a75bf5228335781110
7
- data.tar.gz: f521d26062127bde2bb94fe5be738bac88d098cc79fd18b826f29080916e3b9c2baf05c7bcb30a3499e01d5f464fa763a3065bd0d99bd9d8e5137900e9f1eaa6
6
+ metadata.gz: c6a8ba79872d5a473f77e1fe69e5d7c5d3d710890fd0293d3afbab411a347254c3dc25da2201cc6ad1ea48d9d50146356c2b1b7b5244c2483ff255b088473ea7
7
+ data.tar.gz: 96cc001da48f111185dcd722ca4f61f16f4f08f1668512a6a8aa43d36b24bbeed6f13fc70a4a95bfce0644332ac5f5c30781f486447cee6d57b3c6497a5066c2
data/README.md CHANGED
@@ -99,12 +99,12 @@ 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
108
  end
109
109
  end
110
110
 
@@ -112,6 +112,8 @@ class YourModelDecorator < Tramway::Core::ApplicationDecorator
112
112
  end
113
113
  ```
114
114
 
115
+ **NOTE:** `collections` methods must return array of scopes of `YourModel`. Every collection will be a tab in a list of your model in admin panel.
116
+
115
117
  #### 10. Add inheritance to YourModel
116
118
 
117
119
  *app/models/your_model.rb*
@@ -31,8 +31,13 @@ module Tramway
31
31
  def collections_counts
32
32
  @counts = decorator_class.collections.reduce({}) do |hash, collection|
33
33
  records = model_class.active.send(collection)
34
- records = records.send "#{current_user.role}_scope", current_user.id
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
+ if value.present?
38
+ records = decorator_class.list_filters[filter.to_sym][:query].call(records, value)
39
+ end
40
+ end
36
41
  hash.merge! collection => records.count
37
42
  end
38
43
  end
@@ -44,8 +49,10 @@ module Tramway
44
49
  end
45
50
 
46
51
  def notifications
47
- @notifications ||= Tramway::Admin.notificable_queries&.reduce({}) do |hash, notification|
48
- hash.merge! notification[0] => notification[1].call(current_user)
52
+ if current_admin
53
+ @notifications ||= Tramway::Admin.notificable_queries&.reduce({}) do |hash, notification|
54
+ hash.merge! notification[0] => notification[1].call(current_admin)
55
+ end
49
56
  end
50
57
  @notifications
51
58
  end
@@ -76,7 +83,7 @@ module Tramway
76
83
  end
77
84
 
78
85
  def admin_form_class
79
- "::#{current_user.role.camelize}::#{model_class}Form".constantize
86
+ "::#{current_admin.role.camelize}::#{model_class}Form".constantize
80
87
  end
81
88
 
82
89
  def model_given?
@@ -89,7 +96,7 @@ module Tramway
89
96
  # :tramway, :admin, :application_controller, :form_given, :model_not_included_to_tramway_admin,
90
97
  # model: params[:model]
91
98
  # )
92
- raise "Looks like model #{params[:model]} is not included to tramway-admin for `#{current_user.role}` role. Add it in the `config/initializers/tramway.rb`. This way `Tramway::Admin.set_available_models(#{params[:model]})`"
99
+ # 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]})`"
93
100
  Tramway::Admin.forms.include? params[:form].underscore.sub(%r{^admin/}, '').sub(/_form$/, '')
94
101
  end
95
102
 
@@ -105,12 +112,25 @@ module Tramway
105
112
  check_models_given? :singleton
106
113
  end
107
114
 
115
+ def current_admin
116
+ user = Tramway::User::User.find_by id: session[:admin_id]
117
+ return false unless user
118
+
119
+ Tramway::User::UserDecorator.decorate user
120
+ end
121
+
108
122
  private
109
123
 
110
124
  def check_models_given?(model_type)
111
- models = ::Tramway::Admin.send("#{model_type}_models", role: current_user.role)
125
+ models = ::Tramway::Admin.send("#{model_type}_models", role: current_admin.role)
112
126
  models.any? && params[:model].in?(models.map(&:to_s))
113
127
  end
128
+
129
+ def authenticate_admin!
130
+ if !current_admin && !request.path.in?(['/admin/session/new', '/admin/session'])
131
+ redirect_to '/admin/session/new'
132
+ end
133
+ end
114
134
  end
115
135
  end
116
136
  end
@@ -3,8 +3,14 @@
3
3
  class Tramway::Admin::HasAndBelongsToManyRecordsController < ::Tramway::Admin::ApplicationController
4
4
  def create
5
5
  base_object = params[:model_class].constantize.find params[:object_id]
6
- record_form = params[:form].constantize.new base_object
7
- if record_form.submit params[params[:model_class].underscore]
6
+ form_class = params[:form].constantize
7
+ record_form = form_class.new base_object
8
+ sending_params = if params[params[:model_class].underscore].present?
9
+ params[params[:model_class].underscore]
10
+ else
11
+ params[form_class.associated_as]
12
+ end
13
+ if record_form.submit sending_params
8
14
  redirect_to params[:redirect].present? ? params[:redirect] : record_path(base_object, model: base_object.class)
9
15
  else
10
16
  redirect_to params[:redirect].present? ? params[:redirect] : record_path(base_object, model: base_object.class)
@@ -6,7 +6,12 @@ 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
- records = records.send "#{current_user.role}_scope", current_user.id
9
+ params[:list_filters]&.each do |filter, value|
10
+ if value.present?
11
+ records = decorator_class.list_filters[filter.to_sym][:query].call(records, value)
12
+ end
13
+ end
14
+ records = records.send "#{current_admin.role}_scope", current_admin.id
10
15
  @records = decorator_class.decorate records.page params[:page]
11
16
  end
12
17
 
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Tramway::Admin::SessionsController < ::Tramway::Admin::ApplicationController
4
+ before_action :redirect_if_signed_in, except: :destroy
5
+ skip_before_action :check_available!
6
+ skip_before_action :collections_counts
7
+
8
+ def new
9
+ @session_form = ::Tramway::Auth::SessionForm.new ::Tramway::User::User.new
10
+ end
11
+
12
+ def create
13
+ @session_form = ::Tramway::Auth::SessionForm.new ::Tramway::User::User.active.find_or_initialize_by email: params[:user][:email]
14
+ if @session_form.validate params[:user]
15
+ admin_sign_in @session_form.model
16
+ redirect_to Tramway::Admin::Engine.routes.url_helpers.root_path
17
+ else
18
+ render :new
19
+ end
20
+ end
21
+
22
+ def destroy
23
+ admin_sign_out
24
+ redirect_to '/admin/session/new'
25
+ end
26
+
27
+ private
28
+
29
+ def redirect_if_signed_in
30
+ redirect_to Tramway::Admin::Engine.routes.url_helpers.root_path if current_admin
31
+ end
32
+
33
+ def admin_sign_in(user)
34
+ session[:admin_id] = user.id
35
+ end
36
+
37
+ def admin_sign_out
38
+ session[:admin_id] = nil
39
+ end
40
+ end
@@ -6,7 +6,7 @@ module Tramway::Admin::ActionsHelper
6
6
  association_object,
7
7
  project: (@application_engine || @application.name),
8
8
  model_name: association_object.model.class.name,
9
- role: current_user.role,
9
+ role: current_admin.role,
10
10
  action: :destroy
11
11
  )
12
12
  end
@@ -16,7 +16,7 @@ module Tramway::Admin::ActionsHelper
16
16
  association_object,
17
17
  project: (@application_engine || @application.name),
18
18
  model_name: association_object.model.class.name,
19
- role: current_user.role,
19
+ role: current_admin.role,
20
20
  action: :update
21
21
  )
22
22
  end
@@ -4,7 +4,6 @@ module Tramway
4
4
  module Admin
5
5
  module ApplicationHelper
6
6
  include ::FontAwesome5::Rails::IconHelper
7
- include AuthManagement
8
7
  include AdditionalButtonsBuilder
9
8
  include ::SmartButtons
10
9
  include CasesHelper
@@ -26,6 +25,13 @@ module Tramway
26
25
  end
27
26
  ::Tramway::Admin.available_models_for(@application_engine || @application.name).map(&:to_s).include?(object_class_name) ? :record : :singleton
28
27
  end
28
+
29
+ def current_admin
30
+ user = Tramway::User::User.find_by id: session[:admin_id]
31
+ return false unless user
32
+
33
+ Tramway::User::UserDecorator.decorate user
34
+ end
29
35
  end
30
36
  end
31
37
  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
@@ -7,9 +7,9 @@
7
7
  %button.navbar-toggler.collapsed{ aria: { controls: :navbar, expanded: "false", label: 'Toggle Navigation' }, data: { target: "#navbar", toggle: :collapse }, type: :button }
8
8
  %span.navbar-toggler-icon
9
9
  .navbar-collapse.collapse#navbar
10
- - if signed_in?
10
+ - if current_admin
11
11
  %ul.navbar-nav
12
- - ::Tramway::Admin.navbar_items_for(@application_engine || @application.name, role: current_user.role)&.each do |item|
12
+ - ::Tramway::Admin.navbar_items_for(@application_engine || @application.name, role: current_admin.role)&.each do |item|
13
13
  - case item.keys.first
14
14
  - when Class
15
15
  - model = item.keys.first
@@ -31,7 +31,7 @@
31
31
  = dropdown_model_item model: model, route: ::Tramway::Admin::Engine.routes.url_helpers.records_path(model: model, scope: decorator_class(model).collections.first), pluralize: plural(model.model_name).capitalize
32
32
 
33
33
  %ul.nav.navbar-nav.ml-auto
34
- - if signed_in?
34
+ - if current_admin
35
35
  - if @notifications_count.present?
36
36
  - if @notifications_count > 0
37
37
  %li.nav-item.dropdown.notifications
@@ -50,7 +50,9 @@
50
50
  %span.badge.badge-light
51
51
  = @notifications_count
52
52
  %li.nav-item
53
- = link_to Tramway::Auth::Engine.routes.url_helpers.session_path, method: :delete, class: 'nav-link' do
53
+ -# FIXME url_helpers return with /admin for some reason
54
+ -#= link_to Tramway::Auth::Engine.routes.url_helpers.session_path(model: Tramway::User::User).sub('/admin', ''), method: :delete, class: 'nav-link' do
55
+ = link_to '/admin/sign_out', class: 'nav-link' do
54
56
  = fa_icon 'sign-out-alt'
55
57
  = t('helpers.links.sign_out')
56
58
  - else
@@ -18,9 +18,12 @@
18
18
  %td
19
19
  = record.send attribute
20
20
  %td.actions
21
- = link_to fa_icon('pencil-alt'), edit_current_model_record_path(record.id), class: 'btn btn-warning btn-xs'
22
- = delete_button url: current_model_record_path(record.id), form_options: { class: :smart_button }, button_options: { class: 'btn btn-xs btn-danger' } do
23
- = fa_icon 'trash-alt'
21
+ .row
22
+ &nbsp;&nbsp;&nbsp;
23
+ = link_to fa_icon('pencil-alt'), edit_current_model_record_path(record.id), class: 'btn btn-warning btn-xs'
24
+ &nbsp;&nbsp;
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,15 @@
1
- - if searchable_model?(model_class)
1
+ - if searchable_model?(model_class) || decorator_class(model_class).list_filters.any?
2
2
  .col-md-6
3
3
  .search
4
4
  = form_tag records_path, method: :get do |f|
5
5
  .form-group.text
6
6
  .input-group
7
- = text_field_tag :search, params[:search], class: 'text form-control'
7
+ - if searchable_model?(model_class)
8
+ = text_field_tag :search, params[:search], class: 'text form-control'
8
9
  = hidden_field_tag :model, params[:model]
9
10
  = hidden_field_tag :scope, params[:scope]
10
11
  = hidden_field_tag :filter, params[:filter]
12
+ - decorator_class(model_class).list_filters.each do |filter|
13
+ = select_tag "list_filters[#{filter[0]}]", build_options_for_select(filter[0], filter[1][:select_collection]), include_blank: true, class: 'form-control'
11
14
  .input-group-append
12
15
  = submit_tag t('helpers.actions.search'), class: 'btn btn-primary'
@@ -0,0 +1,9 @@
1
+ - title
2
+ .row
3
+ .col-md-6
4
+ = simple_form_for @session_form.model, url: '/admin/session', method: :post, html: { class: 'form-horizontal' } do |f|
5
+ = f.input :email, as: :string
6
+ = f.input :password
7
+ = hidden_field_tag :model, @session_form.model.class.to_s
8
+ = hidden_field_tag :redirect, Tramway::Admin::Engine.routes.url_helpers.root_path
9
+ = f.button :submit, t('helpers.links.enter'), class: 'btn btn-success'
@@ -1,8 +1,16 @@
1
1
  - if object.class.show_associations.map(&:to_s).include? association.name.to_s
2
+ - association_type = association.class.to_s.split('::').last.sub(/Reflection$/, '').underscore.to_sym
2
3
  %tr
3
4
  %td
4
5
  = model_class.human_attribute_name association.name
5
6
  %hr
6
- = link_to "#{I18n.t('helpers.actions.add')} #{model_class.human_attribute_name(association.name).singularize.downcase}", new_associated_record_path(association: association, object: object, as: object.send("#{association.name}_as")), class: 'btn btn-primary'
7
+ - if association_type != :has_one || !object.send(association.name).present?
8
+ = link_to "#{I18n.t('helpers.actions.add')} #{model_class.human_attribute_name(association.name).singularize.downcase}", new_associated_record_path(association: association, object: object, as: object.send("#{association.name}_as")), class: 'btn btn-primary'
7
9
  %td{ colspan: 2 }
8
- = render 'tramway/admin/shared/show/associations/list', object: object, association: association
10
+ - if association_type.in? [ :has_one, :belongs_to ]
11
+ %table.table.table-striped.table-bordered
12
+ = render 'tramway/admin/shared/show/associations/table_row', object: object, association: association, association_object: object.send(association.name)
13
+ - else
14
+ %table.table.table-striped.table-bordered
15
+ - object.send(association.name)&.each do |association_object|
16
+ = render 'tramway/admin/shared/show/associations/table_row', object: object, association: association, association_object: association_object
@@ -0,0 +1,20 @@
1
+ - association_state_machines = object.send("#{association.name}_state_machines")
2
+ - if (!association_object.is_a?(Array) || !association_object.empty?) && association_object.present?
3
+ %tr{ id: "#{association.name}_#{association_object.id}" }
4
+ %td
5
+ = association_object.id
6
+ %td
7
+ = link_to association_object.name, record_path(association_object.id, model: association.options[:class_name])
8
+ %td
9
+ - association_state_machines.each do |state_method|
10
+ = state_events_buttons association_object, state_method: state_method, model_param_name: :record, controller: 'tramway/admin/records', action: :update, parameters: { redirect: current_model_record_path(object.id), model: association_object.class.model_name }, button_options: { class: :smart_button }
11
+ %td
12
+ - if update_is_available? association_object, object
13
+ = edit_button url: edit_record_path(association_object.id, model: association.options[:class_name], redirect: current_model_record_path(object.id)), button_options: { class: 'btn btn-xs btn-warning edit' } do
14
+ = fa_icon 'pencil-alt'
15
+ - if destroy_is_available? association_object, object
16
+ = delete_button url: record_path(association_object.id, model: association.options[:class_name], redirect: current_model_record_path(object.id)), button_options: { class: 'btn btn-xs btn-danger delete' } do
17
+ = fa_icon 'trash-alt'
18
+ - if habtm_destroy_is_available? association_object, object
19
+ = delete_button url: has_and_belongs_to_many_record_path(association_object.id, model_class: object.model.class, object_id: object.id, form: "Admin::#{object.model.class.to_s.pluralize}::Remove#{association_object.model.class.to_s}Form", redirect: current_model_record_path(object.id)), button_options: { class: 'btn btn-xs btn-danger delete' } do
20
+ = fa_icon 'trash-alt'
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Tramway::Admin::Engine.routes.draw do
4
- mount Tramway::Auth::Engine, at: '/auth'
5
4
  mount Tramway::Export::Engine, at: '/' if defined? Tramway::Export::Engine
6
5
 
7
6
  root to: 'welcome#index'
@@ -9,4 +8,6 @@ Tramway::Admin::Engine.routes.draw do
9
8
  resources :records
10
9
  resource :singleton, only: %i[new create show edit update]
11
10
  resources :has_and_belongs_to_many_records, only: %i[create destroy]
11
+ resource :session, only: %i[new create]
12
+ get 'sign_out', to: 'sessions#destroy'
12
13
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Tramway
4
4
  module Admin
5
- VERSION = '1.29.1.5'
5
+ VERSION = '1.31.0.1'
6
6
  end
7
7
  end
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.29.1.5
4
+ version: 1.31.0.1
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-04-30 00:00:00.000000000 Z
11
+ date: 2020-06-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bootstrap-kaminari-views
@@ -183,6 +183,7 @@ files:
183
183
  - app/controllers/tramway/admin/application_controller.rb
184
184
  - app/controllers/tramway/admin/has_and_belongs_to_many_records_controller.rb
185
185
  - app/controllers/tramway/admin/records_controller.rb
186
+ - app/controllers/tramway/admin/sessions_controller.rb
186
187
  - app/controllers/tramway/admin/singletons_controller.rb
187
188
  - app/controllers/tramway/admin/welcome_controller.rb
188
189
  - app/controllers/tramway/export/application_controller.rb
@@ -207,12 +208,13 @@ files:
207
208
  - app/views/tramway/admin/records/index.html.haml
208
209
  - app/views/tramway/admin/records/new.html.haml
209
210
  - app/views/tramway/admin/records/show.html.haml
211
+ - app/views/tramway/admin/sessions/new.html.haml
210
212
  - app/views/tramway/admin/shared/_show.html.haml
211
213
  - app/views/tramway/admin/shared/errors/server_error.html.haml
212
214
  - app/views/tramway/admin/shared/show/_attribute_tr.html.haml
213
215
  - app/views/tramway/admin/shared/show/associations/_habtm_row.html.haml
214
- - app/views/tramway/admin/shared/show/associations/_list.html.haml
215
216
  - app/views/tramway/admin/shared/show/associations/_row.html.haml
217
+ - app/views/tramway/admin/shared/show/associations/_table_row.html.haml
216
218
  - app/views/tramway/admin/singletons/_form.html.haml
217
219
  - app/views/tramway/admin/singletons/edit.html.haml
218
220
  - app/views/tramway/admin/singletons/new.html.haml
@@ -1,21 +0,0 @@
1
- - association_state_machines = object.send("#{association.name}_state_machines")
2
- %table.table.table-striped.table-bordered
3
- - object.send(association.name)&.each do |association_object|
4
- %tr{ id: "#{association.name}_#{association_object.id}" }
5
- %td
6
- = association_object.id
7
- %td
8
- = link_to association_object.name, record_path(association_object.id, model: association.options[:class_name])
9
- %td
10
- - association_state_machines.each do |state_method|
11
- = state_events_buttons association_object, state_method: state_method, model_param_name: :record, controller: 'tramway/admin/records', action: :update, parameters: { redirect: current_model_record_path(object.id), model: association_object.class.model_name }, button_options: { class: :smart_button }
12
- %td
13
- - if update_is_available? association_object, object
14
- = edit_button url: edit_record_path(association_object.id, model: association.options[:class_name], redirect: current_model_record_path(object.id)), button_options: { class: 'btn btn-xs btn-warning edit' } do
15
- = fa_icon 'pencil-alt'
16
- - if destroy_is_available? association_object, object
17
- = delete_button url: record_path(association_object.id, model: association.options[:class_name], redirect: current_model_record_path(object.id)), button_options: { class: 'btn btn-xs btn-danger delete' } do
18
- = fa_icon 'trash-alt'
19
- - if habtm_destroy_is_available? association_object, object
20
- = delete_button url: has_and_belongs_to_many_record_path(association_object.id, model_class: object.model.class, object_id: object.id, form: "Admin::#{object.model.class.to_s.pluralize}::Remove#{association_object.model.class.to_s}Form", redirect: current_model_record_path(object.id)), button_options: { class: 'btn btn-xs btn-danger delete' } do
21
- = fa_icon 'trash-alt'