pure-admin-rails 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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,70 @@
1
+ #side-menu {
2
+ margin-left: -205px;
3
+ width: 205px;
4
+ position: fixed;
5
+ top: 54px;
6
+ left: 0;
7
+ bottom: 0;
8
+ z-index: 1000;
9
+ background: #3c3c3c;
10
+ overflow-y: auto;
11
+ -webkit-overflow-scrolling: touch;
12
+ border: none;
13
+ font-size: 14px;
14
+
15
+ a {
16
+ color: #aaaaaa;
17
+ border: none;
18
+ padding: 10px 0 10px 15px;
19
+ }
20
+
21
+ &.pure-menu ul {
22
+ border: none;
23
+ background: transparent;
24
+ }
25
+
26
+ &.pure-menu ul,
27
+ &.pure-menu .menu-item-divided {
28
+ border-top: 1px solid #434343;
29
+ }
30
+
31
+ &.pure-menu li a:hover,
32
+ &.pure-menu li a:focus {
33
+ background: #434343;
34
+ color: #ffffff;
35
+ }
36
+
37
+ .pure-menu-heading {
38
+ border-bottom: 1px solid #666666;
39
+ color: #fff;
40
+ margin: 0;
41
+ }
42
+
43
+ .pure-menu-selected {
44
+ background: #434343;
45
+ }
46
+
47
+ .pure-menu-selected a {
48
+ color: #fff;
49
+ }
50
+
51
+ .fa {
52
+ margin-right: 7px;
53
+ width: 1em;
54
+ }
55
+ }
56
+
57
+ .side-menu-link {
58
+ display: block;
59
+ font-size: 120%;
60
+ color: white;
61
+ cursor: pointer;
62
+ float: left;
63
+ position: relative;
64
+ top: 5px;
65
+ left: 5px;
66
+ background: #000;
67
+ padding: 5px;
68
+ padding-top: 2px;
69
+ padding-bottom: 1px;
70
+ }
@@ -0,0 +1,90 @@
1
+ #main-content,
2
+ .portlet-body {
3
+ &:after {
4
+ content: '';
5
+ pointer-events: none;
6
+ width: 100%;
7
+ height: 100%;
8
+ top: 0;
9
+ left: 0;
10
+ position: absolute;
11
+ opacity: 0;
12
+ display: block;
13
+
14
+ transition: opacity 200ms;
15
+
16
+ background-color: rgba($white, 0.75);
17
+
18
+ background-image: image-url('pending.gif');
19
+ background-position: center 5em;
20
+ background-repeat: no-repeat;
21
+ background-size: 4.5em;
22
+ }
23
+
24
+ &.loading {
25
+ position: relative;
26
+
27
+ &:after {
28
+ opacity: 1;
29
+ }
30
+ }
31
+ }
32
+
33
+ .table-filters {
34
+ padding: 0.5rem;
35
+ position: relative;
36
+ width: auto;
37
+ display: block;
38
+ margin: 0;
39
+
40
+ @media (min-width: 35.5em) {
41
+ padding-right: calc(50px + 0.5rem);
42
+ display: inline-block;
43
+ }
44
+
45
+ .filter-group {
46
+ display: block;
47
+
48
+ @media (min-width: 35.5em) {
49
+ margin-right: 1em;
50
+ float: left;
51
+ }
52
+
53
+ label {
54
+ text-transform: uppercase;
55
+ font-size: 0.9rem;
56
+ color: #999;
57
+ }
58
+
59
+ .filter-control {
60
+ height: 2.4em;
61
+ }
62
+
63
+ @media (min-width: 35.5em) {
64
+ .addon-wrapper {
65
+ display: block;
66
+
67
+ .input-addon,
68
+ .filter-control {
69
+ display: inline-block;
70
+ width: initial;
71
+ }
72
+
73
+ .input-addon {
74
+ line-height: 2.3em;
75
+ }
76
+ }
77
+ }
78
+ }
79
+
80
+ .filter-submit {
81
+ margin-right: 0;
82
+ margin-top: 0.5rem;
83
+
84
+ @media (min-width: 35.5em) {
85
+ position: absolute;
86
+ right: 0.5rem;
87
+ bottom: 0.5rem;
88
+ }
89
+ }
90
+ }
@@ -0,0 +1,70 @@
1
+ .pure-table {
2
+ margin: 0.5em 0;
3
+ width: 100%;
4
+ background: #fff;
5
+ border: 1px solid #d9d9d9;
6
+ font-size: 14px;
7
+
8
+ thead {
9
+ background: #f6f6f6;
10
+ border-bottom: 1px solid #CDCDCD;
11
+ }
12
+
13
+ th {
14
+ text-align: left;
15
+ }
16
+
17
+ td {
18
+ padding: 0.4em 1em;
19
+ }
20
+ }
21
+
22
+ .pure-table-striped {
23
+ tr:nth-child(2n-1) td {
24
+ background-color: transparent;
25
+ }
26
+
27
+ tr:nth-child(even) td {
28
+ background-color: #f6f6f6;
29
+ }
30
+ }
31
+
32
+ .table-actions {
33
+ font-size: 0.8em;
34
+ text-align: right;
35
+
36
+ .pure-button {
37
+ padding: 0.4em 1em;
38
+ position: relative;
39
+ top: 1px;
40
+ }
41
+ }
42
+
43
+ #main-title {
44
+ .table-actions {
45
+ position: relative;
46
+ right: $base-font-size * -0.4;
47
+ }
48
+ }
49
+
50
+ .table-filter {
51
+ margin-bottom: 1em;
52
+ font-size: 0.8em;
53
+
54
+ .pure-form {
55
+ margin: 0;
56
+ display: inline-block;
57
+ width: auto;
58
+
59
+ input {
60
+ display: inline-block;
61
+ width: auto;
62
+ margin: 0;
63
+ }
64
+ }
65
+
66
+ .pure-button, .pure-button[type=submit] {
67
+ padding: 0.5em 1em;
68
+ margin-left: -4px;
69
+ }
70
+ }
@@ -0,0 +1,37 @@
1
+ .tag {
2
+ background: #bbbbbb;
3
+ color: #ffffff;
4
+ text-transform: uppercase;
5
+ font-size: 10px;
6
+ padding: 5px;
7
+ padding-top: 3px;
8
+ padding-bottom: 2px;
9
+ line-height: 8px;
10
+ margin-right: 6px;
11
+ position: relative;
12
+ top: -1px;
13
+ display: inline;
14
+ min-height: 13px;
15
+
16
+ &.tag-orange {
17
+ background: #e49457;
18
+ }
19
+
20
+ &.tag-red {
21
+ background: #CC3333;
22
+ }
23
+
24
+ &.tag-green {
25
+ background: #339900;
26
+ }
27
+
28
+ &.tag-blue {
29
+ background: #4a9fc8;
30
+ }
31
+ }
32
+
33
+ .details-panel {
34
+ .tag {
35
+ top: -2px;
36
+ }
37
+ }
@@ -0,0 +1,24 @@
1
+ .text-success {
2
+ color: $text-success;
3
+ }
4
+
5
+ .text-notice {
6
+ color: $text-notice;
7
+ }
8
+
9
+ .text-alert {
10
+ color: $text-alert;
11
+ }
12
+
13
+ .text-error {
14
+ color: $text-error;
15
+ }
16
+
17
+ .text-muted {
18
+ color: $text-muted;
19
+
20
+ a {
21
+ color: inherit;
22
+ text-decoration: underline;
23
+ }
24
+ }
@@ -0,0 +1,38 @@
1
+ // ---- TYPOGRAPHY ----
2
+ $base-font-size: 16px;
3
+
4
+ // ---- COLOURS ----
5
+ $white: #fff;
6
+ $black: #000;
7
+
8
+ $text-color: #555;
9
+
10
+ $menu-color: #50a8d1;
11
+
12
+ $link-color: #50a8d1;
13
+
14
+ $grey-light: #efefef;
15
+ $grey-medium: #d9d9d9;
16
+ $grey-medium-dark: #cdcdcd;
17
+ $grey-dark: #aaa;
18
+
19
+ $text-success: #3c763d;
20
+ $background-success: #c2e6b3;
21
+ $border-success: #acd69a;
22
+
23
+ $text-notice: #31708f;
24
+ $background-notice: #bbdbeb;
25
+ $border-notice: #a8cde0;
26
+
27
+ $text-alert: #8a6d3b;
28
+ $background-alert: #ece7cd;
29
+ $border-alert: #ddd6b2;
30
+
31
+ $text-error: #a94442;
32
+ $background-error: #e9c5c5;
33
+ $border-error: #deb0b0;
34
+
35
+ $text-muted: $grey-dark;
36
+
37
+ $input-border: #ccc;
38
+ $input-active: #4a9fc8;
@@ -0,0 +1,12 @@
1
+ ##
2
+ # Generic helper methods to be used throughout the Pure application.
3
+ module PureAdmin::ApplicationHelper
4
+ ##
5
+ # Merges two values into a new array while flattening and removing nils.
6
+ # @param value1 (String, Array)
7
+ # @param value2 (String, Array)
8
+ # @return (Array)
9
+ def merge_html_classes(value1, value2)
10
+ [value1, value2].flatten.compact
11
+ end
12
+ end
@@ -0,0 +1,58 @@
1
+ ##
2
+ # Helper methods to render buttons.
3
+ module PureAdmin::ButtonHelper
4
+ ##
5
+ # @param options (Hash) all options that can be passed to button_tag are respected here.
6
+ # @return (String) HTML for a save button.
7
+ def save_button(options = {})
8
+ options[:class] = merge_html_classes('pure-button pure-button-primary', options[:class])
9
+ options[:type] ||= :submit
10
+ button_tag('<i class="fa fa-fw fa-check"></i> Save'.html_safe, options)
11
+ end
12
+
13
+ ##
14
+ # @param path (String, Array) the path for the edit button
15
+ # @param options (Hash) all options that can be passed to link_to are respected here.
16
+ # @return (String) HTML for the edit button.
17
+ def edit_button(path, options = {})
18
+ options[:class] = merge_html_classes('pure-button pure-button-primary', options[:class])
19
+ link_to('<i class="fa fa-pencil"></i> Edit'.html_safe, path, options)
20
+ end
21
+
22
+ ##
23
+ # @param path (String, Array) the path for the back button
24
+ # @param options (Hash) all options that can be passed to link_to are respected here.
25
+ # @return (String) HTML for the back button.
26
+ def back_button(path = nil, options = {})
27
+ options[:class] = merge_html_classes('pure-button', options[:class])
28
+ link_to('Back', (path || :back), options)
29
+ end
30
+
31
+ ##
32
+ # @param path (String, Array) the path for the back button
33
+ # @param options (Hash) all options that can be passed to link_to are respected here.
34
+ # @return (String) HTML for the cancel button.
35
+ def cancel_button(path = nil, options = {})
36
+ options[:class] = merge_html_classes('pure-button', options[:class])
37
+ link_to('<i class="fa fa-ban"></i> Cancel'.html_safe, (path || :back), options)
38
+ end
39
+
40
+ ##
41
+ # @param path (String, Array) the path for the delete button
42
+ # @param options (Hash) all options that can be passed to link_to are respected here.
43
+ # @options options :label the label for the delete button
44
+ # @options options :icon the icon for the delete button
45
+ # @return (String) HTML for the delete button.
46
+ def delete_button(path, options = {})
47
+ options[:class] = merge_html_classes('pure-button button-red', options[:class])
48
+ options[:rel] ||= :modal
49
+ options[:modal] ||= :confirm
50
+ options[:data] ||= {}
51
+ options[:data][:modal_request_method] ||= :delete
52
+
53
+ label = options.delete(:label) || 'Delete'
54
+ icon = options.delete(:icon) || 'fa-trash-o'
55
+
56
+ link_to("<i class='fa #{icon}'></i> #{label}".html_safe, path, options)
57
+ end
58
+ end
@@ -0,0 +1,121 @@
1
+ ##
2
+ # Helper methods for the details panel.
3
+ module PureAdmin::DetailsPanelHelper
4
+ ##
5
+ # Renders a "details panel" to the view.
6
+ # @param options (Hash) all options that can be passed to content_tag are respected here.
7
+ # @yield The contents of the details panel
8
+ def details_panel(options = {}, &block)
9
+ options[:class] = merge_html_classes('pure-g details-panel', options[:class])
10
+ content_tag(:div, options, &block)
11
+ end
12
+
13
+ ##
14
+ # Renders a "details panel heading" to the view.
15
+ # @param title (String)
16
+ # @param options (Hash) all options that can be passed to content_tag are respected here.
17
+ # @yield The contents of the details panel heading
18
+ def details_panel_heading(title = nil, options = nil, &block)
19
+ options, title = title, capture(&block) if block_given?
20
+ options = options || {}
21
+ options[:class] = merge_html_classes('pure-u details-panel-heading', options[:class])
22
+ content_tag(:h4, title, options)
23
+ end
24
+
25
+ ##
26
+ # Renders a "details panel item" to the view.
27
+ # @param label (String, Symbol)
28
+ # @param value (Any)
29
+ # @param options (Hash) all options that can be passed to content_tag are respected here.
30
+ # @yield The contents of the details panel item
31
+ def details_panel_item(label, value = nil, options = nil, &block)
32
+ options, value = value, capture(&block) if block_given?
33
+ options = options || {}
34
+
35
+ label = label.to_s.titleize unless label.nil? || label.respond_to?(:titleize)
36
+
37
+ item_html = options.delete(:item_html) || {}
38
+ item_html[:class] = merge_html_classes('details-panel-item pure-u-1', item_html[:class])
39
+
40
+ label_html = options.delete(:label_html) || {}
41
+
42
+ value = value.try(:to_s)
43
+ value = content_tag :span, '(blank)', class: 'text-muted' unless value.present?
44
+
45
+ content_tag(:div, item_html) do
46
+ content_tag(:label, label, label_html) + value
47
+ end
48
+ end
49
+
50
+ ##
51
+ # Renders a "details_panel_controls" element to the view.
52
+ # @param options (Hash) all options that can be passed to content_tag are respected here.
53
+ # @yield The contents of the details panel controls
54
+ def details_panel_controls(options = {}, &block)
55
+ options[:class] = merge_html_classes('details-panel-controls', options[:class])
56
+ content_tag(:div, capture(&block), options)
57
+ end
58
+
59
+ ##
60
+ # Renders a "details panel" to the view using the details panel builder DSL.
61
+ # @param resource (ActiveRecord::Base) the model instance to build the details panel for.
62
+ # @param options (Hash) all options that can be passed to content_tag are respected here.
63
+ # @yield The contents of the details panel
64
+ def details_panel_for(resource, options = {}, &block)
65
+ builder = DetailsPanelBuilder.new(resource, self)
66
+ details_panel(options) do
67
+ capture(builder, &block)
68
+ end
69
+ end
70
+
71
+ ##
72
+ # Allows building of details panels using a custom DSL.
73
+ #
74
+ # <%= details_panel_for @resource do |dp| %>
75
+ # <%= dp.item :title %>
76
+ # <% end %>
77
+ class DetailsPanelBuilder
78
+ ##
79
+ # The resource to build the panel for.
80
+ attr_reader :resource
81
+
82
+ ##
83
+ # Creates an instance of DetailsPanelBuilder
84
+ # @param resource (ActiveRecord::Base) the model instance to build the details panel for.
85
+ # @param helper (ApplicationHelper) instance of application helper to allow access to view helpers.
86
+ # @yield instance of DetailsPanelBuilder
87
+ def initialize(resource, helper)
88
+ @resource = resource
89
+ @helper = helper
90
+ end
91
+
92
+ ##
93
+ # Renders a "details panel item" inside the "details panel" using a custom DSL.
94
+ #
95
+ # The attribute name is used as the item label with i18n. If a block is passed a custom
96
+ # value can be given for the item. NoMethodError is thrown when the attribute is not
97
+ # present on the resource.
98
+ #
99
+ # @param attribute (Symbol) the attribute on the resource
100
+ # @param options (Hash) all options that can be passed to content_tag are respected here.
101
+ # @yield The contents of the details panel item
102
+ def item(attribute, options = {}, &block)
103
+ human_attribute_name = resource.class.human_attribute_name(attribute) if resource.respond_to?(attribute)
104
+
105
+ if block_given?
106
+ helper.details_panel_item(human_attribute_name || attribute, options, &block)
107
+ else
108
+ helper.details_panel_item(human_attribute_name || attribute, resource.send(attribute), options)
109
+ end
110
+ end
111
+
112
+ private
113
+
114
+ ##
115
+ # Access view helpers within the details panel builder
116
+ # @yield instance of ApplicationHelper
117
+ def helper
118
+ @helper
119
+ end
120
+ end
121
+ end