tramway-admin 1.29.1.5 → 1.31.0.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 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'