fullstack-admin 0.2.1 → 0.2.2
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.
- data/TODO.tasks +20 -14
- data/VERSION +1 -1
- data/app/assets/stylesheets/admin/base.css +312 -1
- data/app/assets/stylesheets/admin/login.css +54 -0
- data/app/assets/stylesheets/support/bootstrap-workarounds.css +1 -1
- data/app/controllers/admin/base_controller.rb +19 -14
- data/app/controllers/admin/sessions_controller.rb +18 -10
- data/app/controllers/admin/subject_model_adapter.rb +57 -0
- data/app/models/superuser.rb +4 -10
- data/app/views/admin/_nav.html.erb +39 -22
- data/app/views/admin/base/index.html.erb +47 -28
- data/app/views/admin/sessions/new.html.erb +34 -0
- data/app/views/layouts/admin.html.erb +6 -8
- data/app/views/layouts/login.html.erb +15 -0
- data/config/locales/it.yml +4 -0
- data/config/locales/labels.it.yml +2 -1
- data/config/routes.rb +4 -0
- data/fullstack-admin.gemspec +6 -2
- data/lib/fullstack/admin/resources.rb +22 -1
- data/lib/generators/fullstack/admin/install_generator.rb +3 -2
- data/lib/generators/fullstack/admin/templates/root/lib/support/user_subject.rb +1 -1
- metadata +7 -3
data/TODO.tasks
CHANGED
@@ -2,7 +2,8 @@
|
|
2
2
|
= Fullstack Admin Roadmap =
|
3
3
|
===========================
|
4
4
|
|
5
|
-
- Fix
|
5
|
+
- Fix assets compilation issues (and lock assets-related gems to working versions only)
|
6
|
+
✓ Fix positionable/_collection.html.erb not working
|
6
7
|
|
7
8
|
- Has many nested:
|
8
9
|
has_many_nested = has_many + accepts_nested_attributes_for + :allow_destroy => true [CORE]
|
@@ -33,17 +34,17 @@
|
|
33
34
|
|
34
35
|
✓ Ckeditor: upload assets to S3 according to app.config
|
35
36
|
|
36
|
-
|
37
|
-
|
38
|
-
|
37
|
+
✓ Localizable models
|
38
|
+
✓ Create Localized module: a model is localizable if has a :locale field (cms?)
|
39
|
+
✓ Add a scope to Localized to find models within the current locale (cms?)
|
39
40
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
41
|
+
✓ Create an option to specify the admin_locale
|
42
|
+
✓ add a before filter to Admin::BaseController that uses the default locale for the admin
|
43
|
+
✓ Split localized models index into tabs (either through ajax?)
|
44
|
+
✓ Let the programmer decide a default locale and a set of available locales
|
45
|
+
✓ Translations for locale codes
|
45
46
|
|
46
|
-
- Form for accepts_nested_attributes_for and has_one
|
47
|
+
- Form for accepts_nested_attributes_for and has_one (NOT TESTED?)
|
47
48
|
- Optional tracking of author/updaters for every model (CMS?)
|
48
49
|
|
49
50
|
==================
|
@@ -55,9 +56,9 @@
|
|
55
56
|
- find alternative to sortable
|
56
57
|
|
57
58
|
- Multiple scopes
|
58
|
-
- Tags input with
|
59
|
+
- Tags input with select2
|
59
60
|
|
60
|
-
-
|
61
|
+
- Conditional fields and Virtual Fields:
|
61
62
|
= Group of fields that can be setted exclusively
|
62
63
|
= eg
|
63
64
|
= field :age
|
@@ -65,5 +66,10 @@
|
|
65
66
|
|
66
67
|
= virtual_field :link_method, :in => %W(page external)
|
67
68
|
|
68
|
-
= belongs_to :related_page, :
|
69
|
-
= field :url, :
|
69
|
+
= belongs_to :related_page, :meaningful_when => :link_method.eq("page")
|
70
|
+
= field :url, :meaningful_when => :link_method.eq("external")
|
71
|
+
|
72
|
+
- Validation DSL
|
73
|
+
= field :name, :string, :required
|
74
|
+
= field :email, :required, :unique
|
75
|
+
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.2
|
@@ -1,4 +1,5 @@
|
|
1
1
|
/*
|
2
|
+
*= require admin/login
|
2
3
|
*= require support/base
|
3
4
|
*= require support/bootstrap
|
4
5
|
*= require support/forms
|
@@ -13,15 +14,113 @@
|
|
13
14
|
}
|
14
15
|
}
|
15
16
|
|
17
|
+
input {
|
18
|
+
-moz-box-sizing: border-box;
|
19
|
+
-webkit-box-sizing: border-box;
|
20
|
+
box-sizing: border-box;
|
21
|
+
width: 100%;
|
22
|
+
height: auto !important;
|
23
|
+
}
|
24
|
+
|
25
|
+
/* ========= */
|
26
|
+
/* = Icons = */
|
27
|
+
/* ========= */
|
28
|
+
|
29
|
+
.icon-white, .nav-tabs > .active > a > [class^="icon-"], .nav-tabs > .active > a > [class*=" icon-"], .nav-pills > .active > a > [class^="icon-"], .nav-pills > .active > a > [class*=" icon-"], .nav-list > .active > a > [class^="icon-"], .nav-list > .active > a > [class*=" icon-"], .navbar-inverse .nav > .active > a > [class^="icon-"], .navbar-inverse .nav > .active > a > [class*=" icon-"], .dropdown-menu > li > a:hover > [class^="icon-"], .dropdown-menu > li > a:hover > [class*=" icon-"], .dropdown-menu > .active > a > [class^="icon-"], .dropdown-menu > .active > a > [class*=" icon-"] {
|
30
|
+
background-image: url("/img/glyphicons-halflings-white.png");
|
31
|
+
}
|
32
|
+
|
33
|
+
/* ========== */
|
34
|
+
/* = Navbar = */
|
35
|
+
/* ========== */
|
36
|
+
|
37
|
+
.navbar .nav li.dropdown > .dropdown-toggle .caret {
|
38
|
+
border-top-color: white;
|
39
|
+
border-bottom-color: white;
|
40
|
+
}
|
41
|
+
|
42
|
+
.navbar-inner {
|
43
|
+
background: #3993ba;
|
44
|
+
background: -moz-linear-gradient(top, #3993ba 0%, #067ead 100%);
|
45
|
+
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#3993ba), color-stop(100%,#067ead));
|
46
|
+
background: -webkit-linear-gradient(top, #3993ba 0%,#067ead 100%);
|
47
|
+
background: -o-linear-gradient(top, #3993ba 0%,#067ead 100%);
|
48
|
+
background: -ms-linear-gradient(top, #3993ba 0%,#067ead 100%);
|
49
|
+
background: linear-gradient(top, #3993ba 0%,#067ead 100%);
|
50
|
+
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#3993ba', endColorstr='#067ead',GradientType=0 );
|
51
|
+
-webkit-box-shadow: none;
|
52
|
+
-moz-box-shadow: none;
|
53
|
+
box-shadow: none;
|
54
|
+
|
55
|
+
}
|
56
|
+
|
57
|
+
.navbar .nav > li > a {
|
58
|
+
color: #c1dce7;
|
59
|
+
}
|
60
|
+
|
61
|
+
.navbar .nav > li:hover > a {
|
62
|
+
color:#fff;
|
63
|
+
}
|
64
|
+
|
65
|
+
.navbar .nav .active > a, .navbar .nav .active > a:hover, .navbar .nav li.dropdown.open > .dropdown-toggle {
|
66
|
+
background: #206484;
|
67
|
+
color: #fff;
|
68
|
+
}
|
69
|
+
|
70
|
+
.navbar .divider-vertical {
|
71
|
+
background-color:#2078A1;
|
72
|
+
border-color:#3497C2;
|
73
|
+
}
|
74
|
+
|
75
|
+
.navbar .divider-vertical {
|
76
|
+
border-left-color: #2078A1;
|
77
|
+
border-right-color: #3497C2;
|
78
|
+
}
|
79
|
+
|
80
|
+
.dropdown-menu li > a:hover, .dropdown-menu .active > a,
|
81
|
+
.dropdown-menu .active > a:hover,
|
82
|
+
.nav-list > .active > a, .nav-list > .active > a:hover {
|
83
|
+
background: #48a6d2 !important;
|
84
|
+
}
|
85
|
+
|
86
|
+
.table thead th {background-color:#ebf2f6 !important}
|
87
|
+
.dataTables_wrapper th.sorting_asc,.dataTables_wrapper th.sorting_desc {background-color:#d4e3eb !important}
|
88
|
+
|
89
|
+
|
16
90
|
#left-aside .nav {
|
17
91
|
padding-bottom: 180px;
|
18
92
|
}
|
19
93
|
|
94
|
+
.navbar .nav > li > a {
|
95
|
+
padding-top: 10px;
|
96
|
+
}
|
97
|
+
.navbar .nav > li > a {
|
98
|
+
text-shadow: none;
|
99
|
+
padding: 9px 10px 11px;
|
100
|
+
}
|
101
|
+
.navbar .nav > li > a {
|
102
|
+
color: #C1DCE7;
|
103
|
+
}
|
104
|
+
|
105
|
+
.navbar .brand {
|
106
|
+
width: 200px;
|
107
|
+
font: 100 16px/16px 'PT Sans', sans-serif;
|
108
|
+
text-decoration: none;
|
109
|
+
color: #c1dce7;
|
110
|
+
text-shadow: none;
|
111
|
+
padding: 10px 20px 0;
|
112
|
+
}
|
113
|
+
|
114
|
+
.navbar .brand:hover {
|
115
|
+
color: #fff;
|
116
|
+
}
|
117
|
+
|
20
118
|
.sidenav > li:first-child {
|
21
119
|
-webkit-border-radius: 6px 6px 0 0;
|
22
120
|
-moz-border-radius: 6px 6px 0 0;
|
23
121
|
border-radius: 6px 6px 0 0;
|
24
122
|
}
|
123
|
+
|
25
124
|
.sidenav > li {
|
26
125
|
display: block;
|
27
126
|
margin: 0 0 -1px;
|
@@ -31,7 +130,6 @@ margin-left: -15px;
|
|
31
130
|
margin-right: -15px;
|
32
131
|
}
|
33
132
|
|
34
|
-
|
35
133
|
.thumbnails > li {
|
36
134
|
float: left;
|
37
135
|
margin-left: 0 !important;
|
@@ -58,4 +156,217 @@ margin-right: -15px;
|
|
58
156
|
background: url(/assets/iconic/gray/magnifying_glass_12x12.png) no-repeat left center;
|
59
157
|
margin-left: 7px !important;
|
60
158
|
padding-left: 12px !important;
|
159
|
+
}
|
160
|
+
|
161
|
+
/* ======= */
|
162
|
+
/* = Box = */
|
163
|
+
/* ======= */
|
164
|
+
|
165
|
+
.box {
|
166
|
+
-webkit-box-shadow: 0px 1px 2px 0px #EFEFEF;
|
167
|
+
-moz-box-shadow: 0px 1px 2px 0px #EFEFEF;
|
168
|
+
box-shadow: 0px 1px 2px 0px #EFEFEF;
|
169
|
+
margin-bottom: 20px;
|
170
|
+
}
|
171
|
+
|
172
|
+
.box-header, .box-content, .box-footer {
|
173
|
+
padding: 20px;
|
174
|
+
}
|
175
|
+
|
176
|
+
.box-header {
|
177
|
+
height: 32px;
|
178
|
+
line-height: 32px;
|
179
|
+
border: 1px solid #DDD;
|
180
|
+
padding: 0 10px;
|
181
|
+
background: #FBFBFB;
|
182
|
+
background: -moz-linear-gradient(top, #FBFBFB 0%, #F1F1F1 100%);
|
183
|
+
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#FBFBFB), color-stop(100%,#F1F1F1));
|
184
|
+
background: -webkit-linear-gradient(top, #FBFBFB 0%,#F1F1F1 100%);
|
185
|
+
background: -o-linear-gradient(top, #FBFBFB 0%,#F1F1F1 100%);
|
186
|
+
background: -ms-linear-gradient(top, #FBFBFB 0%,#F1F1F1 100%);
|
187
|
+
background: linear-gradient(top, #FBFBFB 0%,#F1F1F1 100%);
|
188
|
+
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fbfbfb', endColorstr='#f1f1f1',GradientType=0 );
|
189
|
+
font-weight: 700;
|
190
|
+
color: #666;
|
191
|
+
font-size: 11px;
|
192
|
+
}
|
193
|
+
|
194
|
+
|
195
|
+
.box-content {
|
196
|
+
padding: 10px;
|
197
|
+
border: 1px solid #DDD;
|
198
|
+
border-top: none;
|
199
|
+
}
|
200
|
+
|
201
|
+
.box-content:last-child {
|
202
|
+
margin-bottom: 0;
|
203
|
+
padding-bottom: 0;
|
204
|
+
}
|
205
|
+
|
206
|
+
.box-footer {
|
207
|
+
border: 1px solid #DDD;
|
208
|
+
padding: 8px 10px;
|
209
|
+
background: #F1F1F1;
|
210
|
+
border-top: none;
|
211
|
+
}
|
212
|
+
|
213
|
+
.box-footer.align-right {
|
214
|
+
text-align: right;
|
215
|
+
}
|
216
|
+
|
217
|
+
fieldset.box-content {
|
218
|
+
padding-top: 20px;
|
219
|
+
}
|
220
|
+
|
221
|
+
/* ========== */
|
222
|
+
/* = Layout = */
|
223
|
+
/* ========== */
|
224
|
+
|
225
|
+
a, button, input {
|
226
|
+
outline: none !important;
|
227
|
+
}
|
228
|
+
|
229
|
+
a {
|
230
|
+
color: #08C;
|
231
|
+
text-decoration: none;
|
232
|
+
}
|
233
|
+
|
234
|
+
body {
|
235
|
+
padding-top: 60px;
|
236
|
+
}
|
237
|
+
|
238
|
+
.main {
|
239
|
+
background: white;
|
240
|
+
border-left: 1px solid transparent;
|
241
|
+
margin-left: 240px;
|
242
|
+
}
|
243
|
+
|
244
|
+
|
245
|
+
/* =============== */
|
246
|
+
/* = Page Header = */
|
247
|
+
/* =============== */
|
248
|
+
|
249
|
+
.resource_updated_at {
|
250
|
+
font: italic 12px/32px Arial, Helvetica, sans-serif;
|
251
|
+
color: #888;
|
252
|
+
}
|
253
|
+
|
254
|
+
.page-header h1, h1.page-header{
|
255
|
+
line-height: 34px;
|
256
|
+
font-size: 18px;
|
257
|
+
margin-top: 0;
|
258
|
+
}
|
259
|
+
.page-header h1 {
|
260
|
+
margin-bottom: 0;
|
261
|
+
}
|
262
|
+
|
263
|
+
#center > .page-header {
|
264
|
+
margin-top: 0;
|
265
|
+
margin-bottom: 20px;
|
266
|
+
padding: 0;
|
267
|
+
}
|
268
|
+
|
269
|
+
.index-actions {
|
270
|
+
float:right;
|
271
|
+
}
|
272
|
+
|
273
|
+
|
274
|
+
/* =========== */
|
275
|
+
/* = Sidebar = */
|
276
|
+
/* =========== */
|
277
|
+
|
278
|
+
.sidebar {
|
279
|
+
position: fixed;
|
280
|
+
top: 40px;
|
281
|
+
left: 0;
|
282
|
+
margin-left: 0;
|
283
|
+
padding-top: 20px;
|
284
|
+
width: 240px;
|
285
|
+
background: #f1f1f1;
|
286
|
+
border-right: 1px solid #ccc;
|
287
|
+
height: 100%;
|
288
|
+
font: 13px/18px "Helvetica Neue",Helvetica,Arial,sans-serif;
|
289
|
+
}
|
290
|
+
|
291
|
+
.sidebar .accordion {
|
292
|
+
border-top: 1px solid #CCC;
|
293
|
+
margin-bottom: 20px;
|
294
|
+
}
|
295
|
+
|
296
|
+
.sidebar .accordion-heading a:hover {
|
297
|
+
background-color: #CFCFCF;
|
298
|
+
}
|
299
|
+
|
300
|
+
.sidebar .accordion-heading {
|
301
|
+
text-shadow: 1px 1px 0 #EFEFEF;
|
302
|
+
background: #E0E0E0;
|
303
|
+
-webkit-box-shadow: inset 0px 1px 0px 0px #ECECEC;
|
304
|
+
box-shadow: inset 0px 1px 0px 0px #ECECEC;
|
305
|
+
}
|
306
|
+
|
307
|
+
.sidebar .accordion-inner {
|
308
|
+
border-top: 1px solid #CCC;
|
309
|
+
background: #FAFAFA;
|
310
|
+
}
|
311
|
+
|
312
|
+
.sidebar .accordion-group .accordion-heading a {
|
313
|
+
color: #222;
|
314
|
+
}
|
315
|
+
|
316
|
+
.sidebar .accordion-group .active a {
|
317
|
+
color: white;
|
318
|
+
}
|
319
|
+
|
320
|
+
.nav-list > li > a, .dropdown-menu li a {
|
321
|
+
-webkit-border-radius: 4px;
|
322
|
+
-moz-border-radius: 4px;
|
323
|
+
-ms-border-radius: 4px;
|
324
|
+
border-radius: 4px;
|
325
|
+
}
|
326
|
+
|
327
|
+
.dropdown-menu li > a:hover, .dropdown-menu .active > a, .dropdown-menu .active > a:hover, .nav-list > .active > a, .nav-list > .active > a:hover {
|
328
|
+
background: #48A6D2 !important;
|
329
|
+
}
|
330
|
+
|
331
|
+
.nav > li > a:hover {
|
332
|
+
text-decoration: none;
|
333
|
+
background-color: #EEE;
|
334
|
+
}
|
335
|
+
|
336
|
+
.sidebar .accordion-group a {
|
337
|
+
color: #222;
|
338
|
+
text-decoration: none!important;
|
339
|
+
}
|
340
|
+
|
341
|
+
.sidebar .accordion-group {
|
342
|
+
-webkit-border-radius: 0;
|
343
|
+
-moz-border-radius: 0;
|
344
|
+
border-radius: 0;
|
345
|
+
margin-bottom: 0;
|
346
|
+
border-color: #CCC;
|
347
|
+
border-style: solid;
|
348
|
+
border-width: 0 0 1px;
|
349
|
+
}
|
350
|
+
|
351
|
+
.accordion-heading .accordion-toggle {
|
352
|
+
display: block;
|
353
|
+
padding: 7px 15px;
|
354
|
+
}
|
355
|
+
|
356
|
+
.accordion-toggle {
|
357
|
+
-webkit-transition: background-color 0.2s ease-in-out;
|
358
|
+
-moz-transition: background-color 0.2s ease-in-out;
|
359
|
+
-o-transition: background-color 0.2s ease-in-out;
|
360
|
+
transition: background-color 0.2s ease-in-out;
|
361
|
+
}
|
362
|
+
.accordion-toggle {
|
363
|
+
cursor: pointer;
|
364
|
+
}
|
365
|
+
|
366
|
+
/* ================ */
|
367
|
+
/* = Filter Input = */
|
368
|
+
/* ================ */
|
369
|
+
|
370
|
+
.filter-inputs {
|
371
|
+
margin: 0;
|
61
372
|
}
|
@@ -0,0 +1,54 @@
|
|
1
|
+
.login-box {
|
2
|
+
width: 380px;
|
3
|
+
margin: auto;
|
4
|
+
padding: 0;
|
5
|
+
position: relative;
|
6
|
+
top: 50%;
|
7
|
+
background: white;
|
8
|
+
border: 1px solid #CCC;
|
9
|
+
-webkit-border-radius: 6px;
|
10
|
+
-moz-border-radius: 6px;
|
11
|
+
-ms-border-radius: 6px;
|
12
|
+
border-radius: 6px;
|
13
|
+
-webkit-box-shadow: 0 0 6px rgba(0, 0, 0, 0.2);
|
14
|
+
-moz-box-shadow: 0 0 6px rgba(0,0,0,0.2);
|
15
|
+
-ms-box-shadow: 0 0 6px rgba(0,0,0,0.2);
|
16
|
+
box-shadow: 0 0 6px rgba(0, 0, 0, 0.2);
|
17
|
+
}
|
18
|
+
|
19
|
+
.login-box-header, .login-box-content, .form-actions.login-box-footer {
|
20
|
+
padding: 20px;
|
21
|
+
margin: 0;
|
22
|
+
}
|
23
|
+
|
24
|
+
.login-box-header {
|
25
|
+
text-shadow: 0 1px 0 rgba(255, 255, 255, .5);
|
26
|
+
font: 100 18px/42px 'PT Sans', sans-serif;
|
27
|
+
height: 42px;
|
28
|
+
padding: 0 20px;
|
29
|
+
background: #E0E0E0;
|
30
|
+
border-bottom: 1px solid #CCC;
|
31
|
+
-moz-border-radius-topleft: 6px;
|
32
|
+
-moz-border-radius-topright: 6px;
|
33
|
+
-moz-border-radius-bottomright: 0px;
|
34
|
+
-moz-border-radius-bottomleft: 0px;
|
35
|
+
-webkit-border-radius: 6px 6px 0px 0px;
|
36
|
+
border-radius: 6px 6px 0px 0px;
|
37
|
+
font-size: 15px;
|
38
|
+
}
|
39
|
+
|
40
|
+
.login-box input[type="text"], .login-box input[type="password"] {
|
41
|
+
width: 298px;
|
42
|
+
}
|
43
|
+
|
44
|
+
.login-box-footer {
|
45
|
+
padding: 12px 20px;
|
46
|
+
border-top: 1px solid #E7E7E7;
|
47
|
+
background: #F7F7F7;
|
48
|
+
-moz-border-radius-topleft: 0px;
|
49
|
+
-moz-border-radius-topright: 0px;
|
50
|
+
-moz-border-radius-bottomright: 6px;
|
51
|
+
-moz-border-radius-bottomleft: 6px;
|
52
|
+
-webkit-border-radius: 0px 0px 6px 6px;
|
53
|
+
border-radius: 0px 0px 6px 6px;
|
54
|
+
}
|
@@ -1,17 +1,13 @@
|
|
1
1
|
class Admin::BaseController < ApplicationController
|
2
|
-
|
3
|
-
|
2
|
+
before_filter :require_login
|
3
|
+
before_filter :fetch_current_resource
|
4
|
+
|
4
5
|
layout 'admin'
|
5
|
-
authorize(:scope => :admin)
|
6
6
|
|
7
7
|
protected
|
8
8
|
|
9
|
-
def
|
10
|
-
|
11
|
-
redirect_to new_admin_session_path
|
12
|
-
else
|
13
|
-
render :text => "Not Authorized", :status => 403
|
14
|
-
end
|
9
|
+
def not_authenticated
|
10
|
+
redirect_to new_admin_session_url, :alert => "First login to access this page."
|
15
11
|
end
|
16
12
|
|
17
13
|
class << self
|
@@ -27,19 +23,24 @@ class Admin::BaseController < ApplicationController
|
|
27
23
|
:current_resource_class,
|
28
24
|
:current_resource,
|
29
25
|
:current_collection,
|
30
|
-
:title_column
|
26
|
+
:title_column,
|
27
|
+
:subject
|
31
28
|
|
32
29
|
|
30
|
+
def subject
|
31
|
+
@subject ||= ::Admin::SubjectModelAdapter.new(current_user)
|
32
|
+
end
|
33
|
+
|
33
34
|
def current_resource_class
|
34
|
-
@current_resource_class ||= controller_name.singularize.camelize.constantize
|
35
|
+
@current_resource_class ||= controller_name.singularize.camelize.constantize rescue nil
|
35
36
|
end
|
36
37
|
|
37
38
|
def resource_name
|
38
|
-
current_resource_class.name.demodulize.underscore
|
39
|
+
current_resource_class && current_resource_class.name.demodulize.underscore
|
39
40
|
end
|
40
41
|
|
41
42
|
def collection_name
|
42
|
-
resource_name.pluralize
|
43
|
+
resource_name.try(:pluralize)
|
43
44
|
end
|
44
45
|
|
45
46
|
alias :singular_name :resource_name
|
@@ -59,5 +60,9 @@ class Admin::BaseController < ApplicationController
|
|
59
60
|
@_title_columns[model] ||= ( model.column_names.map{ |c| c.to_s } & %W(title name label browser_title seo_title seo_name key claim email) ).first
|
60
61
|
end
|
61
62
|
|
63
|
+
def fetch_current_resource
|
64
|
+
return if !params[:id] || current_resource
|
65
|
+
instance_variable_set("@#{resource_name}", current_resource_class.find(params[:id]))
|
66
|
+
end
|
62
67
|
|
63
|
-
end
|
68
|
+
end
|
@@ -1,19 +1,27 @@
|
|
1
1
|
class Admin::SessionsController < ApplicationController
|
2
|
-
layout '
|
2
|
+
layout 'login'
|
3
|
+
|
4
|
+
def new
|
5
|
+
@user = Superuser.new
|
6
|
+
end
|
3
7
|
|
4
8
|
def create
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
respond_to do |format|
|
10
|
+
if @user = login(params[:username],params[:password])
|
11
|
+
format.html { redirect_back_or_to("/", :notice => I18n.t("signed_in", :scope => "fullstack.admin", :default => 'Signed in successfully.')) }
|
12
|
+
format.xml { render :xml => @user, :status => :created, :location => @user }
|
13
|
+
else
|
14
|
+
format.html { flash.now[:alert] = I18n.t("login_failed", :scope => "fullstack.admin", :default => 'Login failed.'); render :action => "new" }
|
15
|
+
format.xml { render :xml => @user.errors, :status => :unprocessable_entity }
|
16
|
+
end
|
11
17
|
end
|
12
18
|
end
|
13
|
-
|
19
|
+
|
14
20
|
def destroy
|
15
21
|
logout
|
16
|
-
redirect_to
|
22
|
+
redirect_to("/", :notice => I18n.t("signed_out", :scope => "fullstack.admin", :default => 'Signed out successfully.'))
|
17
23
|
end
|
18
24
|
|
19
|
-
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
class Admin::SubjectModelAdapter
|
2
|
+
attr_accessor :subject_model
|
3
|
+
|
4
|
+
def initialize(subject_model)
|
5
|
+
@subject_model = subject_model
|
6
|
+
end
|
7
|
+
|
8
|
+
def guest?
|
9
|
+
!subject_model
|
10
|
+
end
|
11
|
+
|
12
|
+
def logged_in?
|
13
|
+
!!subject_model
|
14
|
+
end
|
15
|
+
|
16
|
+
def owner?(object)
|
17
|
+
object && ( object.respond_to?(:author) && ( subject_model == object.author ) ) || ( object.respond_to?(:owner) && ( subject_model == object.owner ) )
|
18
|
+
end
|
19
|
+
alias :own? :owner?
|
20
|
+
|
21
|
+
def administrator?
|
22
|
+
true
|
23
|
+
end
|
24
|
+
|
25
|
+
def can?(*args)
|
26
|
+
true
|
27
|
+
end
|
28
|
+
|
29
|
+
def can_edit?(*args)
|
30
|
+
true
|
31
|
+
end
|
32
|
+
|
33
|
+
def can_create?(*args)
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def can_destroy?(*args)
|
38
|
+
true
|
39
|
+
end
|
40
|
+
|
41
|
+
def can_new?(*args)
|
42
|
+
true
|
43
|
+
end
|
44
|
+
|
45
|
+
def can_update?(*args)
|
46
|
+
true
|
47
|
+
end
|
48
|
+
|
49
|
+
def can_sort?(*args)
|
50
|
+
true
|
51
|
+
end
|
52
|
+
|
53
|
+
def can_show?(*args)
|
54
|
+
true
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
data/app/models/superuser.rb
CHANGED
@@ -1,12 +1,6 @@
|
|
1
1
|
class Superuser < ActiveRecord::Base
|
2
2
|
authenticates_with_sorcery!
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
validates_presence_of :password, :on => :create
|
8
|
-
validates_presence_of :email
|
9
|
-
validates_uniqueness_of :email
|
10
|
-
field :email
|
11
|
-
field :password
|
12
|
-
end
|
3
|
+
def has_role?(r)
|
4
|
+
true
|
5
|
+
end
|
6
|
+
end
|
@@ -1,13 +1,15 @@
|
|
1
|
-
<% content_for :menu do -%>
|
1
|
+
<% content_for :menu do -%>
|
2
|
+
|
3
|
+
<%= nav(:class => 'float right') do %>
|
4
|
+
<li class="divider-vertical">
|
5
|
+
</li>
|
2
6
|
|
3
|
-
<%=
|
4
|
-
|
5
|
-
|
7
|
+
<%= nav_item t('fullstack.admin.homepage', :default => "Homepage"), "/", :icon => "globe", :"icon_color" => :white %>
|
8
|
+
<li class="divider-vertical">
|
9
|
+
</li>
|
6
10
|
|
7
|
-
|
8
|
-
|
9
|
-
<%= dropdown_nav_item t('fullstack.admin.account', :default => "Account"), :icon => "user" do %>
|
10
|
-
<%= nav_item t('fullstack.admin.logout', :default => "Logout"), destroy_user_session_path, :method => :delete %>
|
11
|
+
<%= dropdown_nav_item t('fullstack.admin.account', :default => "Account"), :icon => "user", :"icon_color" => :white do %>
|
12
|
+
<%= nav_item t('fullstack.admin.logout', :default => "Logout"), admin_sessions_path, :method => :delete %>
|
11
13
|
<% end %>
|
12
14
|
<% end %>
|
13
15
|
|
@@ -15,19 +17,34 @@
|
|
15
17
|
|
16
18
|
<% content_for :nav do -%>
|
17
19
|
|
18
|
-
<div class="tabbable tabs-left float right">
|
19
|
-
<%= nav_list :class => "nav-tabs" do %>
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
21
|
+
<div class="sidebar">
|
22
|
+
<div class="sidebar-inner">
|
23
|
+
<div class="accordion sidebar-accordion" id="sidebar-accordion">
|
24
|
+
<% i = 0 %>
|
25
|
+
<% Fullstack::Admin.grouped_resources.each do |group, resources| %>
|
26
|
+
<div class="accordion-group">
|
27
|
+
<div class="accordion-heading">
|
28
|
+
<a href="#sidebar_group_collapsable_<%= i+=1 %>" data-parent="#sidebar-accordion" data-toggle="collapse" class="accordion-toggle">
|
29
|
+
<i class="icon-<%= group.icon %>"></i> <%= t("fullstack.admin.groups.#{group.name}", :default => group.name.to_s.humanize) %>
|
30
|
+
<% if resources.map(&:name).include?(plural_name) %>
|
31
|
+
<i class="icon-chevron-left float right" style="opacity: 0.4;"></i>
|
32
|
+
<% end %>
|
33
|
+
</a>
|
34
|
+
</div>
|
35
|
+
<div class="accordion-body collapse <%= resources.map(&:name).include?(plural_name) ? 'in' : '' %>" id="sidebar_group_collapsable_<%= i %>">
|
36
|
+
<div class="accordion-inner">
|
37
|
+
<ul class="nav nav-list">
|
38
|
+
<% resources.each do |resource| %>
|
39
|
+
<%= nav_item t("fullstack.admin.resources.#{resource.name}", :default => resource.name.to_s.humanize), [:admin, resource.name] %>
|
40
|
+
<% end %>
|
41
|
+
</ul>
|
42
|
+
</div>
|
43
|
+
</div>
|
44
|
+
</div>
|
45
|
+
<% end %>
|
46
|
+
</div>
|
47
|
+
</div>
|
48
|
+
</div>
|
32
49
|
|
33
|
-
<% end
|
50
|
+
<% end %>
|
@@ -1,10 +1,43 @@
|
|
1
|
+
<div class="page-header">
|
2
|
+
<% unless partial?('collection')%>
|
3
|
+
<div class="mb1 index-actions">
|
4
|
+
<% if subject.can_create?(collection_name) && controller.action_methods.include?("new") %>
|
5
|
+
<%= button t('fullstack.admin.new', :default => "New"),
|
6
|
+
send("new_admin_#{resource_name}_path"),
|
7
|
+
:type => :primary, :icon => :plus, :icon_color => :white %>
|
8
|
+
<% end %>
|
9
|
+
|
10
|
+
<% if subject.can_sort?(collection_name) && positionable?(current_collection.klass) %>
|
11
|
+
<%= button t('fullstack.admin.sort', :default => "Sort"),
|
12
|
+
send("admin_positionables_path", :type => resource_name)
|
13
|
+
%>
|
14
|
+
|
15
|
+
<% end %>
|
16
|
+
|
17
|
+
<%= button t('fullstack.admin.delete', :default => "Delete"),
|
18
|
+
'javascript:void(0)', :class => "toggle-delete",
|
19
|
+
:icon => :trash %>
|
20
|
+
</div>
|
21
|
+
|
22
|
+
<% end %>
|
23
|
+
|
24
|
+
<h1>
|
1
25
|
<% if content_for?(:title) %>
|
2
|
-
|
26
|
+
<%= yield(:title) %>
|
27
|
+
|
3
28
|
<% elsif @title %>
|
4
|
-
|
29
|
+
|
30
|
+
<%= @title %>
|
31
|
+
|
5
32
|
<% else -%>
|
6
|
-
|
33
|
+
|
34
|
+
<%= t(collection_name, :scope => "fullstack.admin.resources") %>
|
35
|
+
|
7
36
|
<% end -%>
|
37
|
+
</h1>
|
38
|
+
|
39
|
+
|
40
|
+
</div>
|
8
41
|
|
9
42
|
<% if partial?('collection') %>
|
10
43
|
<%= render :partial => "collection",
|
@@ -15,24 +48,7 @@
|
|
15
48
|
%>
|
16
49
|
<% else %>
|
17
50
|
|
18
|
-
|
19
|
-
<% if subject.can_create?(collection_name) && controller.action_methods.include?("new") %>
|
20
|
-
<%= button t('fullstack.admin.new', :default => "New"),
|
21
|
-
send("new_admin_#{resource_name}_path"),
|
22
|
-
:type => :primary, :icon => :plus, :icon_color => :white %>
|
23
|
-
<% end %>
|
24
|
-
|
25
|
-
<% if subject.can_sort?(collection_name) && positionable?(current_collection.klass) %>
|
26
|
-
<%= button t('fullstack.admin.sort', :default => "Sort"),
|
27
|
-
send("admin_positionables_path", :type => resource_name)
|
28
|
-
%>
|
29
|
-
|
30
|
-
<% end %>
|
31
|
-
|
32
|
-
<%= button t('fullstack.admin.delete', :default => "Delete"),
|
33
|
-
'javascript:void(0)', :class => "toggle-delete",
|
34
|
-
:icon => :trash %>
|
35
|
-
</div>
|
51
|
+
|
36
52
|
|
37
53
|
|
38
54
|
<table class="table table-bordered table-striped index-table">
|
@@ -56,16 +72,18 @@
|
|
56
72
|
<% content_for :aside do -%>
|
57
73
|
|
58
74
|
<% if (!@skip_filter) && (partial?('filter') || title_column(current_resource_class) || has_timestamps?(current_resource_class)) %>
|
59
|
-
<div class="
|
60
|
-
<div class="
|
61
|
-
|
75
|
+
<div class="box">
|
76
|
+
<div class="box-header">
|
77
|
+
<%= t('fullstack.admin.filter', :default => "Filter") %>
|
62
78
|
</div>
|
79
|
+
|
63
80
|
<%= admin_form_for @search, :url => self.send("admin_#{collection_name}_path") , :html => {:method => :get} do |f| %>
|
81
|
+
<div class="box-content">
|
64
82
|
|
65
83
|
<% if partial?('filter') %>
|
66
84
|
<%= render :partial => "filter", :locals => {:f => f} %>
|
67
85
|
<% else %>
|
68
|
-
<%= f.inputs do %>
|
86
|
+
<%= f.inputs :class => "filter-inputs" do %>
|
69
87
|
|
70
88
|
<% if tc = title_column(current_resource_class) %>
|
71
89
|
<%= f.input :"#{tc}_contains" %>
|
@@ -78,9 +96,10 @@
|
|
78
96
|
<% end %>
|
79
97
|
|
80
98
|
<% end %>
|
81
|
-
|
82
|
-
|
83
|
-
|
99
|
+
</div>
|
100
|
+
<div class="box-footer align-right">
|
101
|
+
<%= f.action t('fullstack.admin.filter', :default => "Filter"), :as => :button %>
|
102
|
+
</div>
|
84
103
|
<% end %>
|
85
104
|
</div>
|
86
105
|
<% end %>
|
@@ -0,0 +1,34 @@
|
|
1
|
+
<%= form_tag admin_sessions_path, :method => :post, :class => "login-box" do %>
|
2
|
+
<div class="login-box-header">
|
3
|
+
Login
|
4
|
+
</div>
|
5
|
+
<div class="login-box-content">
|
6
|
+
|
7
|
+
<% [:notice, :error, :alert].each do |sym| %>
|
8
|
+
|
9
|
+
<% if flash[sym].present? %>
|
10
|
+
<div class="alert alert-info alert-login ">
|
11
|
+
<%= flash[sym] %>
|
12
|
+
</div>
|
13
|
+
<% flash.discard(sym) %>
|
14
|
+
<% end %>
|
15
|
+
|
16
|
+
<% end %>
|
17
|
+
|
18
|
+
|
19
|
+
<div class="input-prepend">
|
20
|
+
<span class="add-on"><i class="icon-user"></i></span>
|
21
|
+
<%= text_field_tag :username, nil, :placeholder => I18n.t("username", :scope => "helpers.label", :default => "Username") %>
|
22
|
+
</div>
|
23
|
+
|
24
|
+
<div class="input-prepend">
|
25
|
+
<span class="add-on"><i class="icon-lock"></i></span>
|
26
|
+
<%= password_field_tag :password, nil, :placeholder => I18n.t("password", :scope => "helpers.label", :default => "Password") %>
|
27
|
+
</div>
|
28
|
+
</div>
|
29
|
+
|
30
|
+
<div class="actions form-actions login-box-footer">
|
31
|
+
<%= submit_tag "Login", :class => "btn btn-primary" %>
|
32
|
+
</div>
|
33
|
+
|
34
|
+
<% end %>
|
@@ -12,25 +12,23 @@
|
|
12
12
|
<%= render :partial => 'admin/nav' %>
|
13
13
|
|
14
14
|
<%= navbar :fluid => true, :fixed => :top do %>
|
15
|
-
|
15
|
+
<a class="brand" href="/admin">
|
16
|
+
<i class="icon-home icon-white"></i> <%= "#{app_name} Admin" %></a>
|
16
17
|
<%= yield :menu %>
|
17
18
|
<% end %>
|
18
19
|
|
19
20
|
<%= yield :crumbs %>
|
21
|
+
<%= yield :nav %>
|
20
22
|
|
21
23
|
<%= container :fluid => true, :class => "main" do %>
|
22
|
-
|
24
|
+
<%= row do %>
|
23
25
|
|
24
|
-
<%= span(
|
25
|
-
<%= yield :nav %>
|
26
|
-
<% end %>
|
27
|
-
|
28
|
-
<%= span(content_for?(:aside) ? 6 : 10, :id => "center") do %>
|
26
|
+
<%= span(content_for?(:aside) ? 9 : 12, :id => "center") do %>
|
29
27
|
<%= yield %>
|
30
28
|
<% end %>
|
31
29
|
|
32
30
|
<% if content_for?(:aside) %>
|
33
|
-
|
31
|
+
<%= span(3, :id => "right-aside") do %>
|
34
32
|
<%= yield :aside %>
|
35
33
|
<% end %>
|
36
34
|
<% end %>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="it">
|
3
|
+
<head>
|
4
|
+
<%= csrf_meta_tags %>
|
5
|
+
<title><%= ( @title ? "#{@title} - " : "" ) + "#{app_name} Admin" %></title>
|
6
|
+
|
7
|
+
<%= stylesheet_link_tag 'admin/admin' %>
|
8
|
+
<%= yield :stylesheets %>
|
9
|
+
</head>
|
10
|
+
|
11
|
+
<body>
|
12
|
+
<%= yield %>
|
13
|
+
</body>
|
14
|
+
</html>
|
15
|
+
|
data/config/locales/it.yml
CHANGED
@@ -30,6 +30,10 @@ it:
|
|
30
30
|
choose_a_file: "Carica"
|
31
31
|
change: "Cambia"
|
32
32
|
preview: "Anteprima"
|
33
|
+
signed_in: 'Login effettuato con successo.'
|
34
|
+
signed_out: 'Logout effettuato con successo.'
|
35
|
+
login_failed: 'Nome utente o password non validi.'
|
36
|
+
|
33
37
|
|
34
38
|
form:
|
35
39
|
correct_these_errors_and_retry: "Correggi questi errori e riprova"
|
data/config/routes.rb
CHANGED
@@ -3,6 +3,10 @@ Rails.application.routes.draw do
|
|
3
3
|
mount Ckeditor::Engine => '/ckeditor'
|
4
4
|
|
5
5
|
namespace :admin do
|
6
|
+
resources :sessions, :only => [:new, :create] do
|
7
|
+
match :destroy, :via => :delete, :on => :collection
|
8
|
+
end
|
9
|
+
|
6
10
|
resources :positionables, :only => [:index] do
|
7
11
|
post :sort, :on => :collection
|
8
12
|
end
|
data/fullstack-admin.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "fullstack-admin"
|
8
|
-
s.version = "0.2.
|
8
|
+
s.version = "0.2.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["mcasimir"]
|
12
|
-
s.date = "2012-11-
|
12
|
+
s.date = "2012-11-05"
|
13
13
|
s.description = "Administration interface framework for fullstack"
|
14
14
|
s.email = "maurizio.cas@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -939,6 +939,7 @@ Gem::Specification.new do |s|
|
|
939
939
|
"app/assets/javascripts/support/plupload.js.coffee",
|
940
940
|
"app/assets/javascripts/support/uploads.js.coffee",
|
941
941
|
"app/assets/stylesheets/admin/base.css",
|
942
|
+
"app/assets/stylesheets/admin/login.css",
|
942
943
|
"app/assets/stylesheets/support/ajax_loading.css",
|
943
944
|
"app/assets/stylesheets/support/base.css",
|
944
945
|
"app/assets/stylesheets/support/bootstrap-workarounds.css",
|
@@ -952,6 +953,7 @@ Gem::Specification.new do |s|
|
|
952
953
|
"app/controllers/admin/responder.rb",
|
953
954
|
"app/controllers/admin/scaffold_controller.rb",
|
954
955
|
"app/controllers/admin/sessions_controller.rb",
|
956
|
+
"app/controllers/admin/subject_model_adapter.rb",
|
955
957
|
"app/helpers/admin_form_helper.rb",
|
956
958
|
"app/helpers/scaffold_helper.rb",
|
957
959
|
"app/inputs/country_input.rb",
|
@@ -993,6 +995,7 @@ Gem::Specification.new do |s|
|
|
993
995
|
"app/views/admin/base/new.html.erb",
|
994
996
|
"app/views/admin/base/update.js.coffee",
|
995
997
|
"app/views/admin/positionables/_collection.html.erb",
|
998
|
+
"app/views/admin/sessions/new.html.erb",
|
996
999
|
"app/views/kaminari/_first_page.html.erb",
|
997
1000
|
"app/views/kaminari/_gap.html.erb",
|
998
1001
|
"app/views/kaminari/_last_page.html.erb",
|
@@ -1001,6 +1004,7 @@ Gem::Specification.new do |s|
|
|
1001
1004
|
"app/views/kaminari/_paginator.html.erb",
|
1002
1005
|
"app/views/kaminari/_prev_page.html.erb",
|
1003
1006
|
"app/views/layouts/admin.html.erb",
|
1007
|
+
"app/views/layouts/login.html.erb",
|
1004
1008
|
"config/initializers/formtastic_bootstrap_timeish_hack.rb",
|
1005
1009
|
"config/locales/devise.en.yml",
|
1006
1010
|
"config/locales/devise.views.en.yml",
|
@@ -61,7 +61,7 @@ module Fullstack
|
|
61
61
|
|
62
62
|
# Group
|
63
63
|
class Group < Entity
|
64
|
-
attr_accessor :children, :name
|
64
|
+
attr_accessor :children, :name, :icon
|
65
65
|
|
66
66
|
def initialize(name)
|
67
67
|
@name = "#{name}"
|
@@ -128,6 +128,27 @@ module Fullstack
|
|
128
128
|
end
|
129
129
|
|
130
130
|
module_function :resources
|
131
|
+
|
132
|
+
def grouped_resources
|
133
|
+
if !@resource_groups
|
134
|
+
@resource_groups = {}
|
135
|
+
current_group = nil
|
136
|
+
|
137
|
+
resources.each do |rog|
|
138
|
+
if rog.type == :group
|
139
|
+
@resource_groups[rog] = []
|
140
|
+
current_group = rog
|
141
|
+
elsif current_group
|
142
|
+
@resource_groups[current_group] << rog
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
@resource_groups
|
147
|
+
end
|
148
|
+
|
149
|
+
module_function :grouped_resources
|
150
|
+
|
151
|
+
|
131
152
|
end
|
132
153
|
end
|
133
154
|
|
@@ -33,12 +33,13 @@ eos
|
|
33
33
|
|
34
34
|
|
35
35
|
def users
|
36
|
+
generate "sorcery:install remember_me activity_logging brute_force_protection --model Superuser"
|
36
37
|
generate "migration:from user"
|
37
38
|
append_to_file "db/seeds.rb" do
|
38
39
|
<<-eos
|
39
40
|
|
40
41
|
if Rails.env.development?
|
41
|
-
user =
|
42
|
+
user = Superuser.new( :email => "admin@example.com",
|
42
43
|
:password => "password" )
|
43
44
|
|
44
45
|
user.skip_confirmation! if user.respond_to?(:skip_confirmation!)
|
@@ -64,7 +65,7 @@ eos
|
|
64
65
|
eos
|
65
66
|
route(src)
|
66
67
|
|
67
|
-
route("\n devise_for :users\n")
|
68
|
+
#route("\n devise_for :users\n")
|
68
69
|
end
|
69
70
|
|
70
71
|
protected
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fullstack-admin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-11-
|
12
|
+
date: 2012-11-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -1149,6 +1149,7 @@ files:
|
|
1149
1149
|
- app/assets/javascripts/support/plupload.js.coffee
|
1150
1150
|
- app/assets/javascripts/support/uploads.js.coffee
|
1151
1151
|
- app/assets/stylesheets/admin/base.css
|
1152
|
+
- app/assets/stylesheets/admin/login.css
|
1152
1153
|
- app/assets/stylesheets/support/ajax_loading.css
|
1153
1154
|
- app/assets/stylesheets/support/base.css
|
1154
1155
|
- app/assets/stylesheets/support/bootstrap-workarounds.css
|
@@ -1162,6 +1163,7 @@ files:
|
|
1162
1163
|
- app/controllers/admin/responder.rb
|
1163
1164
|
- app/controllers/admin/scaffold_controller.rb
|
1164
1165
|
- app/controllers/admin/sessions_controller.rb
|
1166
|
+
- app/controllers/admin/subject_model_adapter.rb
|
1165
1167
|
- app/helpers/admin_form_helper.rb
|
1166
1168
|
- app/helpers/scaffold_helper.rb
|
1167
1169
|
- app/inputs/country_input.rb
|
@@ -1203,6 +1205,7 @@ files:
|
|
1203
1205
|
- app/views/admin/base/new.html.erb
|
1204
1206
|
- app/views/admin/base/update.js.coffee
|
1205
1207
|
- app/views/admin/positionables/_collection.html.erb
|
1208
|
+
- app/views/admin/sessions/new.html.erb
|
1206
1209
|
- app/views/kaminari/_first_page.html.erb
|
1207
1210
|
- app/views/kaminari/_gap.html.erb
|
1208
1211
|
- app/views/kaminari/_last_page.html.erb
|
@@ -1211,6 +1214,7 @@ files:
|
|
1211
1214
|
- app/views/kaminari/_paginator.html.erb
|
1212
1215
|
- app/views/kaminari/_prev_page.html.erb
|
1213
1216
|
- app/views/layouts/admin.html.erb
|
1217
|
+
- app/views/layouts/login.html.erb
|
1214
1218
|
- config/initializers/formtastic_bootstrap_timeish_hack.rb
|
1215
1219
|
- config/locales/devise.en.yml
|
1216
1220
|
- config/locales/devise.views.en.yml
|
@@ -1291,7 +1295,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
1291
1295
|
version: '0'
|
1292
1296
|
segments:
|
1293
1297
|
- 0
|
1294
|
-
hash:
|
1298
|
+
hash: 445393833660587370
|
1295
1299
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
1296
1300
|
none: false
|
1297
1301
|
requirements:
|