ditty 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.pryrc +6 -0
- data/.rspec +2 -0
- data/.rubocop.yml +15 -0
- data/.travis.yml +15 -0
- data/Gemfile.ci +19 -0
- data/License.txt +7 -0
- data/Rakefile +10 -0
- data/Readme.md +67 -0
- data/config.ru +33 -0
- data/ditty.gemspec +46 -0
- data/lib/ditty/components/app.rb +78 -0
- data/lib/ditty/controllers/application.rb +79 -0
- data/lib/ditty/controllers/audit_logs.rb +44 -0
- data/lib/ditty/controllers/component.rb +161 -0
- data/lib/ditty/controllers/main.rb +86 -0
- data/lib/ditty/controllers/roles.rb +16 -0
- data/lib/ditty/controllers/users.rb +183 -0
- data/lib/ditty/db.rb +12 -0
- data/lib/ditty/helpers/authentication.rb +58 -0
- data/lib/ditty/helpers/component.rb +63 -0
- data/lib/ditty/helpers/pundit.rb +34 -0
- data/lib/ditty/helpers/views.rb +50 -0
- data/lib/ditty/helpers/wisper.rb +14 -0
- data/lib/ditty/listener.rb +23 -0
- data/lib/ditty/models/audit_log.rb +14 -0
- data/lib/ditty/models/base.rb +7 -0
- data/lib/ditty/models/identity.rb +70 -0
- data/lib/ditty/models/role.rb +16 -0
- data/lib/ditty/models/user.rb +63 -0
- data/lib/ditty/policies/application_policy.rb +21 -0
- data/lib/ditty/policies/audit_log_policy.rb +41 -0
- data/lib/ditty/policies/identity_policy.rb +25 -0
- data/lib/ditty/policies/role_policy.rb +41 -0
- data/lib/ditty/policies/user_policy.rb +47 -0
- data/lib/ditty/rake_tasks.rb +85 -0
- data/lib/ditty/seed.rb +1 -0
- data/lib/ditty/services/logger.rb +48 -0
- data/lib/ditty/version.rb +5 -0
- data/lib/ditty.rb +142 -0
- data/migrate/20170207_base_tables.rb +40 -0
- data/migrate/20170208_audit_log.rb +12 -0
- data/migrate/20170416_audit_log_details.rb +9 -0
- data/public/browserconfig.xml +9 -0
- data/public/images/apple-icon.png +0 -0
- data/public/images/favicon-16x16.png +0 -0
- data/public/images/favicon-32x32.png +0 -0
- data/public/images/launcher-icon-1x.png +0 -0
- data/public/images/launcher-icon-2x.png +0 -0
- data/public/images/launcher-icon-4x.png +0 -0
- data/public/images/mstile-150x150.png +0 -0
- data/public/images/safari-pinned-tab.svg +43 -0
- data/public/manifest.json +25 -0
- data/views/404.haml +7 -0
- data/views/audit_logs/index.haml +30 -0
- data/views/error.haml +4 -0
- data/views/identity/login.haml +19 -0
- data/views/identity/register.haml +14 -0
- data/views/index.haml +1 -0
- data/views/layout.haml +55 -0
- data/views/partials/delete_form.haml +4 -0
- data/views/partials/footer.haml +5 -0
- data/views/partials/form_control.haml +20 -0
- data/views/partials/navbar.haml +24 -0
- data/views/partials/notifications.haml +24 -0
- data/views/partials/pager.haml +14 -0
- data/views/partials/sidebar.haml +35 -0
- data/views/roles/display.haml +18 -0
- data/views/roles/edit.haml +11 -0
- data/views/roles/form.haml +1 -0
- data/views/roles/index.haml +22 -0
- data/views/roles/new.haml +10 -0
- data/views/users/display.haml +50 -0
- data/views/users/edit.haml +11 -0
- data/views/users/identity.haml +3 -0
- data/views/users/index.haml +23 -0
- data/views/users/new.haml +11 -0
- data/views/users/profile.haml +39 -0
- data/views/users/user.haml +3 -0
- metadata +431 -0
data/views/404.haml
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
.row
|
2
|
+
.col-md-12
|
3
|
+
.panel.panel-default
|
4
|
+
%table.table.table-striped
|
5
|
+
%thead
|
6
|
+
%tr
|
7
|
+
%th User email
|
8
|
+
%th Action
|
9
|
+
%th Details
|
10
|
+
%th Created at
|
11
|
+
%tbody
|
12
|
+
- if list.count > 0
|
13
|
+
- list.all.each do |entity|
|
14
|
+
%tr
|
15
|
+
%td
|
16
|
+
-if entity.user
|
17
|
+
%a{ href: "/users/#{entity.user.id}" }= entity.user.email
|
18
|
+
-else
|
19
|
+
None
|
20
|
+
%td
|
21
|
+
= entity.action
|
22
|
+
%td
|
23
|
+
= entity.details
|
24
|
+
%td
|
25
|
+
= entity.created_at.strftime('%Y-%m-%d %H:%M:%S')
|
26
|
+
- else
|
27
|
+
%tr
|
28
|
+
%td.text-center{ colspan: 4 } No records
|
29
|
+
|
30
|
+
=pagination(list, base_path)
|
data/views/error.haml
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
.row
|
2
|
+
.col-sm-3
|
3
|
+
.col-sm-6
|
4
|
+
.panel.panel-default
|
5
|
+
.panel-heading
|
6
|
+
%h4 Login
|
7
|
+
.panel-body
|
8
|
+
%form{ method: 'post', action: "#{settings.map_path}/auth/identity/callback" }
|
9
|
+
.form-group
|
10
|
+
%label.control-label Username
|
11
|
+
%input.form-control.border-input{ name: 'username' }
|
12
|
+
.form-group
|
13
|
+
%label.control-label Password
|
14
|
+
%input.form-control.border-input{ name: 'password', type: 'password' }
|
15
|
+
%button.btn.btn-primary{ type: 'submit' } Log In
|
16
|
+
.pull-right
|
17
|
+
No account yet?
|
18
|
+
%a.btn.btn-default{ href: "#{settings.map_path}/auth/identity/register" } Register
|
19
|
+
.col-sm-3
|
@@ -0,0 +1,14 @@
|
|
1
|
+
.row
|
2
|
+
.col-md-2
|
3
|
+
.col-md-8
|
4
|
+
.panel.panel-default
|
5
|
+
.panel-heading
|
6
|
+
%h4 Ditty Registration
|
7
|
+
.panel-body
|
8
|
+
%form.form-horizontal{ method: 'post', action: "#{settings.map_path}/auth/identity/new" }
|
9
|
+
= form_control(:username, identity, label: 'Email', placeholder: 'Your email address')
|
10
|
+
= form_control(:password, identity, label: 'Password', type: :password)
|
11
|
+
= form_control(:password_confirmation, identity, label: 'Confirm Password', type: :password)
|
12
|
+
|
13
|
+
%button.btn.btn-primary{ type: 'submit' } Register
|
14
|
+
.col-md-2
|
data/views/index.haml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
%h2 Hello! Ready to get this Ditty started?
|
data/views/layout.haml
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
!!! 5
|
2
|
+
%html{ lang: 'en' }
|
3
|
+
%head
|
4
|
+
%meta{ charset: 'utf-8' }
|
5
|
+
%meta{ 'http-equiv' => 'X-UA-Compatible', 'content' => 'IE=edge,chrome=1' }
|
6
|
+
%meta{ name: 'viewport', content: 'width=device-width, initial-scale=1' }
|
7
|
+
%meta{ name: 'theme-color', content: '#ffffff' }
|
8
|
+
%link{ rel: 'manifest', href: '/manifest.json' }
|
9
|
+
%link{ rel: 'icon', type: 'image/png', sizes: '32x32', href: '/images/favicon-32x32.png' }
|
10
|
+
%link{ rel: 'icon', type: 'image/png', sizes: '16x16', href: '/images/favicon-16x16.png' }
|
11
|
+
%link{ rel: 'apple-touch-icon', sizes: '76x76', href: '/images/apple-icon.png' }
|
12
|
+
%link{ rel: 'mask-icon', href: '/safari-pinned-tab.svg', color: '#5bbad5' }
|
13
|
+
|
14
|
+
%title
|
15
|
+
Ditty
|
16
|
+
- if defined? title
|
17
|
+
= "- #{title}"
|
18
|
+
|
19
|
+
%meta{ name: 'description', content: '' }
|
20
|
+
%meta{ name: 'author', content: '' }
|
21
|
+
|
22
|
+
/ Le styles
|
23
|
+
%link{ rel: 'stylesheet', href: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css', media: 'screen' }
|
24
|
+
%link{ rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/startbootstrap-sb-admin-2/3.3.7+1/css/sb-admin-2.min.css', media: 'screen' }
|
25
|
+
%link{ rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/metisMenu/2.5.2/metisMenu.min.css', media: 'screen' }
|
26
|
+
%link{ rel: 'stylesheet', href: 'https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css', media: 'screen' }
|
27
|
+
/[if lt IE 9] <script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>
|
28
|
+
/[if lt IE 9] <script src="https://cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js"></script>
|
29
|
+
|
30
|
+
%script{ type: 'text/javascript', src: 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js' }
|
31
|
+
%script{ type: 'text/javascript', src: 'https://cdnjs.cloudflare.com/ajax/libs/startbootstrap-sb-admin-2/3.3.7+1/js/sb-admin-2.min.js' }
|
32
|
+
%script{ type: 'text/javascript', src: 'https://cdnjs.cloudflare.com/ajax/libs/metisMenu/2.5.2/metisMenu.min.js' }
|
33
|
+
%body
|
34
|
+
#wrapper
|
35
|
+
= haml :'partials/navbar', locals: { title: (defined?(title) ? title : 'Ditty') }
|
36
|
+
#page-wrapper
|
37
|
+
.row
|
38
|
+
.col-md-12
|
39
|
+
-if defined? title
|
40
|
+
%h1.page-header= title
|
41
|
+
= haml :'partials/notifications'
|
42
|
+
|
43
|
+
= yield
|
44
|
+
= haml :'partials/footer'
|
45
|
+
|
46
|
+
|
47
|
+
/ Placed at the end of the document so the pages load faster
|
48
|
+
%script{ type: 'text/javascript', src: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js' }
|
49
|
+
%script{ type: 'text/javascript', src: 'https://cdnjs.cloudflare.com/ajax/libs/react/15.4.1/react.min.js' }
|
50
|
+
%script{ type: 'text/javascript', src: 'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.bundle.min.js' }
|
51
|
+
:javascript
|
52
|
+
$(function() {
|
53
|
+
$('.sidebar-nav').metisMenu();
|
54
|
+
});
|
55
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
%div{ class: "form-group#{model.errors[field] ? ' has-error' : ''}" }
|
2
|
+
%label.col-sm-3.control-label{ for: attributes[:id] }= label
|
3
|
+
.col-sm-9
|
4
|
+
- type = attributes.delete(:type)
|
5
|
+
- if type == 'select'
|
6
|
+
- options = attributes.delete(:options)
|
7
|
+
%select{attributes}
|
8
|
+
- if attributes[:multiple]
|
9
|
+
- options.each do |k,v| k ||= v; v ||= k;
|
10
|
+
%option{ value: k, selected: (model.send(field).map(&:id).include? k)}= v
|
11
|
+
- else
|
12
|
+
%option{ value: ""} -- Select One --
|
13
|
+
- options.each do |k,v| k ||= v; v ||= k;
|
14
|
+
%option{ value: k, selected: [model[field].to_s, default].include?(k.to_s)}= v
|
15
|
+
- elsif type == 'textarea'
|
16
|
+
%textarea{attributes}= preserve(model[field])
|
17
|
+
- else
|
18
|
+
%input{attributes, type: type, value: model[field] || default}
|
19
|
+
- if model.errors[field]
|
20
|
+
%p.help-block.text-danger= model.errors[field].join(', ')
|
@@ -0,0 +1,24 @@
|
|
1
|
+
.navbar.navbar-default.navbar-static-top{ role: 'navigation', style: 'margin-bottom: 0' }
|
2
|
+
.navbar-header
|
3
|
+
%button.navbar-toggle.collapsed{ 'type' => 'button', 'data-toggle' => 'collapse', 'data-target' => '.navbar-collapse' }
|
4
|
+
%span.sr-only Toggle navigation
|
5
|
+
%span.icon-bar
|
6
|
+
%span.icon-bar
|
7
|
+
%span.icon-bar
|
8
|
+
%span.navbar-brand
|
9
|
+
Ditty
|
10
|
+
|
11
|
+
-if authenticated?
|
12
|
+
%form.nav.navbar-top-links.navbar-form.navbar-right{ action: "#{settings.map_path}/auth/identity", method: 'post' }
|
13
|
+
%a.btn.btn-default{ href: "#{settings.map_path}/users/profile" } My Account
|
14
|
+
%input{ name: '_method', value: 'DELETE', type: 'hidden' }
|
15
|
+
%button.btn.btn-default{ type: 'submit' }
|
16
|
+
/ %i.ti-panel
|
17
|
+
Logout
|
18
|
+
- else
|
19
|
+
%ul.nav.navbar-top-links.navbar-right
|
20
|
+
%li
|
21
|
+
%a.btn.btn-link{ href: "#{settings.map_path}/auth/identity" }
|
22
|
+
Log In
|
23
|
+
.navbar-default.sidebar{ role: 'navigation' }
|
24
|
+
= haml :'partials/sidebar'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
- if flash[:danger]
|
2
|
+
.alert.alert-danger.alert-dismissible{ role: "alert" }
|
3
|
+
%button.close{ 'type' => 'button', 'aria-hidden' => 'true', 'area-label' => 'true', 'data-dismiss' => 'alert' } ×
|
4
|
+
- (flash[:danger].is_a?(Array) ? flash[:danger] : [flash[:danger]]).each do |msg|
|
5
|
+
%span= msg
|
6
|
+
|
7
|
+
- if flash[:warning]
|
8
|
+
.alert.alert-warning.alert-dismissible{ role: "alert" }
|
9
|
+
%button.close{ 'type' => 'button', 'aria-hidden' => 'true', 'area-label' => 'true', 'data-dismiss' => 'alert' } ×
|
10
|
+
- (flash[:warning].is_a?(Array) ? flash[:warning] : [flash[:warning]]).each do |msg|
|
11
|
+
%span= msg
|
12
|
+
|
13
|
+
- if flash[:success]
|
14
|
+
.alert.alert-success.alert-dismissible{ role: "alert" }
|
15
|
+
%button.close{ 'type' => 'button', 'aria-hidden' => 'true', 'area-label' => 'true', 'data-dismiss' => 'alert' } ×
|
16
|
+
- (flash[:success].is_a?(Array) ? flash[:success] : [flash[:success]]).each do |msg|
|
17
|
+
%span= msg
|
18
|
+
|
19
|
+
|
20
|
+
- if flash[:info]
|
21
|
+
.alert.alert-info.alert-dismissible{ role: "alert" }
|
22
|
+
%button.close{ 'type' => 'button', 'aria-hidden' => 'true', 'area-label' => 'true', 'data-dismiss' => 'alert' } ×
|
23
|
+
- (flash[:info].is_a?(Array) ? flash[:info] : [flash[:info]]).each do |msg|
|
24
|
+
%span= msg
|
@@ -0,0 +1,14 @@
|
|
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.pager
|
5
|
+
%li
|
6
|
+
%a{href: "#{base_path}?page=1&count=#{list.page_size}"} First
|
7
|
+
%li{class: ("disabled" if list.first_page?)}
|
8
|
+
%a{href: prev_link} Previous
|
9
|
+
%li{class: ("disabled" if list.last_page?)}
|
10
|
+
%a{href: next_link} Next
|
11
|
+
%li
|
12
|
+
%a{href: "#{base_path}?page=#{list.page_count}&count=#{list.page_size}"} Last
|
13
|
+
- else
|
14
|
+
%p.text-center No records to show
|
@@ -0,0 +1,35 @@
|
|
1
|
+
.sidebar-nav.navbar-collapse
|
2
|
+
%ul.nav.nav-pills.nav-stacked
|
3
|
+
- if authenticated?
|
4
|
+
%li
|
5
|
+
%a{ href: "#{settings.map_path}/" }
|
6
|
+
%i.fa.fa-home.fa-fw
|
7
|
+
Home
|
8
|
+
- Ditty::Components.navigation.each do |item|
|
9
|
+
- if item[:target].nil? || policy(item[:target]).list?
|
10
|
+
- if item[:group]
|
11
|
+
%li
|
12
|
+
%a{ href: '#' }
|
13
|
+
%i.fa.fa-fw{ class: "fa-#{item[:icon]}" }
|
14
|
+
=item[:group]
|
15
|
+
%span.fa.arrow
|
16
|
+
%ul.nav.nav-second-level
|
17
|
+
- item[:items].each do |sub_item|
|
18
|
+
%li
|
19
|
+
%a{ href: "#{settings.map_path}#{sub_item[:link]}" }
|
20
|
+
%i.fa.fa-fw{ class: "fa-#{sub_item[:icon]}" }
|
21
|
+
= sub_item[:text]
|
22
|
+
- else
|
23
|
+
%li
|
24
|
+
%a{ href: "#{settings.map_path}#{item[:link]}" }
|
25
|
+
%i.fa.fa-fw{ class: "fa-#{item[:icon]}" }
|
26
|
+
= item[:text]
|
27
|
+
- else
|
28
|
+
%li.active
|
29
|
+
%a{ href: "#{settings.map_path}/auth/identity" }
|
30
|
+
%i.fa.fa-user.fa-fw
|
31
|
+
Log In
|
32
|
+
%li
|
33
|
+
%a{ href: "#{settings.map_path}/auth/identity/register" }
|
34
|
+
%i.fa.fa-pencil-square-o.fa-fw
|
35
|
+
Register
|
@@ -0,0 +1,18 @@
|
|
1
|
+
.row
|
2
|
+
.col-md-2
|
3
|
+
.col-md-8
|
4
|
+
.panel.panel-default
|
5
|
+
.panel-body
|
6
|
+
%p.description
|
7
|
+
%label Name:
|
8
|
+
= entity.name
|
9
|
+
|
10
|
+
.row
|
11
|
+
.col-md-6
|
12
|
+
%a.btn.btn-default{ href: "#{base_path}/#{entity.id}/edit" } Edit
|
13
|
+
.col-md-6.text-right
|
14
|
+
- if policy(entity).delete?
|
15
|
+
%form{ method: 'post', action: "#{base_path}/#{entity.id}" }
|
16
|
+
%input{ name: '_method', value: 'DELETE', type: 'hidden' }
|
17
|
+
%button.btn.btn-warning{ type: 'submit' } Delete
|
18
|
+
.col-md-2
|
@@ -0,0 +1,11 @@
|
|
1
|
+
.row
|
2
|
+
.col-md-2
|
3
|
+
.col-md-8
|
4
|
+
.panel.panel-default
|
5
|
+
.panel-body
|
6
|
+
%form.form-horizontal{ method: 'post', action: "#{base_path}/#{entity.id}" }
|
7
|
+
%input{ name: '_method', value: 'PUT', type: 'hidden' }
|
8
|
+
= haml :'roles/form', locals: { entity: entity }
|
9
|
+
%button.btn.btn-primary{ type: 'submit' }
|
10
|
+
Update Role
|
11
|
+
.col-md-2
|
@@ -0,0 +1 @@
|
|
1
|
+
= form_control(:name, entity)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
.row
|
2
|
+
.col-md-12
|
3
|
+
.panel.panel-default
|
4
|
+
%table.table.table-striped
|
5
|
+
%thead
|
6
|
+
%tr
|
7
|
+
%th Name
|
8
|
+
%tbody
|
9
|
+
- if list.count > 0
|
10
|
+
- list.all.each do |entity|
|
11
|
+
%tr
|
12
|
+
%td
|
13
|
+
%a{ href: "#{base_path}/#{entity.id}" }= entity.name
|
14
|
+
- else
|
15
|
+
%tr
|
16
|
+
%td.text-center{ colspan: 1 } No records
|
17
|
+
|
18
|
+
- if policy(::Ditty::Role).create?
|
19
|
+
.panel-body.text-right
|
20
|
+
%a.btn.btn-primary{ href: "#{base_path}/new" } New Role
|
21
|
+
|
22
|
+
=pagination(list, base_path)
|
@@ -0,0 +1,50 @@
|
|
1
|
+
.row
|
2
|
+
.col-md-2
|
3
|
+
.col-md-8
|
4
|
+
.panel.panel-default
|
5
|
+
.panel-body
|
6
|
+
.author
|
7
|
+
%img.pull-right.thumbnail{ src: entity.gravatar }
|
8
|
+
%h4= entity.email
|
9
|
+
|
10
|
+
%hr
|
11
|
+
%p.description
|
12
|
+
%label Name:
|
13
|
+
= entity.name
|
14
|
+
%p.description
|
15
|
+
%label Surname:
|
16
|
+
= entity.surname
|
17
|
+
%p.description
|
18
|
+
%label Roles:
|
19
|
+
= entity.roles_dataset.map(:name).map(&:titlecase).join(', ')
|
20
|
+
%p.description
|
21
|
+
%label Signed up:
|
22
|
+
= entity.created_at.strftime('%Y-%m-%d %H:%M:%S')
|
23
|
+
|
24
|
+
.row
|
25
|
+
.col-md-6
|
26
|
+
%a.btn.btn-default{ href: "#{base_path}/#{entity.id}/edit" } Edit
|
27
|
+
.col-md-6.text-right
|
28
|
+
- if policy(entity).delete?
|
29
|
+
%form{ method: 'post', action: "#{base_path}/#{entity.id}" }
|
30
|
+
%input{ name: '_method', value: 'DELETE', type: 'hidden' }
|
31
|
+
%button.btn.btn-warning{ type: 'submit' } Delete
|
32
|
+
.col-md-2
|
33
|
+
|
34
|
+
- if entity.identity.first
|
35
|
+
.row
|
36
|
+
.col-md-2
|
37
|
+
.col-md-8
|
38
|
+
.panel.panel-default
|
39
|
+
.panel-heading
|
40
|
+
%h4 Change Password
|
41
|
+
.panel-body
|
42
|
+
%form.form-horizontal{ method: 'post', action: "#{base_path}/#{entity.id}/identity" }
|
43
|
+
%input{ name: '_method', value: 'PUT', type: 'hidden' }
|
44
|
+
= form_control(:password, entity.identity.first, type: 'password', placeholder: 'Your password', group: 'identity')
|
45
|
+
= form_control(:password_confirmation, entity.identity.first, type: 'password', label: 'Confirm Password', placeholder: 'Confirm your password', group: 'identity')
|
46
|
+
%button.btn.btn-primary{ type: 'submit' }
|
47
|
+
Change Password
|
48
|
+
.col-md-2
|
49
|
+
|
50
|
+
|
@@ -0,0 +1,11 @@
|
|
1
|
+
.row
|
2
|
+
.col-md-2
|
3
|
+
.col-md-8
|
4
|
+
.panel.panel-default
|
5
|
+
.panel-body
|
6
|
+
%form.form-horizontal{ method: 'post', action: "#{base_path}/#{entity.id}" }
|
7
|
+
%input{ name: '_method', value: 'PUT', type: 'hidden' }
|
8
|
+
= haml :'users/user', locals: { user: entity }
|
9
|
+
%button.btn.btn-primary{ type: 'submit' }
|
10
|
+
Update User
|
11
|
+
.col-md-2
|
@@ -0,0 +1,3 @@
|
|
1
|
+
= form_control(:username, identity, label: 'Email', placeholder: 'Your email address')
|
2
|
+
= form_control(:password, identity, type: 'password', placeholder: 'Your password')
|
3
|
+
= form_control(:password_confirmation, identity, type: 'password', label: 'Confirm Password', placeholder: 'Confirm your password')
|
@@ -0,0 +1,23 @@
|
|
1
|
+
.row
|
2
|
+
.col-md-12
|
3
|
+
.panel.panel-default
|
4
|
+
%table.table.table-striped
|
5
|
+
%thead
|
6
|
+
%tr
|
7
|
+
%th Email
|
8
|
+
%th Name
|
9
|
+
%th Surname
|
10
|
+
%th Roles
|
11
|
+
%tbody
|
12
|
+
- list.all.each do |entity|
|
13
|
+
%tr
|
14
|
+
%td
|
15
|
+
%a{ href: "#{base_path}/#{entity.id}" }= entity.email
|
16
|
+
%td= entity.name
|
17
|
+
%td= entity.surname
|
18
|
+
%td= entity.roles_dataset.map(:name).map(&:titlecase).join(', ')
|
19
|
+
- if policy(::Ditty::User).create?
|
20
|
+
.panel-body.text-right
|
21
|
+
%a.btn.btn-primary{ href: "#{base_path}/new" } New User
|
22
|
+
|
23
|
+
=pagination(list, base_path)
|
@@ -0,0 +1,11 @@
|
|
1
|
+
.row
|
2
|
+
.col-md-2
|
3
|
+
.col-md-8
|
4
|
+
.panel.panel-default
|
5
|
+
.panel-body
|
6
|
+
%form.form-horizontal{ method: 'post', action: base_path }
|
7
|
+
= haml :'users/identity', locals: { identity: identity }
|
8
|
+
= haml :'users/user', locals: { user: entity }
|
9
|
+
%button.btn.btn-primary{ type: 'submit' }
|
10
|
+
Create User
|
11
|
+
.col-md-2
|
@@ -0,0 +1,39 @@
|
|
1
|
+
.row
|
2
|
+
.col-md-2
|
3
|
+
.col-md-8
|
4
|
+
.panel.panel-default
|
5
|
+
.panel-body
|
6
|
+
.author
|
7
|
+
%img.pull-right.thumbnail{ src: entity.gravatar }
|
8
|
+
%h4= entity.email
|
9
|
+
|
10
|
+
%hr
|
11
|
+
%p.description
|
12
|
+
%label Name:
|
13
|
+
= entity.name
|
14
|
+
%p.description
|
15
|
+
%label Surname:
|
16
|
+
= entity.surname
|
17
|
+
%p.description
|
18
|
+
%label Roles:
|
19
|
+
= entity.roles_dataset.map(:name).map(&:titlecase).join(', ')
|
20
|
+
%p.description
|
21
|
+
%label Signed up:
|
22
|
+
= entity.created_at.strftime('%Y-%m-%d %H:%M:%S')
|
23
|
+
.col-md-2
|
24
|
+
|
25
|
+
.row
|
26
|
+
.col-md-2
|
27
|
+
.col-md-8
|
28
|
+
.panel.panel-default
|
29
|
+
.panel-heading
|
30
|
+
%h4 Change Password
|
31
|
+
.panel-body
|
32
|
+
%form.form-horizontal{ method: 'post', action: "#{base_path}/#{entity.id}/identity" }
|
33
|
+
%input{ name: '_method', value: 'PUT', type: 'hidden' }
|
34
|
+
= form_control(:old_password, identity, type: 'password', placeholder: 'Your current password')
|
35
|
+
= form_control(:password, identity, type: 'password', placeholder: 'Your new password')
|
36
|
+
= form_control(:password_confirmation, identity, type: 'password', label: 'Confirm Password', placeholder: 'Confirm your password')
|
37
|
+
%button.btn.btn-primary{ type: 'submit' }
|
38
|
+
Change Password
|
39
|
+
.col-md-2
|