pure-admin-rails 2.0.0

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 (66) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +131 -0
  4. data/app/assets/images/menu-fade-left.png +0 -0
  5. data/app/assets/images/menu-fade-right.png +0 -0
  6. data/app/assets/images/pending.gif +0 -0
  7. data/app/assets/javascripts/pure_admin.js +6 -0
  8. data/app/assets/javascripts/pure_admin/dropdown.js +178 -0
  9. data/app/assets/javascripts/pure_admin/flash_messages.js +13 -0
  10. data/app/assets/javascripts/pure_admin/inputs.js +24 -0
  11. data/app/assets/javascripts/pure_admin/inputs/select.js +21 -0
  12. data/app/assets/javascripts/pure_admin/main_header.js +21 -0
  13. data/app/assets/javascripts/pure_admin/main_menu.js +108 -0
  14. data/app/assets/javascripts/pure_admin/modals.js +228 -0
  15. data/app/assets/javascripts/pure_admin/partial_refresh.js +92 -0
  16. data/app/assets/javascripts/pure_admin/portlets.js +139 -0
  17. data/app/assets/javascripts/pure_admin/tabs.js +14 -0
  18. data/app/assets/stylesheets/pure_admin.css.scss +23 -0
  19. data/app/assets/stylesheets/pure_admin/_dropdowns.scss +58 -0
  20. data/app/assets/stylesheets/pure_admin/_tabs.scss +76 -0
  21. data/app/assets/stylesheets/pure_admin/auth.css.scss +22 -0
  22. data/app/assets/stylesheets/pure_admin/breadcrumbs.css.scss +69 -0
  23. data/app/assets/stylesheets/pure_admin/buttons.css.scss +48 -0
  24. data/app/assets/stylesheets/pure_admin/details_panels.css.scss +99 -0
  25. data/app/assets/stylesheets/pure_admin/flash_messages.css.scss +97 -0
  26. data/app/assets/stylesheets/pure_admin/forms.css.scss +129 -0
  27. data/app/assets/stylesheets/pure_admin/inputs/select.css.scss +99 -0
  28. data/app/assets/stylesheets/pure_admin/jquery.tagsinput.css.scss +67 -0
  29. data/app/assets/stylesheets/pure_admin/main_menu.css.scss +146 -0
  30. data/app/assets/stylesheets/pure_admin/modals.css.scss +122 -0
  31. data/app/assets/stylesheets/pure_admin/pagination.css.scss +67 -0
  32. data/app/assets/stylesheets/pure_admin/portlets.css.scss +154 -0
  33. data/app/assets/stylesheets/pure_admin/scopes.css.scss +44 -0
  34. data/app/assets/stylesheets/pure_admin/shell.css.scss +222 -0
  35. data/app/assets/stylesheets/pure_admin/side_menu.css.scss +70 -0
  36. data/app/assets/stylesheets/pure_admin/table_filters.css.scss +90 -0
  37. data/app/assets/stylesheets/pure_admin/tables.css.scss +70 -0
  38. data/app/assets/stylesheets/pure_admin/tags.css.scss +37 -0
  39. data/app/assets/stylesheets/pure_admin/utilities.css.scss +24 -0
  40. data/app/assets/stylesheets/pure_admin/variables.css.scss +38 -0
  41. data/app/helpers/pure_admin/application_helper.rb +12 -0
  42. data/app/helpers/pure_admin/button_helper.rb +58 -0
  43. data/app/helpers/pure_admin/details_panel_helper.rb +121 -0
  44. data/app/helpers/pure_admin/dropdown_helper.rb +40 -0
  45. data/app/helpers/pure_admin/menu_helper.rb +120 -0
  46. data/app/helpers/pure_admin/portlet_helper.rb +75 -0
  47. data/app/helpers/pure_admin/table_filters_helper.rb +158 -0
  48. data/app/inputs/addon_input.rb +17 -0
  49. data/app/inputs/collection_select_input.rb +17 -0
  50. data/app/inputs/email_input.rb +5 -0
  51. data/app/inputs/tel_input.rb +5 -0
  52. data/lib/generators/pure_admin/layout/USAGE +10 -0
  53. data/lib/generators/pure_admin/layout/layout_generator.rb +8 -0
  54. data/lib/generators/pure_admin/layout/templates/admin.css.scss +8 -0
  55. data/lib/generators/pure_admin/layout/templates/admin.html.erb +105 -0
  56. data/lib/generators/pure_admin/scaffold/USAGE +11 -0
  57. data/lib/generators/pure_admin/scaffold/scaffold_generator.rb +66 -0
  58. data/lib/generators/pure_admin/scaffold/templates/_form.html.erb +12 -0
  59. data/lib/generators/pure_admin/scaffold/templates/_show.html.erb +11 -0
  60. data/lib/generators/pure_admin/scaffold/templates/_table.html.erb +21 -0
  61. data/lib/generators/pure_admin/scaffold/templates/models_controller.rb +69 -0
  62. data/lib/generators/pure_admin/simple_form/USAGE +8 -0
  63. data/lib/generators/pure_admin/simple_form/simple_form_generator.rb +7 -0
  64. data/lib/pure-admin-rails.rb +8 -0
  65. data/lib/pure-admin-rails/version.rb +5 -0
  66. metadata +261 -0
@@ -0,0 +1,40 @@
1
+ ##
2
+ # Helper methods for dropdown functionality.
3
+ #
4
+ # The recommended way of using this helper is
5
+ #
6
+ # dropdown 'Tools', class: ''do
7
+ # dropdown_item :name, 'url', item_html: { class: '' }
8
+ # end
9
+ #
10
+ # @note this helper depends {PureAdmin::MenuHelper}
11
+ module PureAdmin::DropdownHelper
12
+ ##
13
+ # Renders a dropdown to the view.
14
+ # @param name (String) the name to display on the main dropdown link.
15
+ # @param options (Hash) all options that can be passed to the menu_helper as menu_html are
16
+ # respected here.
17
+ # @yield The contents for the dropdown
18
+ def dropdown(name, options = {}, &block)
19
+ opts = {}
20
+ opts[:menu_html] = options
21
+ opts[:menu_html][:class] = merge_html_classes('dropdown pure-menu-horizontal', opts[:class])
22
+
23
+ content = capture(&block)
24
+ content = content_tag(:ul, content, class: 'pure-menu-children')
25
+ content = content_tag(:li, link_to(name, '', class: 'pure-menu-link') + content,
26
+ class: 'pure-menu-item pure-menu-has-children')
27
+
28
+ menu(opts) { content }
29
+ end
30
+
31
+ ##
32
+ # Renders a dropdown item to the view.
33
+ # @param name (String) the name to pass to PureAdmin::MenuHelper.menu_item_and_link
34
+ # @param name (url) the url to pass to PureAdmin::MenuHelper.menu_item_and_link
35
+ # @param name (Hash) the options to pass to PureAdmin::MenuHelper.menu_item_and_link
36
+ # @yield the content to pass to PureAdmin::MenuHelper.menu_item_and_link
37
+ def dropdown_item(name = nil, url = nil, options = nil, &block)
38
+ menu_item_and_link(name, url, options, &block)
39
+ end
40
+ end
@@ -0,0 +1,120 @@
1
+
2
+ ##
3
+ # Helper methods to assist in building the Pure Admin menu.
4
+ module PureAdmin::MenuHelper
5
+ ##
6
+ # Renders a pure menu wrapper to the view.
7
+ # @param options (Hash) a container for options to be passed to menus and menu lists.
8
+ # @param options[:menu_html] (Hash) all options that can be passed to content_tag are respected here.
9
+ # @param options[:list_html] (Hash) all options that can be passed to content_tag are respected here.
10
+ # @yield The contents of the menu panel
11
+ def menu(options = {}, &block)
12
+ menu_html = options.delete(:menu_html) || {}
13
+ menu_html[:class] = merge_html_classes('pure-menu', menu_html[:class])
14
+
15
+ list_html = options.delete(:list_html) || {}
16
+ list_html[:class] = merge_html_classes('pure-menu-list', list_html[:class])
17
+
18
+ content_tag(:nav, menu_html) do
19
+ content_tag(:ul, '', list_html, &block)
20
+ end
21
+ end
22
+
23
+ ##
24
+ # Renders a pure sub-menu to the view.
25
+ # @param options (Hash) all options that can be passed to content_tag are respected here.
26
+ # @yield The contents of the menu panel
27
+ def sub_menu(options = {}, &block)
28
+ options[:class] = merge_html_classes('pure-menu-list sub-menu', options[:class])
29
+ content_tag(:ul, '', options, &block)
30
+ end
31
+
32
+ ##
33
+ # Renders a "menu link" to the view.
34
+ # @param name (String, Symbol)
35
+ # @param url (String, Array)
36
+ # @param options (Hash) all options that can be passed to link_to are respected here.
37
+ def menu_link(name = nil, url = nil, options = nil, &block)
38
+ options, url, name = url, name, capture(&block) if block_given?
39
+ options ||= {}
40
+
41
+ name = name.to_s.titleize unless block_given? || name.respond_to?(:titleize)
42
+
43
+ options[:class] = merge_html_classes('pure-menu-link', options[:class])
44
+
45
+ url.present? ? link_to(name, url, options) : content_tag(:span, name, options)
46
+ end
47
+
48
+ ##
49
+ # Renders a "menu item" to the view.
50
+ # @param options (Hash) all options that can be passed to content_tag are respected here.
51
+ def menu_item(options = {}, &block)
52
+ options[:class] = merge_html_classes('pure-menu-item', options[:class])
53
+ options[:class] << 'current' if options.delete(:current)
54
+
55
+ condition = options.key?(:if) ? options.delete(:if) : true
56
+ condition = !options.delete(:unless) if options.key?(:unless)
57
+
58
+ content_tag(:li, capture(&block), options) if condition
59
+ end
60
+
61
+ ##
62
+ # Renders a "menu item" and "menu link" to the view.
63
+ # @param name (String, Symbol)
64
+ # @param url (String, Array)
65
+ # @param options (Hash) a container for options to be passed to menu items and links.
66
+ # @param options[:item_html] (Hash) all options that can be passed to content_tag are respected here.
67
+ # @param options[:link_html] (Hash) all options that can be passed to link_to are respected here.
68
+ def menu_item_and_link(name = nil, url = nil, options = nil, &block)
69
+ options, url, name = url, name, capture(&block) if block_given?
70
+ options ||= {}
71
+
72
+ item_html = options.delete(:item_html) || {}
73
+ item_html[:class] = merge_html_classes('pure-menu-item', item_html[:class])
74
+ item_html[:if] = options[:if] if options.key?(:if)
75
+ item_html[:unless] = options[:unless] if options.key?(:unless)
76
+ item_html[:current] = true if current_menu_item?(url)
77
+
78
+ link_html = options.delete(:link_html) || {}
79
+
80
+ menu_item(item_html) do
81
+ menu_link(name, url, link_html)
82
+ end
83
+ end
84
+
85
+ ##
86
+ # Check if the menu item is currently active
87
+ # @param url (String) the menu item's URL.
88
+ def current_menu_item?(url)
89
+ return false unless url
90
+
91
+ begin
92
+ menu_item_path = URI.parse(url).try(:path)
93
+ rescue
94
+ menu_item_path = nil
95
+ end
96
+
97
+ return false unless menu_item_path
98
+
99
+ # only match roots on exact match
100
+ return request.original_fullpath == menu_item_path
101
+ end
102
+
103
+ ##
104
+ # Check if the menu item is currently active. Is active if it is parent or current.
105
+ # @param url (String) the menu item's URL.
106
+ def current_parent?(url)
107
+ return false unless url
108
+
109
+ begin
110
+ menu_item_path = URI.parse(url).try(:path)
111
+ rescue
112
+ menu_item_path = nil
113
+ end
114
+
115
+ return false unless menu_item_path
116
+
117
+ # match all other items to start of original_fullpath
118
+ return request.original_fullpath =~ /^#{Regexp.escape(menu_item_path)}(\/|$)/
119
+ end
120
+ end
@@ -0,0 +1,75 @@
1
+ ##
2
+ # Helper methods to assist in building Pure Admin portlets.
3
+ module PureAdmin::PortletHelper
4
+ ##
5
+ # Renders a "portlet" to the view.
6
+ # @param title (String)
7
+ # @param options (Hash) a container for options to the portlet.
8
+ # @param options[:portlet_html] (Hash) all options that can be passed to content_tag are respected here.
9
+ # @param options[:heading_html] (Hash) all options that can be passed to content_tag are respected here.
10
+ # @param options[:body_html] (Hash) all options that can be passed to content_tag are respected here.
11
+ # @yield The contents of the portlet
12
+ def portlet(title, options = {}, &block)
13
+ portlet_html = options[:portlet_html] || {}
14
+ portlet_html[:class] = ['portlet clear-fix', portlet_html[:class]]
15
+ portlet_html[:data] ||= {}
16
+ portlet_html[:data][:source] = options[:source] unless block_given?
17
+
18
+ heading_html = options.delete(:heading_html) || {}
19
+ heading_html[:class] = merge_html_classes('portlet-heading', heading_html[:class])
20
+
21
+ body_html = options.delete(:body_html) || {}
22
+ body_html[:class] = merge_html_classes('portlet-body clear-fix', body_html[:class])
23
+
24
+ if options[:icon]
25
+ icon = content_tag(:i, nil, class: "portlet-heading-icon fa fa-fw fa-#{options[:icon].to_s.dasherize}")
26
+ end
27
+
28
+ # This determines if the portlet can be closed. If it is remote it can be closed. If not,
29
+ # it is determined by the presence of expand in the options.
30
+ # e.g. <%= portlet 'A title', expand: true do %>...
31
+ closable = options.key?(:source) || options.key?(:expand)
32
+
33
+ portlet_html[:data][:closable] = closable
34
+
35
+ controls_content = ''.html_safe
36
+ controls = options.delete(:controls)
37
+ if controls.present?
38
+ if controls.respond_to?(:each)
39
+ controls.each do |control|
40
+ controls_content << content_tag(:span, control, class: 'portlet-control-item')
41
+ end
42
+ else
43
+ controls_content << content_tag(:span, controls, class: 'portlet-control-item')
44
+ end
45
+ end
46
+
47
+ if closable
48
+ controls_content << content_tag(:span, nil, class: 'portlet-indicator')
49
+ end
50
+
51
+ if controls_content.present?
52
+ controls_wrapper = content_tag(:div, controls_content, class: 'portlet-controls')
53
+ end
54
+
55
+ # This determines if the portlet should be expanded by default. If it is explicitly given that
56
+ # takes precedence. If not, by default all remote portlets are not expanded and all static
57
+ # portlets are.
58
+ expand = options.key?(:expand) ? options[:expand] : block_given?
59
+
60
+ if expand
61
+ portlet_html[:class] << 'expanded'
62
+ portlet_html[:data][:expand] = true
63
+ end
64
+
65
+ heading_content = content_tag(:div, heading_html) do
66
+ (icon || ''.html_safe) + content_tag(:h4, title) + (controls_wrapper || ''.html_safe)
67
+ end
68
+
69
+ body_content = content_tag(:div, (capture(&block) if block_given?), body_html)
70
+
71
+ content_tag(:div, portlet_html) do
72
+ heading_content + body_content
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,158 @@
1
+ ##
2
+ # Helper methods for table filters functionality.
3
+ #
4
+ # The recommended way of using this helper is
5
+ #
6
+ # filters_for admin_members_path do |filter|
7
+ # filter.on :query the default is a text field
8
+ # filter.on :answer, options: %w(Yes No) if given an options hash, a select will be used
9
+ # filter.on :status, as: :active_status when given :active_status it will use the options
10
+ # All, Active, and Inactive and the default of
11
+ # Active. However these can be overridden by
12
+ # :options and :default respectively.
13
+ # filter.on :starts_on, as: :date when given :date, it will enable the pure_date
14
+ # input type
15
+ # end
16
+ module PureAdmin::TableFiltersHelper
17
+ ##
18
+ # Renders the table filters form to the view.
19
+ # @param path (String) the path for the form_tag
20
+ # @param options (Hash) all options that can be passed to form_tag are respected here.
21
+ # @yield The contents for the table filters
22
+ def table_filters(path, options = {}, &block)
23
+ options[:class] = merge_html_classes('pure-form pure-form-stacked table-filters
24
+ js-partial-refresh clear-fix', options[:class])
25
+
26
+ options[:remote] = false || options[:remote]
27
+ options[:method] ||= :get
28
+
29
+ content = capture(&block)
30
+
31
+ if content
32
+ content << content_tag(:div, submit_tag('Go', class: 'pure-button pure-button-primary'),
33
+ class: 'filter-group filter-submit')
34
+ content << hidden_field_tag(:sort, params[:sort])
35
+ content << hidden_field_tag(:reverse_order, params[:reverse_order])
36
+
37
+ form_tag path, options do
38
+ content
39
+ end
40
+ end
41
+ end
42
+
43
+ ##
44
+ # Renders a table filter item to the view.
45
+ # @param attribute (String, Symbol)
46
+ # @param options (Hash)
47
+ # @options options (Symbol) :type the type of field to display
48
+ # @options options (Hash) :options the select options for select inputs
49
+ # @options options (String) :default the default select option for select inputs
50
+ # @options options (Hash) :input_html any data contained within this hash will be passed to
51
+ # the appropriate *_tag method
52
+ # @options options (Boolean, String) :label the text to display as a label if a string. If false,
53
+ # this will prevent the label from being shown
54
+ # @options options (Hash) :label_html any data contained within this hash will be passed to
55
+ # the content_tag builder for the label
56
+ # @yield The contents of the table filter with the label (unless options[:label] is false)
57
+ def table_filter_item(attribute, options = {}, &block)
58
+ if block_given?
59
+ field = capture(&block)
60
+ else
61
+ type = options.delete(:as) || :string
62
+
63
+ # If we're given an options array, we assume it to be a select filter.
64
+ # This allows for more concise code in the form
65
+ # table_filter_item :status, options: %w(Yes No)
66
+ # or
67
+ # filter.on :status, options %W(Yes No)
68
+ type = :select if options[:options].present?
69
+
70
+ # We define the :active_status type to shortcut a common filter type.
71
+ if type == :active_status
72
+ type = :select
73
+ options[:options] ||= %w(All Active Inactive)
74
+ options[:default] ||= 'Active'
75
+ end
76
+
77
+ input_html = options.delete(:input_html) || {}
78
+ input_html[:class] = merge_html_classes('filter-control', input_html[:class])
79
+
80
+ # Defaulting to a simple text field, we choose which field to output here.
81
+ # @note if at some point we wish to add a new field type, here is the place to add it
82
+ case type
83
+ when :select
84
+ options[:options] ||= []
85
+ field = select_tag(attribute,
86
+ options_for_select(options[:options], params[attribute.to_sym] || options[:default]),
87
+ input_html)
88
+ when :date
89
+ input_html[:class] = merge_html_classes('pure-admin-date', input_html[:class])
90
+ field = text_field_tag(attribute, params[attribute.to_sym], input_html)
91
+ icon = content_tag(:span, nil, class: 'input-addon fa fa-fw fa-calendar')
92
+ field = content_tag(:div, icon + field, class: 'addon-wrapper')
93
+ else # :string
94
+ field = text_field_tag(attribute, params[attribute.to_sym], input_html)
95
+ end
96
+ end
97
+
98
+ label = ''.html_safe
99
+ if options[:label] != false
100
+ label_html = options.delete(:label_html) || {}
101
+ label_text = options.delete(:label) || attribute.to_s.titleize
102
+ label = label_tag(attribute, label_text, label_html)
103
+ end
104
+
105
+ content_tag(:div, label + field, class: 'filter-group')
106
+ end
107
+
108
+ ##
109
+ # Renders a table filters section to the view using the table filter builder DSL.
110
+ # @param resource (ActiveRecord::Base) the model instance to build the table filters for.
111
+ # @param options (Hash) all options that can be passed to content_tag are respected here.
112
+ # @yield The contents of the table filters section
113
+ def filters_for(path, options = {}, &block)
114
+ builder = TableFiltersBuilder.new(self)
115
+ table_filters(path, options) do
116
+ capture(builder, &block)
117
+ end
118
+ end
119
+
120
+ ##
121
+ # Allows building of table filters using a custom DSL.
122
+ #
123
+ # <%= filters_for resources_path do |filter| %>
124
+ # <%= filter.on :query %>
125
+ # <% end %>
126
+ class TableFiltersBuilder
127
+ ##
128
+ # Creates an instance of TableFiltersBuilder
129
+ # @param helper (ApplicationHelper) instance of application helper to allow access to view helpers.
130
+ # @yield instance of TableFiltersBuilder
131
+ def initialize(helper)
132
+ @helper = helper
133
+ end
134
+
135
+ ##
136
+ # Renders a table_filter_item inside the table_filters using a custom DSL.
137
+ #
138
+ # @param attribute (Symbol) the attribute on the resource
139
+ # @param options (Hash) all options that can be passed to content_tag are respected here.
140
+ # @yield The contents of the details panel item
141
+ def on(attribute, options = {}, &block)
142
+ if block_given?
143
+ helper.table_filter_item(attribute, options, &block)
144
+ else
145
+ helper.table_filter_item(attribute, options)
146
+ end
147
+ end
148
+
149
+ private
150
+
151
+ ##
152
+ # Access view helpers within the details panel builder
153
+ # @yield instance of ApplicationHelper
154
+ def helper
155
+ @helper
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,17 @@
1
+ ##
2
+ # Overrides the :email input type to add a default prefix.
3
+ class AddonInput < SimpleForm::Inputs::StringInput
4
+ extend PureAdmin::ApplicationHelper
5
+
6
+ def icon
7
+ if options[:icon].present?
8
+ template.content_tag(:span, nil, class: ['input-addon', 'fa', 'fa-fw', options[:icon]])
9
+ else
10
+ ''
11
+ end
12
+ end
13
+
14
+ def input(wrapper_options = nil)
15
+ icon + super(wrapper_options)
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ ##
2
+ # Overrides SimpleForm's default CollectionSelectInput to add a class.
3
+ # This class is then used to initialise Select2 on all collection select inputs.
4
+ class CollectionSelectInput < SimpleForm::Inputs::CollectionSelectInput
5
+ def input_html_classes
6
+ super.push('pure-admin-select')
7
+ end
8
+
9
+ def input_html_options
10
+ super.deep_merge(
11
+ style: 'width: 100%;',
12
+ data: {
13
+ tags: options[:create_when_no_match] || false
14
+ }
15
+ )
16
+ end
17
+ end
@@ -0,0 +1,5 @@
1
+ ##
2
+ # Overrides the :email input type to add a default prefix.
3
+ class EmailInput < AddonInput
4
+ self.default_options = { icon: 'fa-envelope' }
5
+ end
@@ -0,0 +1,5 @@
1
+ ##
2
+ # Overrides the :tel input type to add a default prefix.
3
+ class TelInput < AddonInput
4
+ self.default_options = { icon: 'fa-phone' }
5
+ end
@@ -0,0 +1,10 @@
1
+ Description:
2
+ This will generate skeleton layout files that you will need to modify to suit your application.
3
+
4
+ Example:
5
+ rails generate pure_admin:layout
6
+
7
+ This will create:
8
+ app/views/layouts/admin.html.erb
9
+ app/assets/stylesheets/admin.css.scss
10
+