ditty 0.7.1 → 0.10.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.
Files changed (185) hide show
  1. checksums.yaml +4 -4
  2. data/.env.test +2 -0
  3. data/.gitignore +3 -0
  4. data/.pryrc +2 -0
  5. data/.rubocop.yml +24 -8
  6. data/.travis.yml +4 -8
  7. data/CNAME +1 -0
  8. data/Dockerfile +18 -0
  9. data/Gemfile.ci +0 -15
  10. data/Rakefile +5 -4
  11. data/Readme.md +24 -2
  12. data/_config.yml +1 -0
  13. data/config.ru +4 -4
  14. data/ditty.gemspec +31 -20
  15. data/docs/CNAME +1 -0
  16. data/docs/_config.yml +1 -0
  17. data/docs/index.md +34 -0
  18. data/exe/ditty +2 -0
  19. data/lib/ditty.rb +30 -4
  20. data/lib/ditty/cli.rb +38 -5
  21. data/lib/ditty/components/ditty.rb +82 -0
  22. data/lib/ditty/controllers/application_controller.rb +267 -0
  23. data/lib/ditty/controllers/{audit_logs.rb → audit_logs_controller.rb} +5 -7
  24. data/lib/ditty/controllers/{auth.rb → auth_controller.rb} +56 -32
  25. data/lib/ditty/controllers/{component.rb → component_controller.rb} +35 -24
  26. data/lib/ditty/controllers/{main.rb → main_controller.rb} +7 -7
  27. data/lib/ditty/controllers/roles_controller.rb +23 -0
  28. data/lib/ditty/controllers/user_login_traits_controller.rb +46 -0
  29. data/lib/ditty/controllers/{users.rb → users_controller.rb} +17 -20
  30. data/lib/ditty/db.rb +9 -5
  31. data/lib/ditty/emails/base.rb +48 -34
  32. data/lib/ditty/generators/crud_generator.rb +114 -0
  33. data/lib/ditty/generators/migration_generator.rb +26 -0
  34. data/lib/ditty/generators/project_generator.rb +52 -0
  35. data/lib/ditty/helpers/authentication.rb +6 -5
  36. data/lib/ditty/helpers/component.rb +11 -2
  37. data/lib/ditty/helpers/pundit.rb +24 -8
  38. data/lib/ditty/helpers/response.rb +38 -15
  39. data/lib/ditty/helpers/views.rb +48 -6
  40. data/lib/ditty/listener.rb +44 -14
  41. data/lib/ditty/memcached.rb +8 -0
  42. data/lib/ditty/middleware/accept_extension.rb +4 -2
  43. data/lib/ditty/middleware/error_catchall.rb +4 -2
  44. data/lib/ditty/models/audit_log.rb +1 -0
  45. data/lib/ditty/models/base.rb +13 -0
  46. data/lib/ditty/models/identity.rb +10 -7
  47. data/lib/ditty/models/role.rb +2 -0
  48. data/lib/ditty/models/user.rb +40 -3
  49. data/lib/ditty/models/user_login_trait.rb +17 -0
  50. data/lib/ditty/policies/audit_log_policy.rb +6 -6
  51. data/lib/ditty/policies/role_policy.rb +3 -3
  52. data/lib/ditty/policies/user_login_trait_policy.rb +45 -0
  53. data/lib/ditty/policies/user_policy.rb +3 -3
  54. data/lib/ditty/rubocop.rb +3 -0
  55. data/lib/ditty/seed.rb +2 -0
  56. data/lib/ditty/services/authentication.rb +31 -15
  57. data/lib/ditty/services/email.rb +22 -12
  58. data/lib/ditty/services/logger.rb +30 -13
  59. data/lib/ditty/services/pagination_wrapper.rb +9 -5
  60. data/lib/ditty/services/settings.rb +19 -7
  61. data/lib/ditty/tasks/ditty.rake +127 -0
  62. data/lib/ditty/tasks/omniauth-ldap.rake +43 -0
  63. data/lib/ditty/templates/.gitignore +5 -0
  64. data/lib/ditty/templates/.rspec +2 -0
  65. data/lib/ditty/templates/.rubocop.yml +7 -0
  66. data/lib/ditty/templates/Rakefile +12 -0
  67. data/lib/ditty/templates/application.rb +12 -0
  68. data/lib/ditty/templates/config.ru +37 -0
  69. data/lib/ditty/templates/controller.rb.erb +64 -0
  70. data/lib/ditty/templates/env.example +4 -0
  71. data/lib/ditty/templates/lib/project.rb.erb +5 -0
  72. data/lib/ditty/templates/migration.rb.erb +7 -0
  73. data/lib/ditty/templates/model.rb.erb +26 -0
  74. data/lib/ditty/templates/pids/.empty_directory +0 -0
  75. data/lib/ditty/templates/policy.rb.erb +48 -0
  76. data/{public → lib/ditty/templates/public}/browserconfig.xml +0 -0
  77. data/lib/ditty/templates/public/css/sb-admin-2.min.css +10 -0
  78. data/lib/ditty/templates/public/css/styles.css +13 -0
  79. data/lib/ditty/templates/public/favicon.ico +0 -0
  80. data/{public → lib/ditty/templates/public}/images/apple-icon.png +0 -0
  81. data/{public → lib/ditty/templates/public}/images/favicon-16x16.png +0 -0
  82. data/{public → lib/ditty/templates/public}/images/favicon-32x32.png +0 -0
  83. data/{public → lib/ditty/templates/public}/images/launcher-icon-1x.png +0 -0
  84. data/{public → lib/ditty/templates/public}/images/launcher-icon-2x.png +0 -0
  85. data/{public → lib/ditty/templates/public}/images/launcher-icon-4x.png +0 -0
  86. data/{public → lib/ditty/templates/public}/images/mstile-150x150.png +0 -0
  87. data/{public → lib/ditty/templates/public}/images/safari-pinned-tab.svg +0 -0
  88. data/lib/ditty/templates/public/js/sb-admin-2.min.js +7 -0
  89. data/lib/ditty/templates/public/js/scripts.js +1 -0
  90. data/{public/manifest.json → lib/ditty/templates/public/manifest.json.erb} +2 -2
  91. data/lib/ditty/templates/settings.yml.erb +19 -0
  92. data/lib/ditty/templates/sidekiq.rb +18 -0
  93. data/lib/ditty/templates/sidekiq.yml +9 -0
  94. data/lib/ditty/templates/spec_helper.rb +43 -0
  95. data/lib/ditty/templates/type.rb.erb +21 -0
  96. data/lib/ditty/templates/views/display.haml.tt +20 -0
  97. data/lib/ditty/templates/views/edit.haml.tt +10 -0
  98. data/lib/ditty/templates/views/form.haml.tt +11 -0
  99. data/lib/ditty/templates/views/index.haml.tt +29 -0
  100. data/lib/ditty/templates/views/new.haml.tt +10 -0
  101. data/lib/ditty/version.rb +1 -1
  102. data/lib/rubocop/cop/ditty/call_services_directly.rb +42 -0
  103. data/migrate/20181209_add_user_login_traits.rb +16 -0
  104. data/migrate/20181209_extend_audit_log.rb +12 -0
  105. data/migrate/20190220_add_parent_id_to_roles.rb +9 -0
  106. data/spec/ditty/api_spec.rb +51 -0
  107. data/spec/ditty/controllers/roles_spec.rb +67 -0
  108. data/spec/ditty/controllers/user_login_traits_spec.rb +72 -0
  109. data/spec/ditty/controllers/users_spec.rb +72 -0
  110. data/spec/ditty/emails/base_spec.rb +76 -0
  111. data/spec/ditty/emails/forgot_password_spec.rb +20 -0
  112. data/spec/ditty/helpers/component_spec.rb +85 -0
  113. data/spec/ditty/models/user_spec.rb +36 -0
  114. data/spec/ditty/services/email_spec.rb +36 -0
  115. data/spec/ditty/services/logger_spec.rb +68 -0
  116. data/spec/ditty/services/settings_spec.rb +63 -0
  117. data/spec/ditty_spec.rb +9 -0
  118. data/spec/factories.rb +46 -0
  119. data/spec/fixtures/logger.yml +17 -0
  120. data/spec/fixtures/section.yml +3 -0
  121. data/spec/fixtures/settings.yml +8 -0
  122. data/spec/spec_helper.rb +51 -0
  123. data/spec/support/api_shared_examples.rb +250 -0
  124. data/spec/support/crud_shared_examples.rb +145 -0
  125. data/views/403.haml +2 -0
  126. data/views/404.haml +2 -4
  127. data/views/500.haml +11 -0
  128. data/views/audit_logs/index.haml +32 -28
  129. data/views/auth/forgot_password.haml +32 -16
  130. data/views/auth/identity.haml +14 -13
  131. data/views/auth/ldap.haml +17 -0
  132. data/views/auth/login.haml +23 -17
  133. data/views/auth/register.haml +20 -18
  134. data/views/auth/register_identity.haml +27 -12
  135. data/views/auth/reset_password.haml +36 -19
  136. data/views/blank.haml +43 -0
  137. data/views/emails/forgot_password.haml +1 -1
  138. data/views/emails/layouts/action.haml +10 -6
  139. data/views/emails/layouts/alert.haml +2 -1
  140. data/views/emails/layouts/billing.haml +2 -1
  141. data/views/embedded.haml +17 -11
  142. data/views/error.haml +8 -3
  143. data/views/index.haml +1 -1
  144. data/views/layout.haml +45 -30
  145. data/views/partials/actions.haml +15 -14
  146. data/views/partials/content_tag.haml +0 -0
  147. data/views/partials/delete_form.haml +1 -1
  148. data/views/partials/filter_control.haml +2 -2
  149. data/views/partials/footer.haml +13 -5
  150. data/views/partials/form_control.haml +30 -19
  151. data/views/partials/form_tag.haml +1 -1
  152. data/views/partials/navitems.haml +42 -0
  153. data/views/partials/notifications.haml +12 -8
  154. data/views/partials/pager.haml +44 -25
  155. data/views/partials/search.haml +15 -11
  156. data/views/partials/sidebar.haml +15 -37
  157. data/views/partials/sort_ui.haml +2 -0
  158. data/views/partials/timespan_selector.haml +64 -0
  159. data/views/partials/topbar.haml +53 -0
  160. data/views/partials/user_associations.haml +32 -0
  161. data/views/quick_start.haml +23 -0
  162. data/views/roles/display.haml +27 -6
  163. data/views/roles/edit.haml +3 -3
  164. data/views/roles/form.haml +1 -0
  165. data/views/roles/index.haml +23 -14
  166. data/views/roles/new.haml +2 -2
  167. data/views/user_login_traits/display.haml +32 -0
  168. data/views/user_login_traits/edit.haml +10 -0
  169. data/views/user_login_traits/form.haml +5 -0
  170. data/views/user_login_traits/index.haml +28 -0
  171. data/views/user_login_traits/new.haml +10 -0
  172. data/views/users/display.haml +15 -16
  173. data/views/users/edit.haml +3 -3
  174. data/views/users/form.haml +0 -0
  175. data/views/users/index.haml +31 -24
  176. data/views/users/login_traits.haml +25 -0
  177. data/views/users/new.haml +2 -2
  178. data/views/users/profile.haml +17 -15
  179. data/views/users/user.haml +1 -1
  180. metadata +314 -76
  181. data/lib/ditty/components/app.rb +0 -77
  182. data/lib/ditty/controllers/application.rb +0 -175
  183. data/lib/ditty/controllers/roles.rb +0 -16
  184. data/lib/ditty/rake_tasks.rb +0 -102
  185. data/views/partials/navbar.haml +0 -23
@@ -1,77 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'ditty'
4
-
5
- module Ditty
6
- class App
7
- def self.load
8
- controllers = File.expand_path('../controllers', __dir__)
9
- Dir.glob("#{controllers}/*.rb").each { |f| require f }
10
-
11
- require 'ditty/models/user'
12
- require 'ditty/models/role'
13
- require 'ditty/models/identity'
14
- require 'ditty/models/audit_log'
15
- end
16
-
17
- def self.configure(_container)
18
- require 'ditty/db' unless defined? ::DB
19
- require 'ditty/listener'
20
- end
21
-
22
- def self.migrations
23
- File.expand_path('../../../migrate', __dir__)
24
- end
25
-
26
- def self.view_folder
27
- File.expand_path('../../../views', __dir__)
28
- end
29
-
30
- def self.routes
31
- load
32
- {
33
- '/' => ::Ditty::Main,
34
- '/auth' => ::Ditty::Auth,
35
- '/users' => ::Ditty::Users,
36
- '/roles' => ::Ditty::Roles,
37
- '/audit-logs' => ::Ditty::AuditLogs
38
- }
39
- end
40
-
41
- def self.navigation
42
- load
43
-
44
- [
45
- {
46
- group: 'User Management',
47
- order: 10,
48
- icon: 'lock',
49
- target: ::Ditty::User,
50
- items: [
51
- { order: 10, link: '/users/', text: 'Users', target: ::Ditty::User, icon: 'user' },
52
- { order: 20, link: '/roles/', text: 'Roles', target: ::Ditty::Role, icon: 'check-square' },
53
- { order: 30, link: '/audit-logs/', text: 'Audit Logs', target: ::Ditty::AuditLog, icon: 'history' }
54
- ]
55
- }
56
- ]
57
- end
58
-
59
- def self.seeder
60
- proc do
61
- load
62
-
63
- ::Ditty::Role.find_or_create(name: 'super_admin')
64
- ::Ditty::Role.find_or_create(name: 'admin')
65
- user_role = ::Ditty::Role.find_or_create(name: 'user')
66
-
67
- # Anonymous User
68
- anon = ::Ditty::User.find_or_create(email: 'anonymous@ditty.io')
69
- anon.remove_role user_role
70
- anon_role = ::Ditty::Role.find_or_create(name: 'anonymous')
71
- anon.add_role anon_role unless anon.role?('anonymous')
72
- end
73
- end
74
- end
75
- end
76
-
77
- Ditty::Components.register_component(:app, Ditty::App)
@@ -1,175 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'wisper'
4
- require 'oga'
5
- require 'sinatra/base'
6
- require 'sinatra/flash'
7
- require 'sinatra/param'
8
- require 'sinatra/respond_with'
9
- require 'ditty/helpers/views'
10
- require 'ditty/helpers/pundit'
11
- require 'ditty/helpers/authentication'
12
- require 'ditty/services/logger'
13
- require 'active_support'
14
- require 'active_support/inflector'
15
- require 'rack/contrib'
16
- require 'rack/csrf'
17
-
18
- module Ditty
19
- class Application < Sinatra::Base
20
- include ActiveSupport::Inflector
21
-
22
- set :root, ENV['APP_ROOT'] || ::File.expand_path(::File.dirname(__FILE__) + '/../../../')
23
- set :map_path, nil
24
- set :view_location, nil
25
- set :model_class, nil
26
- set :raise_sinatra_param_exceptions, true
27
- set track_actions: false
28
-
29
- # The order here is important, since Wisper has a deprecated method respond_with method
30
- helpers Wisper::Publisher
31
- helpers Helpers::Pundit, Helpers::Views, Helpers::Authentication
32
- helpers Sinatra::Param
33
-
34
- register Sinatra::Flash, Sinatra::RespondWith
35
-
36
- use Rack::Csrf, raise: ENV['APP_ENV'] == 'development' unless ENV['APP_ENV'] == 'test'
37
- use Rack::PostBodyContentTypeParser
38
- use Rack::MethodOverride
39
- use Rack::NestedParams
40
-
41
- helpers do
42
- def base_path
43
- settings.base_path || "#{settings.map_path}/#{dasherize(view_location)}"
44
- end
45
-
46
- def view_location
47
- return settings.view_location if settings.view_location
48
- return underscore(pluralize(demodulize(settings.model_class))) if settings.model_class
49
- underscore(demodulize(self.class))
50
- end
51
- end
52
-
53
- configure :production do
54
- disable :show_exceptions
55
- set :dump_errors, false
56
- end
57
-
58
- configure :development do
59
- set :show_exceptions, :after_handler
60
- end
61
-
62
- configure :production, :development do
63
- disable :logging
64
- use Rack::CommonLogger, Ditty::Services::Logger.instance
65
- end
66
-
67
- not_found do
68
- respond_to do |format|
69
- status 404
70
- format.html do
71
- haml :'404', locals: { title: '4 oh 4' }, layout: layout
72
- end
73
- format.json do
74
- json code: 404, errors: ['Not Found']
75
- end
76
- end
77
- end
78
-
79
- error Helpers::NotAuthenticated, ::Pundit::NotAuthorizedError do
80
- respond_to do |format|
81
- status 401
82
- format.html do
83
- flash[:warning] = 'Please log in first.'
84
- redirect with_layout("#{settings.map_path}/auth/login")
85
- end
86
- format.json do
87
- json code: 401, errors: ['Not Authenticated']
88
- end
89
- end
90
- end
91
-
92
- error Sequel::ValidationFailed do
93
- respond_to do |format|
94
- entity = env['sinatra.error'].model
95
- errors = env['sinatra.error'].errors
96
- status 400
97
- format.html do
98
- action = entity.id ? :edit : :new
99
- haml :"#{view_location}/#{action}", locals: { entity: entity, title: heading(action) }, layout: layout
100
- end
101
- format.json do
102
- json code: 400, errors: errors, full_errors: errors.full_messages
103
- end
104
- end
105
- end
106
-
107
- error Sinatra::Param::InvalidParameterError do
108
- respond_to do |format|
109
- status 400
110
- format.html do
111
- flash.now[:danger] = env['sinatra.error'].message
112
- haml :'400', locals: { title: '4 oh oh' }, layout: layout
113
- end
114
- format.json do
115
- json code: 400, errors: { env['sinatra.error'].param => env['sinatra.error'].message }, full_errors: [env['sinatra.error'].message]
116
- end
117
- end
118
- end
119
-
120
- error ::Sequel::ForeignKeyConstraintViolation do
121
- error = env['sinatra.error']
122
- broadcast(:application_error, error)
123
- ::Ditty::Services::Logger.instance.error error
124
- respond_to do |format|
125
- status 400
126
- format.html do
127
- haml :error, locals: { title: 'Something went wrong', error: error }, layout: layout
128
- end
129
- format.json do
130
- json code: 400, errors: ['Invalid Relation Specified']
131
- end
132
- end
133
- end
134
-
135
- error do
136
- error = env['sinatra.error']
137
- broadcast(:application_error, error)
138
- ::Ditty::Services::Logger.instance.error error
139
- respond_to do |format|
140
- status 500
141
- format.html do
142
- haml :error, locals: { title: 'Something went wrong', error: error }, layout: layout
143
- end
144
- format.json do
145
- json code: 500, errors: ['Something went wrong']
146
- end
147
- end
148
- end
149
-
150
- before(/.*/) do
151
- ::Ditty::Services::Logger.instance.debug "Running with #{self.class} - #{request.path_info}"
152
- if request.path =~ /.*\.json\Z/
153
- content_type :json
154
- request.path_info = request.path_info.gsub(/.json$/, '')
155
- elsif request.env['ACCEPT']
156
- content_type request.env['ACCEPT']
157
- else
158
- content_type(:json) if request.accept.count.eql?(1) && request.accept.first.to_s.eql?('*/*')
159
- end
160
- end
161
-
162
- after do
163
- return if params[:layout].nil?
164
- response.body = response.body.map do |resp|
165
- document = Oga.parse_html(resp)
166
- document.css('a').each do |elm|
167
- unless (href = elm.get('href')).nil?
168
- elm.set 'href', with_layout(href)
169
- end
170
- end
171
- document.to_xml
172
- end
173
- end
174
- end
175
- end
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'ditty/controllers/component'
4
- require 'ditty/models/role'
5
- require 'ditty/policies/role_policy'
6
-
7
- module Ditty
8
- class Roles < Ditty::Component
9
- set model_class: Role
10
-
11
- def find_template(views, name, engine, &block)
12
- super(views, name, engine, &block) # Root
13
- super(::Ditty::App.view_folder, name, engine, &block) # Ditty
14
- end
15
- end
16
- end
@@ -1,102 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rake'
4
- require 'rake/tasklib'
5
- require 'ditty/db' unless defined? DB
6
-
7
- module Ditty
8
- class Tasks < ::Rake::TaskLib
9
- include ::Rake::DSL if defined?(::Rake::DSL)
10
-
11
- def install_tasks
12
- namespace :ditty do
13
- desc 'Generate the needed tokens'
14
- task :generate_tokens do
15
- puts 'Generating the Ditty tokens'
16
- require 'securerandom'
17
- File.write('.session_secret', SecureRandom.random_bytes(40)) unless File.file?('.session_secret')
18
- File.write('.token_secret', SecureRandom.random_bytes(40)) unless File.file?('.token_secret')
19
- end
20
-
21
- desc 'Seed the Ditty database'
22
- task :seed do
23
- puts 'Seeding the Ditty database'
24
- require 'ditty/seed'
25
- end
26
-
27
- desc 'Prepare Ditty'
28
- task :prep do
29
- puts 'Prepare the Ditty folders'
30
- Dir.mkdir 'pids' unless File.exist?('pids')
31
-
32
- puts 'Preparing the Ditty public folder'
33
- Dir.mkdir 'public' unless File.exist?('public')
34
- ::Ditty::Components.public_folder.each do |path|
35
- puts "Checking #{path}"
36
- FileUtils.cp_r "#{path}/.", 'public' unless File.expand_path("#{path}/.").eql? File.expand_path('public')
37
- end
38
-
39
- puts 'Preparing the Ditty migrations folder'
40
- Dir.mkdir 'migrations' unless File.exist?('migrations')
41
- ::Ditty::Components.migrations.each do |path|
42
- FileUtils.cp_r "#{path}/.", 'migrations' unless File.expand_path("#{path}/.").eql? File.expand_path('migrations')
43
- end
44
- puts 'Migrations added:'
45
- Dir.foreach('migrations').sort.each { |x| puts x if File.file?("migrations/#{x}") && x[-3..-1] == '.rb' }
46
- end
47
-
48
- desc 'Migrate Ditty database to latest version'
49
- task :migrate do
50
- puts 'Running the Ditty migrations'
51
- Rake::Task['ditty:migrate:up'].invoke
52
- end
53
-
54
- namespace :migrate do
55
- require 'logger'
56
-
57
- folder = 'migrations'
58
-
59
- desc 'Check if the migration is current'
60
- task :check do
61
- ::DB.loggers << Logger.new($stdout) if ::DB.loggers.count.zero?
62
- puts 'Running Ditty Migrations check'
63
- ::Sequel.extension :migration
64
- begin
65
- ::Sequel::Migrator.check_current(::DB, folder)
66
- puts 'Migrations up to date'
67
- rescue Sequel::Migrator::Error => _e
68
- puts 'Migrations NOT up to date'
69
- end
70
- end
71
-
72
- desc 'Migrate Ditty database to latest version'
73
- task :up do
74
- ::DB.loggers << Logger.new($stdout) if ::DB.loggers.count.zero?
75
- puts 'Running Ditty Migrations up'
76
- ::Sequel.extension :migration
77
- ::Sequel::Migrator.apply(::DB, folder)
78
- end
79
-
80
- desc 'Remove the whole Ditty database. You WILL lose data'
81
- task :down do
82
- ::DB.loggers << Logger.new($stdout) if ::DB.loggers.count.zero?
83
- puts 'Running Ditty Migrations down'
84
- ::Sequel.extension :migration
85
- ::Sequel::Migrator.apply(::DB, folder, 0)
86
- end
87
-
88
- desc 'Reset the Ditty database. You WILL lose data'
89
- task :bounce do
90
- ::DB.loggers << Logger.new($stdout) if ::DB.loggers.count.zero?
91
- puts 'Running Ditty Migrations bounce'
92
- ::Sequel.extension :migration
93
- ::Sequel::Migrator.apply(::DB, folder, 0)
94
- ::Sequel::Migrator.apply(::DB, folder)
95
- end
96
- end
97
- end
98
- end
99
- end
100
- end
101
-
102
- Ditty::Tasks.new.install_tasks
@@ -1,23 +0,0 @@
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
- = delete_form_tag("#{settings.map_path}/auth", attributes: { class: 'nav navbar-top-links navbar-form navbar-right' }) do
13
- %a.btn.btn-default{ href: "#{settings.map_path}/users/profile" } My Account
14
- %button.btn.btn-default{ type: 'submit' }
15
- / %i.ti-panel
16
- Logout
17
- - else
18
- %ul.nav.navbar-top-links.navbar-right
19
- %li
20
- %a.btn.btn-link{ href: "#{settings.map_path}/auth/login" }
21
- Log In
22
- .navbar-default.sidebar{ role: 'navigation' }
23
- = haml :'partials/sidebar'