app_frame 0.5.5

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 (70) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +26 -0
  4. data/Gemfile.lock +181 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.md +25 -0
  7. data/Rakefile +47 -0
  8. data/VERSION +1 -0
  9. data/app/assets/javascripts/app_frame/application.js +9 -0
  10. data/app/assets/stylesheets/app_frame/_devise.scss +41 -0
  11. data/app/assets/stylesheets/app_frame/_tree.scss +31 -0
  12. data/app/assets/stylesheets/app_frame/application.scss +73 -0
  13. data/app/controllers/app_frame/devise/confirmations_controller.rb +3 -0
  14. data/app/controllers/app_frame/devise/passwords_controller.rb +3 -0
  15. data/app/controllers/app_frame/devise/registrations_controller.rb +3 -0
  16. data/app/controllers/app_frame/devise/sessions_controller.rb +3 -0
  17. data/app/helpers/app_frame/bootstrap_helper.rb +36 -0
  18. data/app/helpers/app_frame/breadcrumb_helper.rb +18 -0
  19. data/app/helpers/app_frame/menu_helper.rb +43 -0
  20. data/app/helpers/app_frame/pagination_helper.rb +12 -0
  21. data/app/helpers/app_frame/resources_helper.rb +63 -0
  22. data/app/helpers/app_frame/scopes_helper.rb +94 -0
  23. data/app/helpers/app_frame/select_helper.rb +8 -0
  24. data/app/helpers/app_frame/tree_nav_helper.rb +18 -0
  25. data/app/models/menu.rb +44 -0
  26. data/app/models/settings.rb +4 -0
  27. data/app/views/app_frame/devise/confirmations/new.html.haml +8 -0
  28. data/app/views/app_frame/devise/passwords/edit.html.haml +13 -0
  29. data/app/views/app_frame/devise/passwords/new.html.haml +8 -0
  30. data/app/views/app_frame/devise/registrations/edit.html.haml +19 -0
  31. data/app/views/app_frame/devise/registrations/new.html.haml +10 -0
  32. data/app/views/app_frame/devise/sessions/new.html.haml +12 -0
  33. data/app/views/app_frame/devise/shared/_links.html.haml +14 -0
  34. data/app/views/app_frame/devise/unlocks/new.html.haml +9 -0
  35. data/app/views/application/_brand.html.haml +1 -0
  36. data/app/views/application/_breadcrumb.html.haml +12 -0
  37. data/app/views/application/_flashes.html.haml +2 -0
  38. data/app/views/application/_form.html.haml +2 -0
  39. data/app/views/application/_head.html.haml +6 -0
  40. data/app/views/application/_secondary_menu.html.haml +3 -0
  41. data/app/views/application/_show.html.haml +5 -0
  42. data/app/views/application/_sidebar.html.haml +12 -0
  43. data/app/views/application/_sub_menu.html.haml +0 -0
  44. data/app/views/application/_table.html.haml +3 -0
  45. data/app/views/application/_toolbar.html.haml +7 -0
  46. data/app/views/application/_top_menu.html.haml +1 -0
  47. data/app/views/application/edit.html.haml +8 -0
  48. data/app/views/application/index.html.haml +8 -0
  49. data/app/views/application/new.html.haml +7 -0
  50. data/app/views/application/show.html.haml +10 -0
  51. data/app/views/kaminari/app_frame/_first_page.html.haml +9 -0
  52. data/app/views/kaminari/app_frame/_gap.html.haml +8 -0
  53. data/app/views/kaminari/app_frame/_last_page.html.haml +9 -0
  54. data/app/views/kaminari/app_frame/_next_page.html.haml +9 -0
  55. data/app/views/kaminari/app_frame/_page.html.haml +10 -0
  56. data/app/views/kaminari/app_frame/_paginator.html.haml +19 -0
  57. data/app/views/kaminari/app_frame/_prev_page.html.haml +9 -0
  58. data/app/views/layouts/app_frame/default.html.haml +33 -0
  59. data/app/views/layouts/app_frame/devise.html.haml +17 -0
  60. data/app_frame.gemspec +162 -0
  61. data/lib/app_frame.rb +27 -0
  62. data/lib/app_frame/controller_methods.rb +111 -0
  63. data/lib/app_frame/view_methods.rb +19 -0
  64. data/lib/assets/images/.gitkeep +0 -0
  65. data/lib/assets/javascripts/anytime.js +3716 -0
  66. data/lib/assets/stylesheets/anytime.css +777 -0
  67. data/lib/engine.rb +197 -0
  68. data/spec/app_frame_spec.rb +7 -0
  69. data/spec/spec_helper.rb +12 -0
  70. metadata +423 -0
@@ -0,0 +1,3 @@
1
+ class AppFrame::Devise::ConfirmationsController < Devise::ConfirmationsController
2
+ layout 'app_frame/devise'
3
+ end
@@ -0,0 +1,3 @@
1
+ class AppFrame::Devise::PasswordsController < Devise::PasswordsController
2
+ layout 'app_frame/devise'
3
+ end
@@ -0,0 +1,3 @@
1
+ class AppFrame::Devise::RegistrationsController < Devise::RegistrationsController
2
+ layout 'app_frame/devise'
3
+ end
@@ -0,0 +1,3 @@
1
+ class AppFrame::Devise::SessionsController < Devise::SessionsController
2
+ layout 'app_frame/devise'
3
+ end
@@ -0,0 +1,36 @@
1
+ module AppFrame
2
+ module BootstrapHelper
3
+ def alert(message, type = nil)
4
+ message = close_button + message
5
+ content_tag(:div, message, :class => "alert alert-#{alert_type_map(type)}")
6
+ end
7
+
8
+ def close_button
9
+ content_tag(:a, "&times;".html_safe, :class => 'close', :data => { :dismiss => "alert" })
10
+ end
11
+
12
+ def alert_type_map(type)
13
+ map = {
14
+ :alert => 'error',
15
+ :notice => 'success'
16
+ }
17
+
18
+ map[type.to_sym] || type
19
+ end
20
+
21
+ def icon(key, options = {})
22
+ css_class = "icon-#{key}"
23
+ css_class += " icon-white" if options[:invert]
24
+ content_tag(:i, '', :class => css_class).html_safe
25
+ end
26
+
27
+ def page_header(title, &block)
28
+ content = "".html_safe
29
+ content += content_tag(:div, capture(&block), :class => 'page-actions') if block_given?
30
+ content += content_tag(:h1, title)
31
+
32
+ content_tag(:div, content, :class => 'page-header')
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,18 @@
1
+ module AppFrame::BreadcrumbHelper
2
+
3
+ def breadcrumb(items = [])
4
+
5
+ yield items if block_given?
6
+
7
+ return unless items.any?
8
+
9
+ last = items.pop
10
+
11
+ result = items.map { |i| content_tag(:li, i + content_tag(:span, "/", :class => 'divider')) }
12
+ result << content_tag(:li, last, :class => 'active')
13
+
14
+ content_tag :ul, result.join().html_safe, :class => 'breadcrumb'
15
+
16
+ end
17
+
18
+ end
@@ -0,0 +1,43 @@
1
+ module AppFrame
2
+ module MenuHelper
3
+ def menu_link(key, path = '#', options = {}, &block)
4
+ active = false
5
+ highlight = options.delete(:highlights_on) || /#{path}/
6
+ dropdown = options.delete(:dropdown)
7
+
8
+ Array(highlight).each do |regex|
9
+ active = true if request.path =~ regex
10
+ end
11
+
12
+ options[:class] ||= ""
13
+ options[:class] << ' active' if active
14
+ options[:class] << ' dropdown' if dropdown
15
+ options[:class] = options[:class].present? ? options[:class].strip : nil
16
+
17
+ key = t(:"menu.#{key}") if key.is_a?(Symbol)
18
+
19
+ a_class = dropdown ? 'dropdown-toggle' : nil
20
+ ul_class = dropdown ? 'dropdown-menu' : nil
21
+
22
+ content = link_to(key, path, :class => a_class)
23
+ content += content_tag(:ul, capture(&block), :class => ul_class) if block_given?
24
+
25
+ content_tag :li, content, options
26
+ end
27
+
28
+ def content_locale_switch(obj = nil)
29
+ return unless obj.respond_to?(:translated_locales)
30
+
31
+ current_locale = (params[:content_locale] || I18n.default_locale).to_sym
32
+
33
+ locales = I18n.available_locales.map do |s|
34
+ text = s.to_s.upcase
35
+ text << "*" if obj && !obj.translated_locales.include?(s)
36
+ content_tag :li, link_to(text, url_for(:content_locale => s)), :class => current_locale == s ? 'active' : nil
37
+ end
38
+
39
+ content_tag :ul, locales.join("").html_safe, :class => 'nav nav-pills'
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,12 @@
1
+ module AppFrame::PaginationHelper
2
+
3
+ def page_range
4
+ return nil if count == 0
5
+
6
+ range_start = (page - 1) * per_page + 1
7
+ range_end = (page) * per_page
8
+ range_end = count if range_end > count
9
+
10
+ "<div class='page-range'>Displaying <strong>#{range_start} - #{range_end}</strong> of <strong>#{count}</strong> in total</div>".html_safe
11
+ end
12
+ end
@@ -0,0 +1,63 @@
1
+ module AppFrame::ResourcesHelper
2
+
3
+ def collection?
4
+ !!collection
5
+ rescue NameError
6
+ false
7
+ end
8
+
9
+ def resource?
10
+ !!resource
11
+ rescue NameError, ActiveRecord::RecordNotFound
12
+ false
13
+ end
14
+
15
+ def resource_name
16
+ if resource_class
17
+ resource_class.model_name.human
18
+ else
19
+ controller_name
20
+ end
21
+ end
22
+
23
+ def parent?
24
+ controller.respond_to?(:parent?) && controller.send(:parent?)
25
+ end
26
+
27
+ def parent_resource_class
28
+ parent.class
29
+ end
30
+
31
+ def parent_resource_name
32
+ parent_resource_class.model_name.human
33
+ end
34
+
35
+ def controller_namespaces
36
+ result = controller.class.to_s.split('::')
37
+ result.pop
38
+ result.map(&:underscore)
39
+ end
40
+
41
+ def namespaced(string)
42
+ if controller_namespaces.any?
43
+ File.join(controller_namespaces, string)
44
+ else
45
+ string
46
+ end
47
+ end
48
+
49
+ def resource_path_array
50
+ result = controller_namespaces
51
+ result << parent if parent?
52
+ result << resource
53
+ end
54
+
55
+ def parent_collection_url
56
+ return unless parent?
57
+
58
+ result = controller_namespaces
59
+ result << parent_resource_name.underscore.pluralize
60
+ polymorphic_url(result)
61
+ end
62
+
63
+ end
@@ -0,0 +1,94 @@
1
+ module AppFrame::ScopesHelper
2
+ # return all scopes configured in the controller
3
+ def scopes
4
+ controller.class.scopes_configuration || {}
5
+ end
6
+
7
+ def default_scopes
8
+ @default_scopes ||= scopes.inject({}) do |result, element|
9
+ result[element.first] = element.last if element.last[:default] == true
10
+ result
11
+ end
12
+ end
13
+
14
+ # return only the boolean scopes
15
+ def boolean_scopes
16
+ @boolean_scopes ||= scopes.inject({}) do |result, element|
17
+ result[element.first] = element.last if element.last[:type] == :boolean
18
+ result
19
+ end
20
+ end
21
+
22
+ # return only the filter (non boolean) scopes
23
+ def filter_scopes
24
+ @filter_scopes ||= scopes.inject({}) do |result, element|
25
+ result[element.first] = element.last if element.last[:type] != :boolean
26
+ result
27
+ end
28
+ end
29
+
30
+ def current_boolean_scopes
31
+ @current_boolean_scopes ||= current_scopes.inject({}) do |result, element|
32
+ result[element.first] = element.last if boolean_scopes.keys.include?(element.first)
33
+ result
34
+ end
35
+ end
36
+
37
+ def current_filter_scopes
38
+ @current_filter_scopes ||= current_scopes.inject({}) do |result, element|
39
+ result[element.first] = element.last if filter_scopes.keys.include?(element.first)
40
+ result
41
+ end
42
+ end
43
+
44
+ # create a link to a scope (or no scopes), wrapped in a list item
45
+ def scope_link(scope = nil)
46
+ if scope
47
+ as = scope[:as]
48
+ name = as.to_s.humanize
49
+ else
50
+ as = nil
51
+ name = "All"
52
+ end
53
+
54
+ link = current_filter_scopes.dup
55
+
56
+ if as
57
+ unless scope[:default]
58
+ link[as] = true
59
+ default_scopes.each { |dn, ds| link[ds[:as]] = false }
60
+ end
61
+
62
+ active = current_boolean_scopes.keys.include?(as)
63
+ else
64
+ active = current_boolean_scopes.empty?
65
+ end
66
+
67
+ # name = "#{name}: #{scope_count(scope)}"
68
+
69
+ content_tag(:li, link_to(name, link), :class => active ? 'active' : nil)
70
+ end
71
+
72
+ def scope_count(scope)
73
+ chain = controller.end_of_association_chain
74
+ chain = chain.send(scope) if scope
75
+ chain.count
76
+ end
77
+
78
+ # craete a navigation for all the boolean scopes
79
+ def scope_nav
80
+ return unless boolean_scopes.count > 0
81
+
82
+ if default_scopes.any?
83
+ result = []
84
+ else
85
+ result = [scope_link]
86
+ end
87
+
88
+ boolean_scopes.each do |name, s|
89
+ result << scope_link(s)
90
+ end
91
+
92
+ content_tag :ul, result.join("\n").html_safe, :class => 'nav nav-pills'
93
+ end
94
+ end
@@ -0,0 +1,8 @@
1
+ module AppFrame::SelectHelper
2
+ def prepopulate(association)
3
+ return [].to_json unless association
4
+
5
+ association = [association] if association.is_a?(ActiveRecord::Base)
6
+ association.map(&:to_token_hash).to_json
7
+ end
8
+ end
@@ -0,0 +1,18 @@
1
+ module AppFrame::TreeNavHelper
2
+ def tree_nav(node)
3
+ result = []
4
+ result << tree_nav_link("&uarr;", left_admin_section_page_path(parent, node), node.left_sibling)
5
+ result << tree_nav_link("&darr;", right_admin_section_page_path(parent, node), node.right_sibling)
6
+ result << tree_nav_link("&rarr;", down_admin_section_page_path(parent, node), node.left_sibling)
7
+ result << tree_nav_link("&larr;", up_admin_section_page_path(parent, node), node.parent)
8
+ result << link_to("Edit", edit_admin_section_page_path(parent, node))
9
+ yield result if block_given?
10
+ result << link_to("Delete", admin_section_page_path(parent, node), :method => :delete)
11
+ content_tag :span, result.join('').html_safe, :class => 'tree_nav'
12
+ end
13
+
14
+ def tree_nav_link(text, link, condition = true)
15
+ condition ? link_to(text.html_safe, link) : content_tag(:span, text.html_safe)
16
+ end
17
+
18
+ end
@@ -0,0 +1,44 @@
1
+ class MenuItem
2
+ attr_reader :name, :path, :namespace
3
+
4
+ def initialize(namespace, path)
5
+ @namespace = namespace
6
+ @path = path
7
+ @name = path.humanize
8
+ end
9
+
10
+ def url
11
+ "/#{namespace}/#{path}"
12
+ end
13
+ end
14
+
15
+
16
+ class Menu
17
+ attr_reader :namespace
18
+
19
+ def initialize(namespace)
20
+ @namespace = namespace
21
+ end
22
+
23
+ def routes
24
+ @routes ||= Rails.application.routes.routes
25
+ end
26
+
27
+ def menu_routes
28
+ @menu_routes ||= routes.select { |r| r.defaults[:action] == 'index' }
29
+ end
30
+
31
+ def specs
32
+ @specs ||= menu_routes.map { |r| r.path.spec }.uniq
33
+ end
34
+
35
+ def menu_items
36
+ @menu_items = []
37
+ specs.each do |s|
38
+ matches = /\/#{@namespace}\/(\w*)/.match(s.to_s)
39
+ @menu_items << matches[1] if matches
40
+ end
41
+ @menu_items.uniq.map { |i| MenuItem.new(@namespace, i) }
42
+ end
43
+
44
+ end
@@ -0,0 +1,4 @@
1
+ class Settings < Settingslogic
2
+ source "#{Rails.root}/config/application.yml"
3
+ namespace Rails.env
4
+ end
@@ -0,0 +1,8 @@
1
+ = page_header "Resend confirmation instructions"
2
+
3
+ = simple_form_for(resource, :as => resource_name, :url => confirmation_path(resource_name), :html => { :method => :post }) do |f|
4
+ = f.error_notification
5
+
6
+ = f.input :email, :required => true
7
+
8
+ = f.button :submit, "Resend confirmation instructions", :class => 'btn'
@@ -0,0 +1,13 @@
1
+ = page_header "Change your password"
2
+
3
+ = simple_form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :put }) do |f|
4
+ = f.error_notification
5
+
6
+ = f.input :reset_password_token, :as => :hidden
7
+ = f.full_error :reset_password_token
8
+
9
+ = f.input :password, :label => "New password", :required => true
10
+ = f.input :password_confirmation, :label => "Confirm your new password", :required => true
11
+
12
+ = f.button :submit, "Change my password"
13
+
@@ -0,0 +1,8 @@
1
+ =page_header "Forgot your password?"
2
+
3
+ = simple_form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post }) do |f|
4
+ = f.error_notification
5
+
6
+ = f.input :email, :required => true
7
+
8
+ = f.button :submit, "Send", :class => 'btn'
@@ -0,0 +1,19 @@
1
+ = page_header "Edit #{resource_name.to_s.humanize}"
2
+
3
+ = simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f|
4
+ = f.error_notification
5
+
6
+ = f.input :email, :required => true, :autofocus => true
7
+ = f.input :password, :hint => "leave it blank if you don't want to change it", :required => false
8
+ = f.input :password_confirmation, :required => false
9
+ = f.input :current_password, :hint => "we need your current password to confirm your changes", :required => true
10
+
11
+ = f.button :submit, "Update", :class => 'btn'
12
+
13
+ %h3 Cancel my account<
14
+
15
+ %p
16
+ Unhappy?
17
+ = link_to "Cancel my account", registration_path(resource_name), :confirm => "Are you sure?", :method => :delete
18
+
19
+ = link_to "Back", :back, :class => 'btn'
@@ -0,0 +1,10 @@
1
+ = page_header "Sign up"
2
+
3
+ = simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f|
4
+ = f.error_notification
5
+
6
+ = f.input :email, :required => true, :autofocus => true
7
+ = f.input :password, :required => true
8
+ = f.input :password_confirmation, :required => true
9
+
10
+ = f.button :submit, "Sign up", :class => 'btn'
@@ -0,0 +1,12 @@
1
+ =page_header "Sign in"
2
+
3
+ = simple_form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f|
4
+ = f.input :email, :required => false, :autofocus => true
5
+ = f.input :password, :required => false
6
+
7
+ - if devise_mapping.rememberable?
8
+ = f.label :remember_me, :class => 'checkbox' do
9
+ = f.check_box :remember_me
10
+ Remember me
11
+
12
+ = f.button :submit, "Sign in", :class => 'btn'