awesome_admin_layout 0.1.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.
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: []