ditty 0.9.1 → 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/.env.test +2 -0
  3. data/.gitignore +1 -0
  4. data/.rubocop.yml +23 -4
  5. data/.travis.yml +2 -7
  6. data/Gemfile.ci +0 -15
  7. data/ditty.gemspec +19 -15
  8. data/lib/ditty.rb +2 -2
  9. data/lib/ditty/cli.rb +5 -0
  10. data/lib/ditty/components/ditty.rb +4 -7
  11. data/lib/ditty/controllers/application_controller.rb +6 -5
  12. data/lib/ditty/controllers/audit_logs_controller.rb +2 -0
  13. data/lib/ditty/controllers/auth_controller.rb +5 -2
  14. data/lib/ditty/controllers/component_controller.rb +3 -3
  15. data/lib/ditty/controllers/user_login_traits_controller.rb +28 -1
  16. data/lib/ditty/controllers/users_controller.rb +3 -2
  17. data/lib/ditty/db.rb +4 -3
  18. data/lib/ditty/emails/base.rb +32 -30
  19. data/lib/ditty/generators/crud_generator.rb +51 -41
  20. data/lib/ditty/generators/project_generator.rb +1 -0
  21. data/lib/ditty/helpers/pundit.rb +4 -4
  22. data/lib/ditty/helpers/response.rb +6 -11
  23. data/lib/ditty/helpers/views.rb +21 -3
  24. data/lib/ditty/listener.rb +1 -1
  25. data/lib/ditty/models/base.rb +5 -0
  26. data/lib/ditty/models/identity.rb +7 -7
  27. data/lib/ditty/models/user.rb +9 -1
  28. data/lib/ditty/policies/user_policy.rb +1 -1
  29. data/lib/ditty/services/authentication.rb +19 -9
  30. data/lib/ditty/services/email.rb +13 -13
  31. data/lib/ditty/services/logger.rb +26 -20
  32. data/lib/ditty/services/pagination_wrapper.rb +7 -5
  33. data/lib/ditty/services/settings.rb +7 -6
  34. data/lib/ditty/tasks/ditty.rake +2 -1
  35. data/lib/ditty/templates/application.rb +1 -1
  36. data/lib/ditty/templates/config.ru +2 -2
  37. data/lib/ditty/templates/controller.rb.erb +7 -1
  38. data/{public → lib/ditty/templates/public}/browserconfig.xml +0 -0
  39. data/{public → lib/ditty/templates/public}/css/styles.css +0 -0
  40. data/lib/ditty/templates/public/favicon.ico +0 -0
  41. data/{public → lib/ditty/templates/public}/images/apple-icon.png +0 -0
  42. data/{public → lib/ditty/templates/public}/images/favicon-16x16.png +0 -0
  43. data/{public → lib/ditty/templates/public}/images/favicon-32x32.png +0 -0
  44. data/{public → lib/ditty/templates/public}/images/launcher-icon-1x.png +0 -0
  45. data/{public → lib/ditty/templates/public}/images/launcher-icon-2x.png +0 -0
  46. data/{public → lib/ditty/templates/public}/images/launcher-icon-4x.png +0 -0
  47. data/{public → lib/ditty/templates/public}/images/mstile-150x150.png +0 -0
  48. data/{public → lib/ditty/templates/public}/images/safari-pinned-tab.svg +0 -0
  49. data/{public → lib/ditty/templates/public}/js/scripts.js +0 -0
  50. data/{public/manifest.json → lib/ditty/templates/public/manifest.json.erb} +2 -2
  51. data/lib/ditty/templates/settings.yml.erb +1 -0
  52. data/lib/ditty/templates/spec_helper.rb +1 -1
  53. data/lib/ditty/templates/views/display.haml.tt +1 -1
  54. data/lib/ditty/templates/views/edit.haml.tt +1 -1
  55. data/lib/ditty/templates/views/index.haml.tt +1 -1
  56. data/lib/ditty/templates/views/new.haml.tt +1 -1
  57. data/lib/ditty/version.rb +1 -1
  58. data/spec/ditty/api_spec.rb +1 -1
  59. data/spec/ditty/emails/base_spec.rb +3 -3
  60. data/spec/ditty/emails/forgot_password_spec.rb +3 -2
  61. data/spec/ditty/models/user_spec.rb +3 -3
  62. data/spec/ditty/services/logger_spec.rb +7 -6
  63. data/spec/ditty/services/settings_spec.rb +2 -2
  64. data/spec/factories.rb +4 -4
  65. data/spec/spec_helper.rb +5 -1
  66. data/views/403.haml +1 -1
  67. data/views/500.haml +11 -0
  68. data/views/audit_logs/index.haml +12 -11
  69. data/views/auth/forgot_password.haml +29 -24
  70. data/views/auth/ldap.haml +1 -1
  71. data/views/auth/login.haml +3 -2
  72. data/views/auth/register.haml +3 -2
  73. data/views/auth/reset_password.haml +36 -19
  74. data/views/blank.haml +1 -0
  75. data/views/embedded.haml +17 -11
  76. data/views/layout.haml +16 -8
  77. data/views/partials/actions.haml +15 -14
  78. data/views/partials/filter_control.haml +1 -1
  79. data/views/partials/footer.haml +10 -2
  80. data/views/partials/form_tag.haml +1 -1
  81. data/views/partials/navitems.haml +25 -27
  82. data/views/partials/pager.haml +44 -25
  83. data/views/partials/search.haml +14 -9
  84. data/views/partials/sidebar.haml +2 -2
  85. data/views/partials/sort_ui.haml +2 -0
  86. data/views/partials/timespan_selector.haml +64 -0
  87. data/views/partials/topbar.haml +0 -15
  88. data/views/partials/user_associations.haml +32 -0
  89. data/views/quick_start.haml +23 -0
  90. data/views/roles/display.haml +3 -3
  91. data/views/roles/edit.haml +1 -1
  92. data/views/roles/index.haml +2 -2
  93. data/views/roles/new.haml +1 -1
  94. data/views/user_login_traits/display.haml +1 -1
  95. data/views/user_login_traits/edit.haml +1 -1
  96. data/views/user_login_traits/index.haml +23 -25
  97. data/views/user_login_traits/new.haml +1 -1
  98. data/views/users/display.haml +5 -5
  99. data/views/users/edit.haml +1 -1
  100. data/views/users/index.haml +5 -5
  101. data/views/users/login_traits.haml +2 -2
  102. data/views/users/new.haml +1 -1
  103. data/views/users/profile.haml +4 -4
  104. data/views/users/user.haml +1 -1
  105. metadata +116 -54
@@ -1,26 +1,45 @@
1
1
  %nav{"aria-label" => "Page navigation"}
2
- - if list.pagination_record_count > 0
3
- %p.text-center Showing #{list.current_page_record_range} of #{list.pagination_record_count} records
4
- %ul.pagination.justify-content-center
5
- - if list.first_page?
6
- %li.page-item.disabled
7
- %span.page-link First
8
- %li.page-item.disabled
9
- %span.page-link Previous
10
- - else
11
- %li.page-item
12
- %a.page-link{href: first_link} First
13
- %li.page-item
14
- %a.page-link{href: prev_link} Previous
15
- - if list.last_page?
16
- %li.page-item.disabled
17
- %span.page-link Next
18
- %li.page-item.disabled
19
- %span.page-link Last
20
- - else
21
- %li.page-item
22
- %a.page-link{href: next_link} Next
23
- %li.page-item
24
- %a.page-link{href: last_link} Last
25
- - else
26
- %p.text-center No records to show
2
+ .row
3
+ .col-sm-12.col-md-6
4
+ %p.my-2
5
+ - if list.pagination_record_count > 0
6
+ Showing #{list.current_page_record_range} of #{list.pagination_record_count} records
7
+ - else
8
+ %p.text-center No records to show
9
+ .col-sm-12.col-md-6
10
+ - if list.pagination_record_count > 0
11
+ %ul.pagination.justify-content-end
12
+ - if list.first_page?
13
+ %li.page-item.disabled
14
+ %span.page-link First
15
+ %li.page-item.disabled
16
+ %span.page-link Previous
17
+ - else
18
+ %li.page-item
19
+ %a.page-link{ href: first_link } First
20
+ %li.page-item
21
+ %a.page-link{ href: prev_link } Previous
22
+ %li.page-item
23
+ .dropdown
24
+ %button.page-link.dropdown-toggle{ type: 'button', id: 'dropdownMenuButton', 'data-toggle': 'dropdown', 'aria-haspopup': 'true', 'aria-expanded': 'false' }
25
+ = params[:count] || 10
26
+ .dropdown-menu
27
+ %a.dropdown-item{ href: "#{base_path}?#{query_string(count: 10)}" } 10
28
+ %a.dropdown-item{ href: "#{base_path}?#{query_string(count: 25)}" } 25
29
+ %a.dropdown-item{ href: "#{base_path}?#{query_string(count: 50)}" } 50
30
+ %a.dropdown-item{ href: "#{base_path}?#{query_string(count: 100)}" } 100
31
+ - if list.last_page?
32
+ %li.page-item.disabled
33
+ %span.page-link Next
34
+ %li.page-item.disabled
35
+ %span.page-link Last
36
+ - else
37
+ %li.page-item
38
+ %a.page-link{ href: next_link } Next
39
+ %li.page-item
40
+ %a.page-link{ href: last_link } Last
41
+ %li
42
+  
43
+ %li
44
+ %a.page-link{ href: "#{base_path}/.csv?#{URI.encode_www_form(params.merge(count: 'all'))}" }
45
+ Export
@@ -1,20 +1,25 @@
1
- - if self.class.const_defined?(:SEARCHABLE) || self.class.const_defined?(:FILTERS)
1
+ - if self.class.const_defined?(:SEARCHABLE) && SEARCHABLE.count.positive? || self.class.const_defined?(:FILTERS) && FILTERS.count.positive?
2
2
  = form_tag(base_path, form_verb: :get, attributes: { class: '' }) do
3
- - if self.class.const_defined?(:SEARCHABLE)
3
+ - if self.class.const_defined?(:SEARCHABLE) && SEARCHABLE.count.positive?
4
4
  .form-group
5
5
  .input-group
6
6
  %input.form-control{ name: 'q', type: 'text', placeholder: 'Search...', value: params[:q] }
7
7
  .input-group-btn
8
8
  %button.btn.btn-primary{ type: 'submit' }
9
9
  %span.fa.fa-search
10
- - if self.class.const_defined? :FILTERS
10
+ - if self.class.const_defined?(:FILTERS) && FILTERS.count.positive?
11
11
  .input-group-btn
12
12
  %button.btn.btn-secondary{ type: 'button', :'data-toggle' => 'collapse', :'data-target' => '#filter-form', :'aria-expanded' => 'false', :'aria-controls' => '#filter-form'}
13
13
  %span.fa.fa-arrow-down
14
14
 
15
- - if self.class.const_defined?(:FILTERS)
16
- #filter-form.row{ class: self.class.const_defined?(:SEARCHABLE) ? 'collapse' : '' }
17
- - FILTERS.each do |filter|
18
- = filter_control(filter, filters: FILTERS.count)
19
- - unless self.class.const_defined?(:SEARCHABLE)
20
- %button.btn.btn-secondary{ type: 'submit'} Go
15
+ - if self.class.const_defined?(:FILTERS) && FILTERS.count.positive?
16
+ #filter-form{ class: self.class.const_defined?(:SEARCHABLE) && SEARCHABLE.count.positive? ? 'collapse' : '' }
17
+ .card.card-default.mb-2
18
+ .card-body
19
+ .row
20
+ - FILTERS.each do |filter|
21
+ = filter_control(filter, filters: FILTERS.count)
22
+ - unless self.class.const_defined?(:SEARCHABLE) && SEARCHABLE.count.positive?
23
+ .form-group
24
+ %label
25
+ %button.form-control.btn.btn-secondary{ type: 'submit'} Go
@@ -3,12 +3,12 @@
3
3
  / Sidebar - Brand
4
4
  %a.sidebar-brand.d-flex.align-items-center.justify-content-center{ href: config('ditty.home_page', settings.map_path || '/') }
5
5
  .sidebar-brand-icon.rotate-n-15
6
- %i.fas.fa-laugh-wink
6
+ %i.fas{ class: config('ditty.brand-icon', 'fa-laugh-wink') }
7
7
  .sidebar-brand-text.mx-3
8
8
  = config('ditty.title', 'Ditty')
9
9
 
10
- / Divider
11
10
  %hr.sidebar-divider.my-0
11
+
12
12
  = haml :'partials/navitems'
13
13
 
14
14
  .text-center.d-none.d-md-inline
@@ -0,0 +1,2 @@
1
+ %a{ href: "#{base_path}?#{sort_query(field)}" }
2
+ %i.fa{ class: sort_icon(field) }
@@ -0,0 +1,64 @@
1
+ - if defined?(context)
2
+ - if context.interval
3
+ %li.nav-item.dropdown.no-arrow
4
+ %a#intervalDropdown.nav-link.dropdown-toggle{ href: '#', role: 'button', 'aria-haspopup': 'true', 'area-expanded': 'false', 'data-toggle': 'dropdown' }
5
+ %span.mr-2.d-none.d-lg-inline.text-gray-600
6
+ Interval /
7
+ %strong
8
+ = context.interval
9
+ .dropdown-menu.dropdown-menu-right.shadow.animated--grow-in{ 'aria-labelledby': 'intervalDropdown' }
10
+ %a.dropdown-item{ href: "?#{URI.encode_www_form(and_params.merge(interval: '1m'))}", class: context.interval == '1m' ? 'active' : '' }
11
+ 1 Minute
12
+ %a.dropdown-item{ href: "?#{URI.encode_www_form(and_params.merge(interval: '5m'))}", class: context.interval == '5m' ? 'active' : '' }
13
+ 5 Minutes
14
+ %a.dropdown-item{ href: "?#{URI.encode_www_form(and_params.merge(interval: '15m'))}", class: context.interval == '15m' ? 'active' : '' }
15
+ 15 Minutes
16
+ .dropdown-divider
17
+ %a.dropdown-item{ href: "?#{URI.encode_www_form(and_params.merge(interval: '1h'))}", class: context.interval == '1h' ? 'active' : '' }
18
+ 1 Hour
19
+ %a.dropdown-item{ href: "?#{URI.encode_www_form(and_params.merge(interval: '3h'))}", class: context.interval == '3h' ? 'active' : '' }
20
+ 3 Hours
21
+ %a.dropdown-item{ href: "?#{URI.encode_www_form(and_params.merge(interval: '6h'))}", class: context.interval == '6h' ? 'active' : '' }
22
+ 6 Hours
23
+ .dropdown-divider
24
+ %a.dropdown-item{ href: "?#{URI.encode_www_form(and_params.merge(interval: '1d'))}", class: context.interval == '1d' ? 'active' : '' }
25
+ 1 Day
26
+ %a.dropdown-item{ href: "?#{URI.encode_www_form(and_params.merge(interval: '2d'))}", class: context.interval == '2d' ? 'active' : '' }
27
+ 2 Days
28
+ %a.dropdown-item{ href: "?#{URI.encode_www_form(and_params.merge(interval: '1w'))}", class: context.interval == '1w' ? 'active' : '' }
29
+ 1 Week
30
+
31
+ - if context.timespan
32
+ %li.nav-item.dropdown.no-arrow
33
+ %a#timespanDropdown.nav-link.dropdown-toggle{ href: '#', role: 'button', 'aria-haspopup': 'true', 'area-expanded': 'false', 'data-toggle': 'dropdown' }
34
+ %span.mr-2.d-none.d-lg-inline.text-gray-600
35
+ Timespan /
36
+ %strong
37
+ = context.timespan.split('/').first
38
+ .dropdown-menu.dropdown-menu-right.shadow.animated--grow-in{ 'aria-labelledby': 'timespanDropdown' }
39
+ %a.dropdown-item{ href: "?#{URI.encode_www_form(and_params.merge(timespan: '1h', interval: ''))}", class: context.timespan == '1h' ? 'active' : '' }
40
+ %i.fas.fa-chevron-right.fa-sm.fa-fw.mr-2.text-gray-400
41
+ 1 Hour
42
+ %a.dropdown-item{ href: "?#{URI.encode_www_form(and_params.merge(timespan: '1d', interval: ''))}", class: context.timespan == '1d' ? 'active' : '' }
43
+ %i.fas.fa-chevron-right.fa-sm.fa-fw.mr-2.text-gray-400
44
+ 1 Day
45
+ .dropdown-divider
46
+ %a.dropdown-item{ href: "?#{URI.encode_www_form(and_params.merge(timespan: '1w/d', interval: ''))}", class: context.timespan == '1w/d' ? 'active' : '' }
47
+ %i.fas.fa-chevron-right.fa-sm.fa-fw.mr-2.text-gray-400
48
+ 1 Week
49
+ %a.dropdown-item{ href: "?#{URI.encode_www_form(and_params.merge(timespan: '2w/d', interval: ''))}", class: context.timespan == '2w/d' ? 'active' : '' }
50
+ %i.fas.fa-chevron-right.fa-sm.fa-fw.mr-2.text-gray-400
51
+ 2 Weeks
52
+ %a.dropdown-item{ href: "?#{URI.encode_www_form(and_params.merge(timespan: '1M/d', interval: ''))}", class: context.timespan == '1M/d' ? 'active' : '' }
53
+ %i.fas.fa-chevron-right.fa-sm.fa-fw.mr-2.text-gray-400
54
+ 1 Month
55
+ .dropdown-divider
56
+ %a.dropdown-item{ href: "?#{URI.encode_www_form(and_params.merge(timespan: '3M/d', interval: ''))}", class: context.timespan == '3M/d' ? 'active' : '' }
57
+ %i.fas.fa-chevron-right.fa-sm.fa-fw.mr-2.text-gray-400
58
+ 3 Months
59
+ %a.dropdown-item{ href: "?#{URI.encode_www_form(and_params.merge(timespan: '6M/d', interval: ''))}", class: context.timespan == '6M/d' ? 'active' : '' }
60
+ %i.fas.fa-chevron-right.fa-sm.fa-fw.mr-2.text-gray-400
61
+ 6 Months
62
+ %a.dropdown-item{ href: "?#{URI.encode_www_form(and_params.merge(timespan: '1y/d', interval: ''))}", class: context.timespan == '1y/d' ? 'active' : '' }
63
+ %i.fas.fa-chevron-right.fa-sm.fa-fw.mr-2.text-gray-400
64
+ 1 Year
@@ -1,18 +1,3 @@
1
- / Logout Modal
2
- #logoutModal.modal.fade{ tabindex: -1, role: 'dialog', 'aria-hidden': 'true' }
3
- .modal-dialog{ role: 'document' }
4
- .modal-content
5
- .modal-header
6
- %h5.modal-title Ready to Leave?
7
- %button.close{ type: 'button', 'data-dismiss': 'modal', 'aria-label': 'Close' }
8
- %span{ 'aria-hidden': 'true' } ×
9
- .modal-body
10
- Select "Logout" below if you are ready to end your current session.
11
- .modal-footer
12
- %button.btn.btn-secondary{ type: 'button', 'data-dismiss': 'modal' } Cancel
13
- = delete_form_tag("#{settings.map_path}/auth") do
14
- %button.btn.btn-primary{ type: 'submit' } Logout
15
-
16
1
  %nav.navbar.navbar-expand.navbar-light.bg-white.topbar.mb-4.static-top.shadow
17
2
  / Sidebar Toggle
18
3
  %button#sidebarToggleTop.btn.btn-link.d-md-none.rounded-circle.mr-3
@@ -0,0 +1,32 @@
1
+ - group = entity.class.to_s.demodulize.underscore
2
+ %table.table.mb-0
3
+ %tbody
4
+ - if entity.users.count.positive?
5
+ - entity.users.each do |user|
6
+ %tr
7
+ %td
8
+ - if policy(user).read?
9
+ %a{ href: "#{settings.map_path}/users/#{user.id}" }
10
+ = user.username
11
+ - else
12
+ = user.username
13
+ %td.text-right
14
+ = delete_form_tag "#{base_path}/#{entity.display_id}/users/#{user.id}" do
15
+ %button.btn.btn-danger.btn-sm{ type: 'submit' } ×
16
+ - else
17
+ %tr
18
+ %td{ colspan: 2 } No Users Associated
19
+ %tr
20
+ %td{ colspan: 2 }
21
+ - users = user_options.select { |k, v| entity.users.map(&:id).include?(k) == false }
22
+ - if users && users.count.positive?
23
+ = new_form_tag "#{base_path}/#{entity.display_id}/users" do
24
+ .input-group
25
+ %select.form-control{ name: "#{group}[user_id]", id: 'user_id' }
26
+ %option{ value: '' } Select User
27
+ - users.each do |key, value|
28
+ %option{ value: key }= value
29
+ %span.input-group-append
30
+ %button.btn.btn-primary{ type: 'submit' } Add User
31
+ - else
32
+ No Users available to link
@@ -0,0 +1,23 @@
1
+ %link{ rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.20.0/themes/prism-okaidia.min.css' }
2
+
3
+ .row.mb-4
4
+ .col-2
5
+ .col-8
6
+ .card.card-default.border-left-dark.shadow.h-100
7
+ %h4.card-header Run on a folder
8
+ .card-body
9
+ %pre
10
+ %code.lang-shell
11
+ :preserve
12
+ docker run -d -e ELASTICSEARCH_HOSTS=192.168.1.200:9200 \
13
+ --volume=/var/log/nginx/:/usr/share/incoming/ \
14
+ hackerplanet/requestd-filebeat:latest
15
+ .card.card-default.border-left-dark.shadow.h-100
16
+ %h4.card-header Run on a single file
17
+ .card-body
18
+ %pre
19
+ %code.lang-shell
20
+ :preserve
21
+ docker run -d -e ELASTICSEARCH_HOSTS=elastic.hackerpla.net:9200 \
22
+ --volume=/var/log/nginx/access.log:/usr/share/incoming/access.log \
23
+ hackerplanet/requestd-filebeat:latest
@@ -1,7 +1,7 @@
1
1
  .row.mb-4
2
2
  .col-md-2
3
3
  .col-md-8
4
- .card.card-default
4
+ .card.card-default.shadow
5
5
  .card-body
6
6
  %p.description
7
7
  %label Name:
@@ -22,10 +22,10 @@
22
22
  .row
23
23
  .col-md-2
24
24
  .col-md-8
25
- .card.card-default
25
+ .card.card-default.shadow
26
26
  .card-body
27
27
  %h4.card-title Included Roles
28
- %table.table.table-striped
28
+ %table.table.table-striped.mb-0
29
29
  %tbody
30
30
  - if entity.descendants.count > 0
31
31
  - entity.descendants.each do |role|
@@ -1,7 +1,7 @@
1
1
  .row
2
2
  .col-md-2
3
3
  .col-md-8
4
- .card
4
+ .card.card-default.shadow
5
5
  .card-body
6
6
  = edit_form_tag "#{base_path}/#{entity.display_id}" do
7
7
  = haml :'roles/form', locals: { entity: entity }
@@ -4,7 +4,7 @@
4
4
  %table.table.table-striped.table-bordered.table-hover
5
5
  %thead.thead-dark
6
6
  %tr
7
- %th Name
7
+ %th= "Name#{sort_ui(:name)}"
8
8
  %th Parent
9
9
  %th
10
10
  %tbody
@@ -24,4 +24,4 @@
24
24
  %td.text-center{ colspan: 3 } No Roles
25
25
 
26
26
  - if list.count > 0
27
- =pagination(list, base_path)
27
+ = pagination(list, base_path)
data/views/roles/new.haml CHANGED
@@ -1,7 +1,7 @@
1
1
  .row
2
2
  .col-md-2
3
3
  .col-md-8
4
- .card.card-default
4
+ .card.card-default.shadow
5
5
  .card-body
6
6
  = new_form_tag base_path do
7
7
  = haml :'roles/form', locals: { entity: entity }
@@ -1,7 +1,7 @@
1
1
  .row
2
2
  .col-md-2
3
3
  .col-md-8
4
- .card.card-default
4
+ .card.card-default.shadow
5
5
  .card-body
6
6
  %p.description
7
7
  %label User:
@@ -1,7 +1,7 @@
1
1
  .row
2
2
  .col-md-2
3
3
  .col-md-8
4
- .card.card-default
4
+ .card.card-default.shadow
5
5
  .card-body
6
6
  = edit_form_tag "#{base_path}/#{entity.display_id}" do
7
7
  = haml :'user_login_traits/form', locals: { entity: entity }
@@ -1,30 +1,28 @@
1
1
  .row
2
2
  .col-md-12
3
- .card.card-default
4
- .card-body
5
- = haml :'partials/search'
6
- %table.table.table-striped
7
- %thead.thead-dark
8
- %tr
9
- %th User
10
- %th IP Address
11
- %th Device
12
- %th Platform
13
- %th Browser
14
- %th Last Seen
15
- %tbody
16
- - if list.count.positive?
17
- - list.all.each do |entity|
18
- %tr
19
- %td= entity.user&.email || 'Unknown'
20
- %td
21
- %a{ href: "#{base_path}/#{entity.display_id}" }= entity.ip_address || 'Unknown'
22
- %td= entity.device || 'Unknown'
23
- %td= entity.platform || 'Unknown'
24
- %td= entity.browser || 'Unknown'
25
- %td= entity.updated_at
26
- - else
3
+ = haml :'partials/search'
4
+ %table.table.table-striped.table-bordered.table-hover
5
+ %thead.thead-dark
6
+ %tr
7
+ %th= "User #{sort_ui(:user_id)}"
8
+ %th= "IP Address #{sort_ui(:ip_address)}"
9
+ %th= "Device #{sort_ui(:device)}"
10
+ %th= "Platform #{sort_ui(:platform)}"
11
+ %th= "Browser #{sort_ui(:browser)}"
12
+ %th= "Last Seen #{sort_ui(:updated_at)}"
13
+ %tbody
14
+ - if list.count.positive?
15
+ - list.all.each do |entity|
27
16
  %tr
28
- %td.text-center{ colspan: 6 } No records
17
+ %td= entity.user&.email || 'Unknown'
18
+ %td
19
+ %a{ href: "#{base_path}/#{entity.display_id}" }= entity.ip_address || 'Unknown'
20
+ %td= entity.device || 'Unknown'
21
+ %td= entity.platform || 'Unknown'
22
+ %td= entity.browser || 'Unknown'
23
+ %td= entity.updated_at
24
+ - else
25
+ %tr
26
+ %td.text-center{ colspan: 6 } No records
29
27
 
30
28
  =pagination(list, base_path)
@@ -1,7 +1,7 @@
1
1
  .row
2
2
  .col-md-2
3
3
  .col-md-8
4
- .card.card-default
4
+ .card.card-default.shadow
5
5
  .card-body
6
6
  = new_form_tag base_path do
7
7
  = haml :'user_login_traits/form', locals: { entity: entity }
@@ -1,19 +1,19 @@
1
1
  .row.mb-4
2
2
  .col-md-2
3
3
  .col-md-8
4
- .card.card-default
4
+ .card.card-default.shadow
5
5
  .card-body
6
6
  .author
7
7
  %img.float-right.img-thumbnail{ src: entity.gravatar }
8
- %h4= entity.email
8
+ %h4= entity.display_name
9
9
 
10
10
  %hr
11
11
  %p.description
12
12
  %label Name:
13
- = entity.name
13
+ = entity.name || '(None)'
14
14
  %p.description
15
15
  %label Surname:
16
- = entity.surname
16
+ = entity.surname || '(None)'
17
17
  %p.description
18
18
  %label Roles:
19
19
  = entity.roles_dataset.map(:name).map(&:titlecase).join(', ')
@@ -35,7 +35,7 @@
35
35
  .row.mb-4
36
36
  .col-md-2
37
37
  .col-md-8
38
- .card.card-default
38
+ .card.card-default.shadow
39
39
  .card-body
40
40
  %h4.card-title Change Password
41
41
  = edit_form_tag("#{base_path}/#{entity.display_id}/identity") do