ditty 0.3.2 → 0.3.3

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
  SHA1:
3
- metadata.gz: 2b443ee45c38fca3c0f69379d0631b03f1f91263
4
- data.tar.gz: 3b26f6324b6979e1e517c6338e41cb994dce80c0
3
+ metadata.gz: a55bb96414dd9974ba6f8ce44aadacbc340967e4
4
+ data.tar.gz: c529f7ac183eedfc9530d7c8703660d9a8894093
5
5
  SHA512:
6
- metadata.gz: 6794d0ac24c5fa6f0e95bd98e90cf8456f42b12c3cc8b3c0f3933f76a01912e1f62a798eddbc0076068351077b08d9e80e1071305630a256a9f27a78091071c3
7
- data.tar.gz: 4356aa0fca5ffd090d90a39450d2d8f5dfa90286aa9d0c66e7708ded6e1669d1cfa853ea5d4dbab9dc34476c233e0f2e72b5bed759833b82f55cd7b52de561b3
6
+ metadata.gz: 759f21f4031b46c3f486081f238d8846402c0c1d7c85dab75fc6f19d096757150020e217531772e5cfca88c6a32031663a8fb71692a046c2956010d63c70cd24
7
+ data.tar.gz: b821ad004ff984706263355b5408ae66d33f0f230fe22057fefd28dc075308a7c74928f11b68ab08fa3540220b042fb386f82caded9400fe9847222aced3366c
data/.travis.yml CHANGED
@@ -1,21 +1,29 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.4.0
5
- - 2.3.3
6
- - 2.2.6
4
+ - 2.4.0
5
+ - 2.3.3
6
+ - 2.2.6
7
7
  gemfile: Gemfile.ci
8
8
  env:
9
- - DATABASE_URL="sqlite::memory:" RACK_ENV=test
9
+ - DATABASE_URL="sqlite::memory:" RACK_ENV=test
10
10
  before_install:
11
- - gem install bundler -v 1.12.5
11
+ - gem install bundler -v 1.12.5
12
12
  before_script:
13
- - bundle exec rake ditty:prep
13
+ - bundle exec rake ditty:prep
14
14
  script:
15
- - bundle exec rake
16
- - bundle exec rubocop --fail-level W lib views
15
+ - bundle exec rake
16
+ - bundle exec rubocop --fail-level W lib views
17
17
  addons:
18
18
  code_climate:
19
19
  repo_token: 289860573c6284a8e277de86848caba84d840be49e35f3601bcd672ab40d1e35
20
20
  after_success:
21
- - bundle exec codeclimate-test-reporter
21
+ - bundle exec codeclimate-test-reporter
22
+ deploy:
23
+ provider: rubygems
24
+ api_key:
25
+ secure: i0GPUrE9cU31oOXoEiyAJEUU2EjGB8RAJ11veipq1x29F9sX3aDPWS2s9mk+uQsoUHC7IhziN8rD2Aw9bjNss+YywRvxA0M6bfP3w+C5v2rGV5j7p9R1pnUfKVgOIXTpOjocafgcUr6LslDhpdJileG29Z9dtQWi5wuqARXE54EhBPk1vvCh86l4t07vY4AbguNj73nbF2Rz0Z/+aZ9MrhS+rUhJ85ynIhH913ckl1jCjVycOTazyWdX6GBiEUYiToZBtQK/4XCsUuE4UQAcWXgNdwscV6WD1n53M2JBu6neqZzosLxyJ2aOZ65U643AtfrZd0qVqt1V9Od2083gwRmCXl58VltCDraXUbkWbqb/tfgdy4STeZilKNh5IPEmoySjjWiYmmN2vN+32D8ekyGRr2iciOSsMsy4pQW6r0MX16HfVct283guwIp4dFacVxQLuTZcjjkaRXILVOGuml/mcKxe48u82kHtlxveBKm0K9avDXupLWhXQ2Fy8B6q1z8ekSL4eNk1bcAyonXdQCgyHqlZQMEONd584XFVq1/L4yxvplxYoe4lOfTuDnwwTboHHZz8wLh27xAMguRhGUIa8oYTj8SgRZBpkVfUqQp14z/oH/qQ67MIY/kLWbjDY9cSA9MbhrOGCA/VczlLRkhmn4WJrYZHDyDMQkZwAOU=
26
+ gem: ditty
27
+ on:
28
+ tags: true
29
+ repo: EagerELK/ditty
@@ -38,6 +38,7 @@ module Ditty
38
38
 
39
39
  configure :production do
40
40
  disable :show_exceptions
41
+ set :dump_errors, false
41
42
  end
42
43
 
43
44
  configure :development do
@@ -46,7 +47,7 @@ module Ditty
46
47
 
47
48
  configure :production, :development do
48
49
  enable :logging
49
- # use Rack::CommonLogger, Ditty::Services::Logger.instance
50
+ use Rack::CommonLogger, Ditty::Services::Logger.instance
50
51
  end
51
52
 
52
53
  not_found do
@@ -73,7 +74,7 @@ module Ditty
73
74
  end
74
75
  end
75
76
 
76
- error Helpers::NotAuthenticated do
77
+ error Helpers::NotAuthenticated, ::Pundit::NotAuthorizedError do
77
78
  respond_to do |format|
78
79
  format.html do
79
80
  flash[:warning] = 'Please log in first.'
@@ -85,18 +86,6 @@ module Ditty
85
86
  end
86
87
  end
87
88
 
88
- error ::Pundit::NotAuthorizedError do
89
- respond_to do |format|
90
- format.html do
91
- flash[:warning] = 'Please log in first.'
92
- redirect "#{settings.map_path}/auth/identity"
93
- end
94
- format.json do
95
- [401, { 'Content-Type' => 'application/json' }, [{ code: 401, errors: ['Not Authorized'] }.to_json]]
96
- end
97
- end
98
- end
99
-
100
89
  error ::Sequel::ForeignKeyConstraintViolation do
101
90
  respond_to do |format|
102
91
  format.html do
@@ -110,10 +99,11 @@ module Ditty
110
99
 
111
100
  before(/.*/) do
112
101
  ::Ditty::Services::Logger.instance.debug "Running with #{self.class}"
113
- if request.url =~ /.json/
114
- request.accept.unshift('application/json')
115
- request.path_info = request.path_info.gsub(/.json/, '')
102
+ if request.path =~ /.*\.json\Z/
103
+ content_type :json
116
104
  end
105
+ # Ensure the accept header is set. People forget to include it in API requests
106
+ content_type(:json) if request.accept.count.eql?(1) && request.accept.first.to_s.eql?('*/*')
117
107
  end
118
108
  end
119
109
  end
@@ -2,11 +2,12 @@
2
2
 
3
3
  require 'ditty/controllers/application'
4
4
  require 'ditty/helpers/component'
5
+ require 'ditty/helpers/response'
5
6
  require 'sinatra/json'
6
7
 
7
8
  module Ditty
8
9
  class Component < Application
9
- helpers Helpers::Component
10
+ helpers Helpers::Component, Helpers::Response
10
11
 
11
12
  set base_path: nil
12
13
  set dehumanized: nil
@@ -18,28 +19,13 @@ module Ditty
18
19
  end
19
20
 
20
21
  # List
21
- get '/', provides: %i[html json] do
22
+ get '/' do
22
23
  authorize settings.model_class, :list
23
24
 
24
- actions = {}
25
- actions["#{base_path}/new"] = "New #{heading}" if policy(settings.model_class).create?
25
+ result = list
26
26
 
27
27
  log_action("#{dehumanized}_list".to_sym) if settings.track_actions
28
- respond_to do |format|
29
- format.html do
30
- haml :"#{view_location}/index",
31
- locals: { list: list, title: heading(:list), actions: actions }
32
- end
33
- format.json do
34
- # TODO: Add links defined by actions (New #{heading})
35
- json(
36
- 'items' => list.all.map(&:for_json),
37
- 'page' => (params['page'] || 1).to_i,
38
- 'count' => list.count,
39
- 'total' => dataset.count
40
- )
41
- end
42
- end
28
+ list_response(result)
43
29
  end
44
30
 
45
31
  # Create Form
@@ -52,29 +38,13 @@ module Ditty
52
38
 
53
39
  # Create
54
40
  post '/' do
55
- authorize settings.model_class, :create
56
41
  entity = settings.model_class.new(permitted_attributes(settings.model_class, :create))
57
- success = entity.valid? && entity.save
42
+ authorize entity, :create
58
43
 
59
- log_action("#{dehumanized}_create".to_sym) if success && settings.track_actions
60
- respond_to do |format|
61
- format.html do
62
- if success
63
- flash[:success] = "#{heading} Created"
64
- redirect "#{base_path}/#{entity.id}"
65
- else
66
- haml :"#{view_location}/new", locals: { entity: entity, title: heading(:new) }
67
- end
68
- end
69
- format.json do
70
- content_type :json
71
- if success
72
- redirect "#{base_path}/#{entity.id}", 201
73
- else
74
- [400, { errors: entity.errors }.to_json]
75
- end
76
- end
77
- end
44
+ entity.save # Will trigger a Sequel::ValidationFailed exception if the model is incorrect
45
+
46
+ log_action("#{dehumanized}_create".to_sym) if settings.track_actions
47
+ create_response(entity)
78
48
  end
79
49
 
80
50
  # Read
@@ -83,20 +53,8 @@ module Ditty
83
53
  halt 404 unless entity
84
54
  authorize entity, :read
85
55
 
86
- actions = {}
87
- actions["#{base_path}/#{entity.id}/edit"] = "Edit #{heading}" if policy(entity).update?
88
-
89
56
  log_action("#{dehumanized}_read".to_sym) if settings.track_actions
90
- respond_to do |format|
91
- format.html do
92
- haml :"#{view_location}/display",
93
- locals: { entity: entity, title: heading, actions: actions }
94
- end
95
- format.json do
96
- # TODO: Add links defined by actions (Edit #{heading})
97
- json entity.for_json
98
- end
99
- end
57
+ read_response(entity)
100
58
  end
101
59
 
102
60
  # Update Form
@@ -115,32 +73,10 @@ module Ditty
115
73
  authorize entity, :update
116
74
 
117
75
  entity.set(permitted_attributes(settings.model_class, :update))
76
+ entity.save # Will trigger a Sequel::ValidationFailed exception if the model is incorrect
118
77
 
119
- success = entity.valid? && entity.save
120
- log_action("#{dehumanized}_update".to_sym) if success && settings.track_actions
121
- if success
122
- respond_to do |format|
123
- format.html do
124
- # TODO: Ability to customize the return path and message?
125
- flash[:success] = "#{heading} Updated"
126
- redirect "#{base_path}/#{entity.id}"
127
- end
128
- format.json do
129
- headers 'Location' => "#{base_path}/#{entity.id}"
130
- json body entity.for_json
131
- end
132
- end
133
- else
134
- respond_to do |format|
135
- format.html do
136
- haml :"#{view_location}/edit", locals: { entity: entity, title: heading(:edit) }
137
- end
138
- format.json do
139
- content_type :json
140
- [400, { errors: entity.errors }.to_json]
141
- end
142
- end
143
- end
78
+ log_action("#{dehumanized}_update".to_sym) if settings.track_actions
79
+ update_response(entity)
144
80
  end
145
81
 
146
82
  delete '/:id' do |id|
@@ -151,15 +87,20 @@ module Ditty
151
87
  entity.destroy
152
88
 
153
89
  log_action("#{dehumanized}_delete".to_sym) if settings.track_actions
90
+ delete_response(entity)
91
+ end
92
+
93
+ error Sequel::ValidationFailed do
154
94
  respond_to do |format|
95
+ entity = env['sinatra.error'].model
96
+ errors = env['sinatra.error'].errors
97
+ status 400
155
98
  format.html do
156
- flash[:success] = "#{heading} Deleted"
157
- redirect base_path.to_s
99
+ action = entity.id ? :edit : :new
100
+ haml :"#{view_location}/#{action}", locals: { entity: entity, title: heading(action) }
158
101
  end
159
102
  format.json do
160
- content_type :json
161
- headers 'Location' => '/users'
162
- status 204
103
+ json [400, { errors: errors }]
163
104
  end
164
105
  end
165
106
  end
@@ -18,6 +18,12 @@ module Ditty
18
18
  # OmniAuth Identity Stuff
19
19
  # Log in Page
20
20
  get '/auth/identity' do
21
+ # Redirect to the registration page if there's no SA user
22
+ sa = Role.find_or_create(name: 'super_admin')
23
+ if User.where(roles: sa).count == 0
24
+ flash[:info] = 'Please register the super admin user.'
25
+ redirect "#{settings.map_path}/auth/identity/register"
26
+ end
21
27
  haml :'identity/login', locals: { title: 'Log In' }
22
28
  end
23
29
 
@@ -42,47 +42,20 @@ module Ditty
42
42
  user = locals[:user] = User.new(user_params)
43
43
  identity = locals[:identity] = Identity.new(identity_params)
44
44
 
45
- if identity.valid? && user.valid?
46
- DB.transaction(isolation: :serializable) do
47
- identity.save
48
- user.save
49
- user.add_identity identity
50
- if roles
51
- roles.each do |role_id|
52
- user.add_role(role_id) unless user.roles.map(&:id).include? role_id.to_i
53
- end
54
- end
55
- user.check_roles
56
- end
57
-
58
- log_action("#{dehumanized}_create".to_sym) if settings.track_actions
59
- respond_to do |format|
60
- format.html do
61
- flash[:success] = 'User created'
62
- redirect "#{base_path}/#{user.id}"
63
- end
64
- format.json do
65
- headers 'Content-Type' => 'application/json'
66
- redirect "#{base_path}/#{user.id}", 201
67
- end
68
- end
69
- else
70
- respond_to do |format|
71
- format.html do
72
- flash.now[:danger] = 'Could not create the user'
73
- locals[:entity] = user
74
- locals[:identity] = identity
75
- haml :"#{view_location}/new", locals: locals
76
- end
77
- format.json do
78
- headers \
79
- 'Content-Type' => 'application/json',
80
- 'Content-Location' => "#{view_location}/new"
81
- body ''
82
- status 402
45
+ DB.transaction(isolation: :serializable) do
46
+ identity.save # Will trigger a Sequel::ValidationFailed exception if the model is incorrect
47
+ user.save
48
+ user.add_identity identity
49
+ if roles
50
+ roles.each do |role_id|
51
+ user.add_role(role_id) unless user.roles.map(&:id).include? role_id.to_i
83
52
  end
84
53
  end
54
+ user.check_roles
85
55
  end
56
+
57
+ log_action("#{dehumanized}_create".to_sym) if settings.track_actions
58
+ create_response(user)
86
59
  end
87
60
 
88
61
  # Update
@@ -94,36 +67,16 @@ module Ditty
94
67
  values = permitted_attributes(settings.model_class, :update)
95
68
  roles = values.delete('role_id')
96
69
  entity.set values
97
- if entity.valid? && entity.save
98
- if roles
99
- entity.remove_all_roles
100
- roles.each { |role_id| entity.add_role(role_id) }
101
- entity.check_roles
102
- end
70
+ entity.save # Will trigger a Sequel::ValidationFailed exception if the model is incorrect
103
71
 
104
- log_action("#{dehumanized}_update".to_sym) if settings.track_actions
105
- respond_to do |format|
106
- format.html do
107
- flash[:success] = "#{heading} Updated"
108
- redirect back
109
- end
110
- format.json do
111
- content_type 'application/json'
112
- headers 'Location' => "/users/#{entity.id}"
113
- body entity.to_hash.to_json
114
- status 200
115
- end
116
- end
117
- else
118
- respond_to do |format|
119
- format.html do
120
- haml :"#{view_location}/edit", locals: { entity: entity, title: heading(:edit) }
121
- end
122
- format.json do
123
- 400
124
- end
125
- end
72
+ if roles
73
+ entity.remove_all_roles
74
+ roles.each { |role_id| entity.add_role(role_id) }
75
+ entity.check_roles
126
76
  end
77
+
78
+ log_action("#{dehumanized}_update".to_sym) if settings.track_actions
79
+ update_response(entity)
127
80
  end
128
81
 
129
82
  put '/:id/identity' do |id|
@@ -169,17 +122,7 @@ module Ditty
169
122
  entity.destroy
170
123
 
171
124
  log_action("#{dehumanized}_delete".to_sym) if settings.track_actions
172
- respond_to do |format|
173
- format.html do
174
- flash[:success] = "#{heading} Deleted"
175
- redirect base_path
176
- end
177
- format.json do
178
- content_type 'application/json'
179
- headers 'Location' => '/users'
180
- status 204
181
- end
182
- end
125
+ delete_response(entity)
183
126
  end
184
127
 
185
128
  # Profile
data/lib/ditty/db.rb CHANGED
@@ -2,8 +2,12 @@
2
2
 
3
3
  require 'sequel'
4
4
  require 'ditty/services/logger'
5
+ require 'active_support'
6
+ require 'active_support/core_ext/object/blank'
5
7
 
6
- if ENV['DATABASE_URL']
8
+ if defined? DB
9
+ Ditty::Services::Logger.instance.warn 'Database connection already set up'
10
+ elsif ENV['DATABASE_URL'].blank? == false
7
11
  # Delete DATABASE_URL from the environment, so it isn't accidently
8
12
  # passed to subprocesses. DATABASE_URL may contain passwords.
9
13
  DB = Sequel.connect(ENV['RACK_ENV'] == 'production' ? ENV.delete('DATABASE_URL') : ENV['DATABASE_URL'])
@@ -16,7 +16,8 @@ module Ditty
16
16
  count = params['count'] || 10
17
17
  page = params['page'] || 1
18
18
 
19
- dataset.select.paginate(page.to_i, count.to_i)
19
+ ds = dataset.select
20
+ count == 'all' ? ds : ds.paginate(page.to_i, count.to_i)
20
21
  end
21
22
 
22
23
  def heading(action = nil)
@@ -83,11 +84,13 @@ module Ditty
83
84
  assoc
84
85
  end
85
86
 
87
+ def search_filters
88
+ searchable_fields.map { |f| Sequel.ilike(f.to_sym, "%#{params[:q]}%") }
89
+ end
90
+
86
91
  def search(dataset)
87
92
  return dataset if ['', nil].include?(params['q']) || searchable_fields == []
88
-
89
- filters = searchable_fields.map { |f| Sequel.ilike(f.to_sym, "%#{params[:q]}%") }
90
- dataset.where Sequel.|(*filters)
93
+ dataset.where Sequel.|(*search_filters)
91
94
  end
92
95
  end
93
96
  end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ditty
4
+ module Helpers
5
+ module Response
6
+ def list_response(result)
7
+ respond_to do |format|
8
+ format.html do
9
+ actions = {}
10
+ actions["#{base_path}/new"] = "New #{heading}" if policy(settings.model_class).create?
11
+ haml :"#{view_location}/index",
12
+ locals: { list: result, title: heading(:list), actions: actions }
13
+ end
14
+ format.json do
15
+ # TODO: Add links defined by actions (New #{heading})
16
+ json(
17
+ 'items' => result.all.map(&:for_json),
18
+ 'page' => (params['page'] || 1).to_i,
19
+ 'count' => result.count,
20
+ 'total' => result.pagination_record_count
21
+ )
22
+ end
23
+ end
24
+ end
25
+
26
+ def create_response(entity)
27
+ respond_to do |format|
28
+ format.html do
29
+ flash[:success] = "#{heading} Created"
30
+ redirect "#{base_path}/#{entity.id}"
31
+ end
32
+ format.json do
33
+ content_type :json
34
+ redirect "#{base_path}/#{entity.id}", 201
35
+ end
36
+ end
37
+ end
38
+
39
+ def read_response(entity)
40
+ respond_to do |format|
41
+ format.html do
42
+ actions = {}
43
+ actions["#{base_path}/#{entity.id}/edit"] = "Edit #{heading}" if policy(entity).update?
44
+ title = heading(:read) + (entity.respond_to?(:name) ? ": #{entity.name}" : '')
45
+ haml :"#{view_location}/display", locals: { entity: entity, title: title, actions: actions }
46
+ end
47
+ format.json do
48
+ # TODO: Add links defined by actions (Edit #{heading})
49
+ json entity.for_json
50
+ end
51
+ end
52
+ end
53
+
54
+ def update_response(entity)
55
+ respond_to do |format|
56
+ format.html do
57
+ # TODO: Ability to customize the return path and message?
58
+ flash[:success] = "#{heading} Updated"
59
+ redirect "#{base_path}/#{entity.id}"
60
+ end
61
+ format.json do
62
+ headers 'Location' => "#{base_path}/#{entity.id}"
63
+ json body entity.for_json
64
+ end
65
+ end
66
+ end
67
+
68
+ def delete_response(_entity)
69
+ respond_to do |format|
70
+ format.html do
71
+ flash[:success] = "#{heading} Deleted"
72
+ redirect base_path.to_s
73
+ end
74
+ format.json do
75
+ content_type :json
76
+ headers 'Location' => "#{base_path}"
77
+ status 204
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -47,6 +47,7 @@ module Ditty
47
47
  end
48
48
 
49
49
  def pagination(list, base_path, qp = {})
50
+ return unless list.respond_to? :pagination_record_count
50
51
  qs = params.clone.merge(qp)
51
52
  qs.delete('captures')
52
53
  locals = {
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'rake'
4
4
  require 'rake/tasklib'
5
- require 'ditty/db'
5
+ require 'ditty/db' unless defined? DB
6
6
 
7
7
  module Ditty
8
8
  class Tasks < ::Rake::TaskLib
data/lib/ditty/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ditty
4
- VERSION = '0.3.2'.freeze
4
+ VERSION = '0.3.3'.freeze
5
5
  end
@@ -1,24 +1,28 @@
1
1
  - if flash[:danger]
2
2
  .alert.alert-danger.alert-dismissible{ role: "alert" }
3
3
  %button.close{ 'type' => 'button', 'aria-hidden' => 'true', 'area-label' => 'true', 'data-dismiss' => 'alert' } &times;
4
- - (flash[:danger].is_a?(Array) ? flash[:danger] : [flash[:danger]]).each do |msg|
5
- %span= msg
4
+ %ul
5
+ - [*flash[:danger]].each do |msg|
6
+ %li= msg
6
7
 
7
8
  - if flash[:warning]
8
9
  .alert.alert-warning.alert-dismissible{ role: "alert" }
9
10
  %button.close{ 'type' => 'button', 'aria-hidden' => 'true', 'area-label' => 'true', 'data-dismiss' => 'alert' } &times;
10
- - (flash[:warning].is_a?(Array) ? flash[:warning] : [flash[:warning]]).each do |msg|
11
- %span= msg
11
+ %ul
12
+ - [*flash[:warning]].each do |msg|
13
+ %li= msg
12
14
 
13
15
  - if flash[:success]
14
16
  .alert.alert-success.alert-dismissible{ role: "alert" }
15
17
  %button.close{ 'type' => 'button', 'aria-hidden' => 'true', 'area-label' => 'true', 'data-dismiss' => 'alert' } &times;
16
- - (flash[:success].is_a?(Array) ? flash[:success] : [flash[:success]]).each do |msg|
17
- %span= msg
18
+ %ul
19
+ - [*flash[:success]].each do |msg|
20
+ %li= msg
18
21
 
19
22
 
20
23
  - if flash[:info]
21
24
  .alert.alert-info.alert-dismissible{ role: "alert" }
22
25
  %button.close{ 'type' => 'button', 'aria-hidden' => 'true', 'area-label' => 'true', 'data-dismiss' => 'alert' } &times;
23
- - (flash[:info].is_a?(Array) ? flash[:info] : [flash[:info]]).each do |msg|
24
- %span= msg
26
+ %ul
27
+ - [*flash[:info]].each do |msg|
28
+ %li= msg
@@ -8,6 +8,7 @@
8
8
  %th Name
9
9
  %th Surname
10
10
  %th Roles
11
+ %th Signed Up
11
12
  %tbody
12
13
  - list.all.each do |entity|
13
14
  %tr
@@ -16,6 +17,7 @@
16
17
  %td= entity.name
17
18
  %td= entity.surname
18
19
  %td= entity.roles_dataset.map(:name).map(&:titlecase).join(', ')
20
+ %td= entity.created_at.strftime('%Y-%m-%d')
19
21
  - if policy(::Ditty::User).create?
20
22
  .panel-body.text-right
21
23
  %a.btn.btn-primary{ href: "#{base_path}/new" } New User
data/views/users/new.haml CHANGED
@@ -4,7 +4,7 @@
4
4
  .panel.panel-default
5
5
  .panel-body
6
6
  %form.form-horizontal{ method: 'post', action: base_path }
7
- = haml :'users/identity', locals: { identity: identity }
7
+ = haml :'users/identity', locals: { identity: Ditty::Identity.new }
8
8
  = haml :'users/user', locals: { user: entity }
9
9
  %button.btn.btn-primary{ type: 'submit' }
10
10
  Create User
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ditty
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jurgens du Toit
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-11-14 00:00:00.000000000 Z
11
+ date: 2018-01-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -349,6 +349,7 @@ files:
349
349
  - lib/ditty/helpers/authentication.rb
350
350
  - lib/ditty/helpers/component.rb
351
351
  - lib/ditty/helpers/pundit.rb
352
+ - lib/ditty/helpers/response.rb
352
353
  - lib/ditty/helpers/views.rb
353
354
  - lib/ditty/helpers/wisper.rb
354
355
  - lib/ditty/listener.rb