awesome_admin_layout 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 44af5363829a9f03c57f66666cfce21f3d192dba
4
+ data.tar.gz: 1a86d7dc0d4606815f023ef30eac8e8add690efa
5
+ SHA512:
6
+ metadata.gz: 4f43a317f0986eb4d7629eecfa5c530548ddd7883207d36324e5fd2d605b2905d6b09cae6df41a1215c4652bd24ca986f726b97fcca696e224740fb4ea5e28c1
7
+ data.tar.gz: e2c0cc6e8e0426f6de9220d0b23c352daab232f1d2145915ef81a708e6ca490872d00f37087995a0216c7b2d4666d9772af084a7881ae6b9c68ea037008d0d12
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /test/dummy/.sass-cache/
10
+ /tmp/
11
+ /vendor/bundle/
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.2
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ## AwesomeAdminLayout 0.4.2 (June 08, 2015) ##
2
+
3
+ * Initialize this gem.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in awesome_admin_layout.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,200 @@
1
+ # AwesomeAdminLayout
2
+
3
+ AwesomeAdminLayout provides a simple way to add admin panel layout to your application.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'awesome_admin_layout'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ ```sh
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+
21
+ ```sh
22
+ $ gem install awesome_admin_layout
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ - [Ruby on Rails](#a-ruby-on-rails)
28
+ - [Sinatra](#b-sinatra)
29
+
30
+ ### a. Ruby on Rails
31
+
32
+ 1. Install [font-awesome-rails](https://github.com/bokmann/font-awesome-rails) and [jquery-rails](https://github.com/rails/jquery-rails).
33
+
34
+ 2. Import a style in `app/assets/stylesheets/application.scss`:
35
+
36
+ ```scss
37
+ @import "awesome_admin_layout";
38
+ ```
39
+
40
+ 3. Require a script in `app/assets/javascripts/application.coffee`:
41
+
42
+ ```coffee
43
+ #= require awesome_admin_layout
44
+ ```
45
+
46
+ 4. Create a file named `awesome_admin_layout.rb` in `config/initializers`.
47
+ And writing the definitions as follows:
48
+
49
+ ```ruby
50
+ #
51
+ # NOTE: if you only use this layout in admin controller,
52
+ # you can write like this:
53
+ #
54
+ # `AwesomeAdminLayout.setup(only: Admin::ApplicationController)`
55
+ #
56
+ AwesomeAdminLayout.setup do |controller|
57
+ navigation do
58
+ brand 'AwesomeAdminLayout' do
59
+ external_link controller.root_path
60
+ end
61
+
62
+ item 'Dashboard' do
63
+ link controller.dashboard_path
64
+ icon 'dashboard'
65
+ end
66
+
67
+ item 'Orders' do
68
+ link controller.orders_path
69
+ icon 'shopping-cart'
70
+ active true
71
+ end
72
+
73
+ item 'Products' do
74
+ nest :products
75
+ icon 'cube'
76
+ badge true
77
+ end
78
+
79
+ item 'Users' do
80
+ link controller.users_path
81
+ icon 'user'
82
+ end
83
+
84
+ item 'Promotions' do
85
+ link controller.promotions_path
86
+ icon 'bullhorn'
87
+ end
88
+
89
+ item 'Analytics' do
90
+ link controller.analytics_path
91
+ icon 'bar-chart'
92
+ badge true
93
+ end
94
+
95
+ divider
96
+
97
+ item 'Store' do
98
+ nest :store
99
+ icon 'home'
100
+ end
101
+
102
+ divider
103
+
104
+ item 'Extentions' do
105
+ link controller.extentions_path
106
+ icon 'puzzle-piece'
107
+ badge 10
108
+ end
109
+
110
+ item 'Settings' do
111
+ link controller.settings_path
112
+ icon 'cog'
113
+ end
114
+
115
+ flex_divider
116
+
117
+ item current_user.email do
118
+ nest :profile
119
+ icon 'gift'
120
+ end
121
+ end
122
+
123
+ navigation :products do
124
+ brand 'Products'
125
+
126
+ item 'Products' do
127
+ link controller.products_path
128
+ end
129
+
130
+ item 'Stocks' do
131
+ link controller.stocks_path
132
+ end
133
+
134
+ item 'Categories' do
135
+ link controller.categories_path
136
+ end
137
+ end
138
+
139
+ navigation :store do
140
+ brand 'Store' do
141
+ external_link '/#external'
142
+ end
143
+
144
+ item 'Pages' do
145
+ link controller.pages_path
146
+ end
147
+
148
+ item 'Links' do
149
+ link controller.links_path
150
+ end
151
+
152
+ item 'Themes' do
153
+ link controller.themes_path
154
+ end
155
+ end
156
+
157
+ navigation :profile do
158
+ brand current_user.email
159
+
160
+ item 'Edit Profile' do
161
+ link controller.edit_user_path(current_user)
162
+ end
163
+
164
+ item 'Logout' do
165
+ link controller.destroy_user_session_path, method: :delete
166
+ end
167
+ end
168
+ end
169
+ ```
170
+
171
+ 5. Use the helper method in your views.
172
+
173
+ ```erb
174
+ <%== render_admin_layout do %>
175
+ <%# Put your main contents ... %>
176
+ <% end %>
177
+ ```
178
+
179
+ ### b. Sinatra
180
+
181
+ pending...
182
+
183
+ ## Development
184
+
185
+ To set up a dummy application for development, simply do:
186
+
187
+ ```sh
188
+ $ cd test/dummy
189
+ $ bundle exec ruby app.rb
190
+ ```
191
+
192
+ And go to your browser and open `http://localhost:4567`.
193
+
194
+ ## Contributing
195
+
196
+ 1. Fork it ( https://github.com/appirits/awesome_admin_layout/fork )
197
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
198
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
199
+ 4. Push to the branch (`git push origin my-new-feature`)
200
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,26 @@
1
+ $(document).ready(->
2
+ #
3
+ # Variables
4
+ #
5
+ $layout = $('#awesome_admin_layout')
6
+ $navigation = $('.awesome_admin_layout-navigation')
7
+ $navigation_toggle = $('.awesome_admin_layout-navigation-toggle')
8
+
9
+ #
10
+ # Events
11
+ #
12
+ $navigation.on('click', 'li:not(.nested)', ->
13
+ $navigation.find('.open').removeClass('open')
14
+ $navigation.find('.expanded').removeClass('expanded')
15
+ )
16
+
17
+ $navigation.on('click', 'li.nested', (event) ->
18
+ $navigation.find('.open').removeClass('open')
19
+ $(this).closest('ul').addClass('expanded')
20
+ $(this).find('.awesome_admin_layout-nested-navigation').addClass('open')
21
+ )
22
+
23
+ $navigation_toggle.on('click', 'i', ->
24
+ $layout.toggleClass('open')
25
+ )
26
+ )
@@ -0,0 +1,358 @@
1
+ // Variables
2
+ $awesome_admin_layout-navigation-bg: #31373d !default;
3
+ $awesome_admin_layout-navigation-expanded-bg: #212529 !default;
4
+ $awesome_admin_layout-navigation-width: 250px !default;
5
+ $awesome_admin_layout-navigation-brand-color: #fff !default;
6
+ $awesome_admin_layout-navigation-brand-bg: #272c30 !default;
7
+ $awesome_admin_layout-navigation-brand-height: 60px !default;
8
+ $awesome_admin_layout-navigation-item-color: #c3cfd8 !default;
9
+ $awesome_admin_layout-navigation-item-hover-color: #fff !default;
10
+ $awesome_admin_layout-navigation-item-active-color: #fff !default;
11
+ $awesome_admin_layout-navigation-item-active-bg: #454e57 !default;
12
+ $awesome_admin_layout-navigation-item-icon-color: #798c9c !default;
13
+ $awesome_admin_layout-navigation-item-icon-hover-color: #fff !default;
14
+ $awesome_admin_layout-navigation-item-icon-active-color: #fff !default;
15
+ $awesome_admin_layout-navigation-item-height: 40px !default;
16
+ $awesome_admin_layout-navigation-toggle-color: #444 !default;
17
+ $awesome_admin_layout-navigation-toggle-border: #ccc !default;
18
+ $awesome_admin_layout-navigation-toggle-bg: #eee !default;
19
+ $awesome_admin_layout-badge-color: #fff !default;
20
+ $awesome_admin_layout-badge-bg: #479ccf !default;
21
+ $awesome_admin_layout-badge-height: 25px !default;
22
+ $awesome_admin_layout-notice-bg: #479ccf !default;
23
+ $awesome_admin_layout-notice-size: 10px !default;
24
+
25
+ // Mixins
26
+ @mixin awesome_admin_layout-display-flex() {
27
+ display: -webkit-box;
28
+ display: -moz-box;
29
+ display: -ms-flexbox;
30
+ display: -webkit-flex;
31
+ display: flex;
32
+ }
33
+
34
+ @mixin awesome_admin_layout-flex($flex) {
35
+ -webkit-box-flex: $flex;
36
+ -moz-box-flex: $flex;
37
+ -ms-flex: $flex;
38
+ -webkit-flex: $flex;
39
+ flex: $flex;
40
+ }
41
+
42
+ @mixin awesome_admin_layout-flex-direction($direction) {
43
+ @if $direction == 'column' {
44
+ -webkit-box-orient: vertical;
45
+ -moz-box-orient: vertical;
46
+ -ms-flex-direction: column;
47
+ -webkit-flex-direction: column;
48
+ flex-direction: column;
49
+ } else {
50
+ -webkit-box-orient: horizontal;
51
+ -moz-box-orient: horizontal;
52
+ -ms-flex-direction: row;
53
+ -webkit-flex-direction: row;
54
+ flex-direction: row;
55
+ }
56
+ }
57
+
58
+ @mixin awesome_admin_layout-align-items($align) {
59
+ -webkit-box-align: $align;
60
+ -moz-box-align: $align;
61
+ -ms-flex-align: $align;
62
+ -webkit-align-items: $align;
63
+ align-items: $align;
64
+ }
65
+
66
+ @mixin awesome_admin_layout-border-radius($radius) {
67
+ -moz-border-radius: $radius;
68
+ -ms-border-radius: $radius;
69
+ -webkit-border-radius: $radius;
70
+ border-radius: $radius;
71
+ }
72
+
73
+ @mixin awesome_admin_layout-fa($name, $float: none) {
74
+ &:before {
75
+ float: $float;
76
+ @extend .fa !optional;
77
+ }
78
+ @extend .fa-#{$name} !optional;
79
+ }
80
+
81
+ @mixin awesome_admin_layout-transform($transform) {
82
+ -moz-transform: $transform;
83
+ -o-transform: $transform;
84
+ -ms-transform: $transform;
85
+ -webkit-transform: $transform;
86
+ transform: $transform;
87
+ }
88
+
89
+ @mixin awesome_admin_layout-transition($transitions...) {
90
+ -moz-transition: $transitions;
91
+ -o-transition: $transitions;
92
+ -ms-transition: $transitions;
93
+ -webkit-transition: $transitions;
94
+ transition: $transitions;
95
+ }
96
+
97
+ // Rules
98
+ #awesome_admin_layout {
99
+ }
100
+
101
+ .awesome_admin_layout-navigation {
102
+ @include awesome_admin_layout-transition(transform 200ms ease);
103
+ width: $awesome_admin_layout-navigation-width;
104
+ background-color: $awesome_admin_layout-navigation-bg;
105
+ position: fixed;
106
+ top: 0;
107
+ left: 0;
108
+ bottom: 0;
109
+ z-index: 300;
110
+ overflow: hidden;
111
+
112
+ .awesome_admin_layout-wrapper {
113
+ width: 100%;
114
+ position: absolute;
115
+ top: 0;
116
+ left: 0;
117
+ bottom: 0;
118
+ overflow-x: hidden;
119
+ overflow-y: auto;
120
+ }
121
+ }
122
+
123
+ .awesome_admin_layout-main {
124
+ @include awesome_admin_layout-transition(transform 200ms ease);
125
+ padding-left: $awesome_admin_layout-navigation-width;
126
+ margin: 15px;
127
+ }
128
+
129
+ .awesome_admin_layout-navigation-brand {
130
+ @include awesome_admin_layout-display-flex;
131
+ width: 100%;
132
+ height: $awesome_admin_layout-navigation-brand-height;
133
+ line-height: $awesome_admin_layout-navigation-brand-height;
134
+ font-weight: bold;
135
+ color: $awesome_admin_layout-navigation-brand-color;
136
+ background-color: $awesome_admin_layout-navigation-brand-bg;
137
+
138
+ span {
139
+ margin: 0 20px;
140
+ }
141
+
142
+ a:link, a:visited, a:hover, a:active {
143
+ color: $awesome_admin_layout-navigation-brand-color;
144
+ text-decoration: none;
145
+ }
146
+
147
+ .awesome_admin_layout-nested-navigation & {
148
+ color: $awesome_admin_layout-navigation-item-color;
149
+ background-color: $awesome_admin_layout-navigation-bg;
150
+ border-bottom: 1px solid $awesome_admin_layout-navigation-brand-bg;
151
+ }
152
+
153
+ .awesome_admin_layout-external-link {
154
+ margin-left: auto;
155
+ margin-right: 20px;
156
+ padding: 0;
157
+ height: auto;
158
+
159
+ i {
160
+ text-align: right;
161
+ font-weight: bold;
162
+ color: $awesome_admin_layout-navigation-item-icon-color;
163
+ }
164
+
165
+ &:hover i, &:active i {
166
+ color: $awesome_admin_layout-navigation-item-icon-hover-color;
167
+ }
168
+ }
169
+ }
170
+
171
+ .awesome_admin_layout-badge {
172
+ @include awesome_admin_layout-border-radius(10px);
173
+ font-size: smaller;
174
+ color: $awesome_admin_layout-badge-color;
175
+ padding: 0 10px;
176
+ background-color: $awesome_admin_layout-badge-bg;
177
+ }
178
+
179
+ .awesome_admin_layout-notice {
180
+ @include awesome_admin_layout-border-radius(100%);
181
+ background-color: $awesome_admin_layout-notice-bg;
182
+ }
183
+
184
+ .awesome_admin_layout-navigation {
185
+ ul {
186
+ @include awesome_admin_layout-display-flex;
187
+ @include awesome_admin_layout-flex-direction(column);
188
+ @include awesome_admin_layout-transition(background 200ms ease);
189
+ margin: 0;
190
+ padding: 0;
191
+ width: 100%;
192
+ position: absolute;
193
+ top: $awesome_admin_layout-navigation-brand-height;
194
+ bottom: 0;
195
+ left: 0;
196
+ right: 0;
197
+
198
+ &.expanded {
199
+ background-color: $awesome_admin_layout-navigation-expanded-bg;
200
+
201
+ & > li > a > .awesome_admin_layout-text {
202
+ display: none;
203
+ }
204
+
205
+ .awesome_admin_layout-notice,
206
+ .awesome_admin_layout-badge {
207
+ height: $awesome_admin_layout-notice-size / 2;
208
+ width: $awesome_admin_layout-notice-size / 2;
209
+ }
210
+
211
+ .awesome_admin_layout-badge {
212
+ padding: 0;
213
+ text-indent: -99999px;
214
+ }
215
+
216
+ li.nested i.fa-angle-right {
217
+ display: none;
218
+ }
219
+
220
+ & > li.active > a {
221
+ background-color: transparent;
222
+ }
223
+ }
224
+ }
225
+
226
+ li {
227
+ display: block;
228
+ margin: 0;
229
+ padding: 0;
230
+ list-style: none;
231
+ height: $awesome_admin_layout-navigation-item-height;
232
+ min-height: $awesome_admin_layout-navigation-item-height;
233
+
234
+ i {
235
+ margin-right: 0.5em;
236
+ width: 20px;
237
+ color: $awesome_admin_layout-navigation-item-icon-color;
238
+ font-size: larger;
239
+ text-align: center;
240
+ }
241
+
242
+ a {
243
+ @include awesome_admin_layout-display-flex;
244
+ @include awesome_admin_layout-align-items(center);
245
+ height: 100%;
246
+ padding: 0 20px;
247
+ white-space: nowrap;
248
+ color: $awesome_admin_layout-navigation-item-color;
249
+ text-decoration: none;
250
+
251
+ .awesome_admin_layout-text {
252
+ margin-right: auto;
253
+ }
254
+
255
+ &:hover, &:active {
256
+ color: $awesome_admin_layout-navigation-item-hover-color;
257
+
258
+ & > i {
259
+ color: $awesome_admin_layout-navigation-item-icon-hover-color;
260
+ }
261
+ }
262
+ }
263
+
264
+ &.active > a {
265
+ color: $awesome_admin_layout-navigation-item-active-color;
266
+ background-color: $awesome_admin_layout-navigation-item-active-bg;
267
+
268
+ & > i {
269
+ color: $awesome_admin_layout-navigation-item-icon-active-color;
270
+ }
271
+ }
272
+
273
+ .awesome_admin_layout-badge {
274
+ height: $awesome_admin_layout-badge-height;
275
+ line-height: $awesome_admin_layout-badge-height;
276
+ }
277
+
278
+ .awesome_admin_layout-notice {
279
+ height: $awesome_admin_layout-notice-size;
280
+ width: $awesome_admin_layout-notice-size;
281
+ }
282
+ }
283
+
284
+ .awesome_admin_layout-nested-navigation {
285
+ @include awesome_admin_layout-transition(visibility 200ms ease, transform 200ms ease);
286
+ @include awesome_admin_layout-transform(translate3d($awesome_admin_layout-navigation-width, 0, 0));
287
+ visibility: hidden;
288
+ width: $awesome_admin_layout-navigation-width - 65px;
289
+ background-color: $awesome_admin_layout-navigation-bg;
290
+ position: fixed;
291
+ top: 0;
292
+ bottom: 0;
293
+ z-index: 400;
294
+
295
+ &.open {
296
+ @include awesome_admin_layout-transform(translate3d(65px, 0, 0));
297
+ visibility: visible;
298
+ }
299
+ }
300
+
301
+ li.nested i.fa-angle-right {
302
+ text-align: right;
303
+ font-weight: bold;
304
+ }
305
+
306
+ li.divider {
307
+ height: 20px;
308
+ min-height: 20px;
309
+ }
310
+
311
+ li.flex-divider {
312
+ @include awesome_admin_layout-flex(1);
313
+ }
314
+ }
315
+
316
+ .awesome_admin_layout-navigation-toggle {
317
+ display: none;
318
+
319
+ i {
320
+ cursor: pointer;
321
+ margin-right: 10px;
322
+ padding: 7.5px 10px;
323
+ color: $awesome_admin_layout-navigation-toggle-color;
324
+ border: 1px solid $awesome_admin_layout-navigation-toggle-border;
325
+ @include awesome_admin_layout-border-radius(5px);
326
+
327
+ &:hover, &:active {
328
+ background-color: $awesome_admin_layout-navigation-toggle-bg;
329
+ }
330
+ }
331
+ }
332
+
333
+ @media screen and (max-width: 768px) {
334
+ .awesome_admin_layout-navigation-toggle {
335
+ display: block !important;
336
+ }
337
+
338
+ .awesome_admin_layout-navigation {
339
+ @include awesome_admin_layout-transform(translate3d(-$awesome_admin_layout-navigation-width, 0, 0));
340
+ }
341
+
342
+ .awesome_admin_layout-main {
343
+ @include awesome_admin_layout-transform(translate3d(0, 0, 0));
344
+ padding-left: 0;
345
+ }
346
+
347
+ #awesome_admin_layout.open {
348
+ overflow-x: hidden;
349
+
350
+ .awesome_admin_layout-navigation {
351
+ @include awesome_admin_layout-transform(translate3d(0, 0, 0));
352
+ }
353
+
354
+ .awesome_admin_layout-main {
355
+ @include awesome_admin_layout-transform(translate3d($awesome_admin_layout-navigation-width, 0, 0));
356
+ }
357
+ }
358
+ }
@@ -0,0 +1,25 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ require 'awesome_admin_layout/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'awesome_admin_layout'
8
+ spec.version = AwesomeAdminLayout::VERSION
9
+ spec.authors = ['YOSHIDA Hiroki']
10
+ spec.email = ['hyoshida@appirits.com']
11
+ spec.summary = 'Providing a simple way to add admin panel layout.'
12
+ spec.description = 'AwesomeAdminLayout provides a simple way to add admin panel layout to your application.'
13
+ spec.homepage = 'https://github.com/appirits/awesome_admin_layout'
14
+
15
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
+ spec.require_paths = ['lib']
17
+
18
+ spec.add_dependency 'slim'
19
+ spec.add_dependency 'sass'
20
+ spec.add_dependency 'coffee-script'
21
+
22
+ spec.add_development_dependency 'bundler', '~> 1.9'
23
+ spec.add_development_dependency 'rake', '~> 10.0'
24
+ spec.add_development_dependency 'sinatra', '~> 1.4.6'
25
+ end
@@ -0,0 +1,11 @@
1
+ module AwesomeAdminLayout
2
+ class Engine < ::Rails::Engine
3
+ ActiveSupport.on_load(:action_view) do
4
+ ActionView::Base.send(:include, AwesomeAdminLayout::Helpers)
5
+ end
6
+
7
+ ActiveSupport.on_load(:action_controller) do
8
+ ActionController::Base.send(:extend, AwesomeAdminLayout::Helpers::ClassMethods)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,28 @@
1
+ module AwesomeAdminLayout
2
+ module Helpers
3
+ module ClassMethods
4
+ def awesome_admin_layout(&block)
5
+ before_filter -> { AwesomeAdminLayout.awesome_admin_layout(self, &block) }
6
+ end
7
+ end
8
+
9
+ def render_admin_layout(&block)
10
+ <<-HTML
11
+ <div id="awesome_admin_layout">
12
+ <nav class="awesome_admin_layout-navigation">
13
+ <div class="awesome_admin_layout-wrapper">
14
+ #{AwesomeAdminLayout.script.to_html}
15
+ </div>
16
+ </nav>
17
+
18
+ <main class="awesome_admin_layout-main">
19
+ <div class="awesome_admin_layout-navigation-toggle">
20
+ <i class="fa fa-bars"></i>
21
+ </div>
22
+ #{defined?(::Rails) ? capture(&block) : yield}
23
+ </main>
24
+ </div>
25
+ HTML
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,49 @@
1
+ module AwesomeAdminLayout
2
+ class Navigation
3
+ class Brand
4
+ def initialize(name = nil)
5
+ @item = { name: name }
6
+ end
7
+
8
+ def name(name = nil, &block)
9
+ @item[:name] = block_given? ? block : name
10
+ end
11
+
12
+ def link(link)
13
+ @item[:link] = link
14
+ end
15
+
16
+ def external_link(link)
17
+ @item[:external_link] = link
18
+ end
19
+
20
+ def to_s
21
+ %Q{<div class="#{__css_class}">#{__link_to("#{__name}")}#{__enternal_link}</div>}
22
+ end
23
+
24
+ private
25
+
26
+ def __css_class
27
+ 'awesome_admin_layout-navigation-brand'
28
+ end
29
+
30
+ def __name
31
+ "<span>#{@item[:name].is_a?(Proc) ? @item[:name].call : @item[:name]}</span>"
32
+ end
33
+
34
+ def __link_to(name)
35
+ return name unless @item[:link]
36
+ %Q{<a href="#{@item[:link]}">#{name}</a>}
37
+ end
38
+
39
+ def __enternal_link
40
+ return unless @item[:external_link]
41
+ %Q{<a href="#{@item[:external_link]}" target="_blank" class="awesome_admin_layout-external-link">#{__external_link_icon}</a>}
42
+ end
43
+
44
+ def __external_link_icon
45
+ '<i class="fa fa-external-link"></i>'
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,15 @@
1
+ module AwesomeAdminLayout
2
+ class Navigation
3
+ class Divider
4
+ def class_name
5
+ 'divider'
6
+ end
7
+
8
+ def to_s
9
+ css_class = class_name.join(' ') if class_name.is_a? Array
10
+ css_class ||= class_name
11
+ %Q{<li class="#{css_class}"></li>}
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ module AwesomeAdminLayout
2
+ class Navigation
3
+ class FlexDivider < Divider
4
+ def class_name
5
+ ['divider', 'flex-divider']
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,115 @@
1
+ module AwesomeAdminLayout
2
+ class Navigation
3
+ class Item
4
+ def initialize(name = nil)
5
+ @item = { name: name }
6
+ end
7
+
8
+ def name(name = nil, &block)
9
+ @item[:name] = block_given? ? block : name
10
+ end
11
+
12
+ def link(href, option = {})
13
+ @item[:link] = option.merge(href: href)
14
+ end
15
+
16
+ def active(active)
17
+ @item[:active] = active
18
+ end
19
+
20
+ def icon(icon)
21
+ @item[:icon] = icon
22
+ end
23
+
24
+ def badge(badge)
25
+ @item[:badge] = badge
26
+ end
27
+
28
+ def nest(key)
29
+ @item[:nest] = Navigation.find(key)
30
+ end
31
+
32
+ def to_s
33
+ %Q{<li#{" class=\"#{__css_class}\"" unless __css_class.empty?}>#{__link_to("#{__name_with_icon}#{__badge}#{__arrow}")}#{__nest}</li>}
34
+ end
35
+
36
+ def __active?
37
+ return @item[:active] unless @item[:active].nil?
38
+ return false unless @item[:link]
39
+ AwesomeAdminLayout.active_url? @item[:link][:href]
40
+ end
41
+
42
+ def __nested?
43
+ @item[:nest] ? true : false
44
+ end
45
+
46
+ def __has_active_nest?
47
+ return false unless @item[:nest]
48
+ @item[:nest].__has_active_item?
49
+ end
50
+
51
+ private
52
+
53
+ def __arrow
54
+ '<i class="fa fa-angle-right"></i>' if __nested?
55
+ end
56
+
57
+ def __nest
58
+ %Q{<div class="#{__nest_css_class}">#{@item[:nest]}</div>} if __nested?
59
+ end
60
+
61
+ def __css_class
62
+ css_class = []
63
+ css_class << 'active' if __active? || __has_active_nest?
64
+ css_class << 'nested' if __nested?
65
+ css_class.join(' ')
66
+ end
67
+
68
+ def __nest_css_class
69
+ css_class = []
70
+ css_class << 'awesome_admin_layout-nested-navigation'
71
+ css_class << 'open' if __has_active_nest?
72
+ css_class.join(' ')
73
+ end
74
+
75
+ def __name_with_icon
76
+ %Q{#{__icon}<span class="awesome_admin_layout-text">#{__name}</span>}
77
+ end
78
+
79
+ def __name
80
+ @item[:name].is_a?(Proc) ? @item[:name].call : @item[:name]
81
+ end
82
+
83
+ def __icon
84
+ return unless @item[:icon]
85
+ %Q{<i class="fa fa-#{@item[:icon]}"></i>}
86
+ end
87
+
88
+ def __badge
89
+ return unless @item[:badge]
90
+ case @item[:badge]
91
+ when TrueClass, FalseClass
92
+ %Q{<span class="awesome_admin_layout-notice"></span>}
93
+ else
94
+ %Q{<span class="awesome_admin_layout-badge">#{@item[:badge]}</span>}
95
+ end
96
+ end
97
+
98
+ def __link_to(name)
99
+ if __nested?
100
+ %Q{<a href="javascript:void(0);">#{name}</a>}
101
+ else
102
+ return name unless @item[:link]
103
+ return ActionController::Base.helpers.link_to(name.html_safe, @item[:link][:href], @item[:link]) if defined? Rails
104
+ %Q{<a href="#{@item[:link][:href]}" #{__link_attributes}>#{name}</a>}
105
+ end
106
+ end
107
+
108
+ def __link_attributes
109
+ attributes = {}
110
+ attributes = { 'data-method' => @item[:link][:method] } if @item[:link][:method]
111
+ attributes.map { |(key, value)| %Q{#{key}="#{value}"} }.join(' ')
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,80 @@
1
+ require 'awesome_admin_layout/navigation/brand'
2
+ require 'awesome_admin_layout/navigation/item'
3
+ require 'awesome_admin_layout/navigation/divider'
4
+ require 'awesome_admin_layout/navigation/flex_divider'
5
+
6
+ module AwesomeAdminLayout
7
+ class Navigation
8
+ @@collection = {}
9
+
10
+ class << self
11
+ def find(key)
12
+ return unless @@collection
13
+ return fail "Navigation '#{key}' was not faound!" unless @@collection.has_key? key
14
+ element = @@collection[key]
15
+ code = element.delete(:code)
16
+ element[:object].instance_eval(&code) if code
17
+ element[:object]
18
+ end
19
+ end
20
+
21
+ def initialize(key = :default, &block)
22
+ __add_to_collection(key, block)
23
+ @tree = []
24
+ end
25
+
26
+ def brand(name, &block)
27
+ brand = Brand.new(name)
28
+ brand.instance_eval(&block) if block_given?
29
+ @brand = brand
30
+ end
31
+
32
+ def item(name, &block)
33
+ item = Item.new(name)
34
+ item.instance_eval(&block) if block_given?
35
+ @tree << item
36
+ end
37
+
38
+ def divider
39
+ @tree << Divider.new
40
+ end
41
+
42
+ def flex_divider
43
+ @tree << FlexDivider.new
44
+ end
45
+
46
+ def nest(key)
47
+ @tree << Navigation.find(key)
48
+ end
49
+
50
+ def to_s
51
+ __convert
52
+ end
53
+
54
+ def __has_active_item?
55
+ __items.any?(&:__active?)
56
+ end
57
+
58
+ def __has_active_nested_item?
59
+ __items.any?(&:__has_active_nest?)
60
+ end
61
+
62
+ private
63
+
64
+ def __add_to_collection(key, block)
65
+ @@collection[key] = { object: self, code: block }
66
+ end
67
+
68
+ def __convert
69
+ "#{@brand}<ul#{' class="expanded"' if __has_active_nested_item?}>#{__convert_items}</ul>"
70
+ end
71
+
72
+ def __convert_items
73
+ @tree.map(&:to_s).join
74
+ end
75
+
76
+ def __items
77
+ @tree.select { |node| node.is_a? Item }
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,52 @@
1
+ # Ruby module that can recognize paths of the main Rails application as well as the engines.
2
+ # from: https://gist.github.com/jtanium/6114632
3
+ module AwesomeAdminLayout
4
+ module RecognizePath
5
+ def active_url?(url)
6
+ return false unless AwesomeAdminLayout.request
7
+ same_url? AwesomeAdminLayout.request.fullpath, url
8
+ end
9
+
10
+ # TODO: Add tests
11
+ def recognize_path(path, options = {})
12
+ recognized_path = Rails.application.routes.recognize_path(path, options)
13
+ # We have a route that catches everything and sends it to 'errors#not_found', you might
14
+ # need to rescue ActionController::RoutingError
15
+ rescue ActionController::RoutingError
16
+ # The main app didn't recognize the path, try the engines...
17
+ Rails::Engine.subclasses.each do |engine|
18
+ engine_instance = engine.instance
19
+ # Find the route to the engine, e.g. '/blog' -> Blog::Engine (a.k.a. "mount")
20
+ engine_class = engine_instance.class
21
+ engine_route = Rails.application.routes.routes.find { |r| r.app.app == engine_class }
22
+ next unless engine_route
23
+
24
+ # The engine won't recognize the "mount", so strip it off the path,
25
+ # e.g. '/blog/posts/new'.gsub(%r(^/blog), '') #=> '/posts/new', which will be recognized by the engine
26
+ path_for_engine = path.gsub(/^#{engine_route.path.spec}/, '')
27
+
28
+ begin
29
+ recognized_path = engine_instance.routes.recognize_path(path_for_engine, options)
30
+ rescue ActionController::RoutingError => e
31
+ Rails.logger.debug "[#{engine}] ActionController::RoutingError: #{e.message}"
32
+ end
33
+ end
34
+
35
+ recognized_path
36
+ end
37
+
38
+ private
39
+
40
+ def same_url?(first_url, second_url)
41
+ if defined? Rails
42
+ first_path = recognize_path(first_url)
43
+ return false unless first_path
44
+ second_path = recognize_path(second_url)
45
+ return false unless second_path
46
+ first_path[:controller] == second_path[:controller]
47
+ else
48
+ first_url.split('?').first.match(/^#{second_url.split('?').first}(\/\d*)?$/)
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,17 @@
1
+ require 'awesome_admin_layout/navigation/item'
2
+ require 'awesome_admin_layout/navigation/divider'
3
+ require 'awesome_admin_layout/navigation/flex_divider'
4
+
5
+ module AwesomeAdminLayout
6
+ class Script
7
+ def navigation(key = :default, &block)
8
+ Navigation.new(key, &block)
9
+ end
10
+
11
+ def to_s
12
+ Navigation.find(:default)
13
+ end
14
+
15
+ alias_method :to_html, :to_s
16
+ end
17
+ end
@@ -0,0 +1,47 @@
1
+ require 'awesome_admin_layout/version'
2
+
3
+ root = File.expand_path('../../../', __FILE__)
4
+ version = AwesomeAdminLayout::VERSION
5
+ tag = "v#{version}"
6
+
7
+ directory 'pkg'
8
+
9
+ namespace :awesome_admin_layout do
10
+ gemname = 'awesome_admin_layout'
11
+ gem = "#{gemname}-#{version}.gem"
12
+ gemspec = "#{gemname}.gemspec"
13
+
14
+ task :clean do
15
+ rm_f "pkg/#{gem}"
16
+ end
17
+
18
+ task :build => :pkg do
19
+ sh "gem build #{gemspec} && mv #{gemn}.gem #{root}/pkg/"
20
+ end
21
+
22
+ task :install => :build do
23
+ sh "gem install pkg/#{gem}"
24
+ end
25
+
26
+ task :push => :build do
27
+ sh "gem push pkg/#{gem}"
28
+ end
29
+
30
+ task :commit do
31
+ File.open('pkg/commit_message.txt', 'w') do |f|
32
+ f.puts "# Bump to #{version}\n"
33
+ f.puts
34
+ f.puts '# UNCOMMENT THE LINE ABOVE TO APPROVE THIS COMMIT'
35
+ end
36
+
37
+ sh 'git add . && git commit --verbose --template=pkg/commit_message.txt'
38
+ rm_f 'pkg/commit_message.txt'
39
+ end
40
+
41
+ task :tag do
42
+ sh "git tag -m '#{tag} release' #{tag}"
43
+ sh 'git push --tags'
44
+ end
45
+
46
+ task :release => %w(clean build commit tag push)
47
+ end
@@ -0,0 +1,3 @@
1
+ module AwesomeAdminLayout
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,40 @@
1
+ require 'awesome_admin_layout/version'
2
+ require 'awesome_admin_layout/script'
3
+ require 'awesome_admin_layout/navigation'
4
+ require 'awesome_admin_layout/helpers'
5
+ require 'awesome_admin_layout/engine' if defined? Rails
6
+ require 'awesome_admin_layout/recognize_path'
7
+
8
+ module AwesomeAdminLayout
9
+ extend AwesomeAdminLayout::RecognizePath
10
+
11
+ @@context = nil
12
+ @@request = nil
13
+ @@script = nil
14
+
15
+ class << self
16
+ def request
17
+ return @@request if @@request
18
+ @@context.request if @@context
19
+ end
20
+
21
+ def script
22
+ @@script
23
+ end
24
+
25
+ def awesome_admin_layout(context = nil, &block)
26
+ @@context = context
27
+ @@script ||= AwesomeAdminLayout::Script.new
28
+ @@script.instance_exec(context, &block)
29
+ end
30
+
31
+ def setup(options = {}, &block)
32
+ @@request = options[:request]
33
+ if defined? Rails
34
+ (options[:only] || ActionController::Base).send(:before_filter, -> { AwesomeAdminLayout.awesome_admin_layout(self, &block) })
35
+ else
36
+ awesome_admin_layout(&block)
37
+ end
38
+ end
39
+ end
40
+ end
metadata ADDED
@@ -0,0 +1,149 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: awesome_admin_layout
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - YOSHIDA Hiroki
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: slim
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: sass
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: coffee-script
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.9'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.9'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: sinatra
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 1.4.6
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 1.4.6
97
+ description: AwesomeAdminLayout provides a simple way to add admin panel layout to
98
+ your application.
99
+ email:
100
+ - hyoshida@appirits.com
101
+ executables: []
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - ".gitignore"
106
+ - ".travis.yml"
107
+ - CHANGELOG.md
108
+ - Gemfile
109
+ - README.md
110
+ - Rakefile
111
+ - app/assets/javascripts/awesome_admin_layout.coffee
112
+ - app/assets/stylesheets/awesome_admin_layout.scss
113
+ - awesome_admin_layout.gemspec
114
+ - lib/awesome_admin_layout.rb
115
+ - lib/awesome_admin_layout/engine.rb
116
+ - lib/awesome_admin_layout/helpers.rb
117
+ - lib/awesome_admin_layout/navigation.rb
118
+ - lib/awesome_admin_layout/navigation/brand.rb
119
+ - lib/awesome_admin_layout/navigation/divider.rb
120
+ - lib/awesome_admin_layout/navigation/flex_divider.rb
121
+ - lib/awesome_admin_layout/navigation/item.rb
122
+ - lib/awesome_admin_layout/recognize_path.rb
123
+ - lib/awesome_admin_layout/script.rb
124
+ - lib/awesome_admin_layout/tasks/release.rake
125
+ - lib/awesome_admin_layout/version.rb
126
+ homepage: https://github.com/appirits/awesome_admin_layout
127
+ licenses: []
128
+ metadata: {}
129
+ post_install_message:
130
+ rdoc_options: []
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ requirements: []
144
+ rubyforge_project:
145
+ rubygems_version: 2.2.2
146
+ signing_key:
147
+ specification_version: 4
148
+ summary: Providing a simple way to add admin panel layout.
149
+ test_files: []