upmin-admin 0.1.01 → 0.1.3
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 +4 -4
- data/README.md +10 -18
- data/Rakefile +18 -18
- data/app/assets/javascripts/upmin/attributes/datetime.js +37 -11
- data/app/assets/stylesheets/upmin/application.css +0 -1
- data/app/assets/stylesheets/upmin/base.css.scss +8 -1
- data/app/assets/stylesheets/upmin/dashboard.css +16 -0
- data/app/assets/stylesheets/upmin/instances.css.scss +7 -0
- data/app/controllers/upmin/dashboard_controller.rb +11 -0
- data/app/controllers/upmin/models_controller.rb +28 -9
- data/app/views/layouts/upmin/application.html.haml +6 -2
- data/app/views/upmin/dashboard/_chart.html.haml +9 -0
- data/app/views/upmin/dashboard/index.html.haml +14 -0
- data/app/views/upmin/models/search.html.haml +20 -4
- data/app/views/upmin/partials/attributes/_boolean.html.haml +1 -6
- data/app/views/upmin/partials/attributes/_date.html.haml +26 -0
- data/app/views/upmin/partials/attributes/_enum.html.haml +9 -0
- data/app/views/upmin/partials/attributes/_money_cents.html.haml +10 -0
- data/app/views/upmin/partials/models/_model.html.haml +5 -6
- data/app/views/upmin/partials/models/_new_model.html.haml +1 -1
- data/app/views/upmin/partials/search_boxes/_ransack_search_box.html.haml +6 -1
- data/config/routes.rb +3 -5
- data/lib/generators/upmin/install_generator.rb +24 -0
- data/lib/generators/upmin/templates/initializer.rb +13 -0
- data/lib/upmin/active_record/model.rb +15 -1
- data/lib/upmin/admin.rb +2 -1
- data/lib/upmin/attribute.rb +4 -1
- data/lib/upmin/configuration.rb +1 -0
- data/lib/upmin/data_mapper/model.rb +10 -0
- data/lib/upmin/engine.rb +4 -3
- data/lib/upmin/model.rb +37 -5
- data/lib/upmin/railtie.rb +1 -0
- data/lib/upmin/railties/dashboard.rb +88 -0
- data/lib/upmin/railties/render_helpers.rb +2 -0
- data/lib/upmin/version.rb +1 -1
- data/spec/features/delete_model_spec.rb +38 -0
- data/spec/features/edit_model_spec.rb +1 -1
- data/spec/features/enum_attributes_spec.rb +24 -0
- data/spec/features/navbar_spec.rb +4 -4
- data/spec/features/new_model_spec.rb +1 -1
- data/spec/features/search_spec.rb +17 -27
- data/spec/lib/attribute_spec.rb +15 -0
- data/spec/lib/upmin/active_record/model_spec.rb +15 -0
- data/spec/spec_helper.rb +8 -0
- metadata +49 -4
- data/app/views/upmin/models/dashboard.html.haml +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 04a4f4f1edcfc6d6b2717175fcba3473962400d6
|
4
|
+
data.tar.gz: 40a38a4a7233b3a9ddb09e826731911b346c0286
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b6a111fa50f037447043dc456538dbd033ebae0f77b17fd5ce42228ce529576c60c0c9a8844fa84769dcf1e522a9e240121a8a46e509deb946713f6a3465b5d0
|
7
|
+
data.tar.gz: 3acbf22f1bf9df75aab7b3481e30712b935d5c26cb7b6613bd61c9962ea59e80a17357ab396c1c3c7317291611b0b1fef958595ead294d0ecf5c79c366187912
|
data/README.md
CHANGED
@@ -6,15 +6,9 @@ Upmin Admin is a framework for creating powerful Ruby on Rails admin backends wi
|
|
6
6
|
Upmin currently supports Rails 3.2, 4.0, 4.1 & 4.2.
|
7
7
|
|
8
8
|
|
9
|
-
## Demo Videos
|
10
|
-
|
11
|
-
**NOTE** - The videos are currently outdated, and are only relevant for versions below `0.1.0`. Please refer to the docs for recent releases until we get them updated.
|
12
|
-
|
13
|
-
To see videos showing how to install and giving a pretty good overview of the main features of upmin-admin go to [https://www.upmin.com/admin-rails](https://www.upmin.com/admin-rails).
|
14
|
-
|
15
9
|
## Demo Applications
|
16
10
|
|
17
|
-
There is
|
11
|
+
There is a demo application you can test out here: [store_demo](https://github.com/upmin/store_demo).
|
18
12
|
|
19
13
|
If you do choose to use the [store_demo](https://github.com/upmin/store_demo), please follow the directions in the [README](https://github.com/upmin/store_demo/blob/master/README.md) to ensure you have seed data to work with.
|
20
14
|
|
@@ -29,31 +23,29 @@ Installing `upmin-admin` is incredibly easy. Simple add the gem to your `Gemfile
|
|
29
23
|
gem 'upmin-admin'
|
30
24
|
```
|
31
25
|
|
32
|
-
|
26
|
+
Then run the generator:
|
33
27
|
|
34
28
|
```ruby
|
35
|
-
|
29
|
+
rails g upmin:install
|
36
30
|
```
|
37
31
|
|
38
|
-
|
32
|
+
This mounts the engine in your `routes.rb` file:
|
39
33
|
|
40
34
|
```ruby
|
41
|
-
mount Upmin::Engine => '/
|
35
|
+
mount Upmin::Engine => '/admin'
|
42
36
|
```
|
43
37
|
|
44
|
-
And
|
45
|
-
|
46
|
-
|
47
|
-
### Rails 4.2
|
38
|
+
And adds a configuration file at `config/initializers/upmin.rb`
|
48
39
|
|
49
|
-
|
40
|
+
If you already have routes pointing to `/admin` you can use any path you want, for example you could use the following instead:
|
50
41
|
|
51
42
|
```ruby
|
52
|
-
|
43
|
+
mount Upmin::Engine => '/ice-ice-baby'
|
53
44
|
```
|
54
45
|
|
55
|
-
|
46
|
+
And you would access your admin page at `localhost:3000/ice-ice-baby` or `example.com/ice-ice-baby`.
|
56
47
|
|
48
|
+
If you prefer not to use the generator, simply add the route, and optionally the config file as documented in the wiki.
|
57
49
|
|
58
50
|
## Documentation
|
59
51
|
|
data/Rakefile
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
#!/usr/bin/env rake
|
2
2
|
# encoding: utf-8
|
3
3
|
|
4
|
-
require 'bundler'
|
5
|
-
Bundler::GemHelper.install_tasks
|
4
|
+
require 'bundler/gem_tasks'
|
6
5
|
|
7
6
|
require 'rspec/core'
|
8
7
|
require 'rspec/core/rake_task'
|
@@ -35,28 +34,29 @@ namespace :spec do
|
|
35
34
|
%w(active_record_32 active_record_40 active_record_41 active_record_42 will_paginate data_mapper).each do |gemfile|
|
36
35
|
desc "Run Tests against #{gemfile}"
|
37
36
|
task "#{gemfile}" do
|
38
|
-
Dir.chdir("test_apps/#{gemfile}")
|
39
|
-
|
40
|
-
|
41
|
-
|
37
|
+
Dir.chdir("test_apps/#{gemfile}") do
|
38
|
+
puts "Testing in #{`pwd`}"
|
39
|
+
sh "bundle install --quiet"
|
40
|
+
sh "bundle update --quiet"
|
42
41
|
|
43
|
-
|
44
|
-
|
42
|
+
# Drop migrations and recreate
|
43
|
+
sh "rm -rf db/migrate/*"
|
45
44
|
|
46
|
-
|
47
|
-
|
48
|
-
|
45
|
+
if gemfile != "data_mapper"
|
46
|
+
sh "bundle exec rake railties:install:migrations > /dev/null"
|
47
|
+
end
|
49
48
|
|
50
|
-
|
51
|
-
|
52
|
-
|
49
|
+
if gemfile == "active_record_32"
|
50
|
+
sh "bundle exec rake db:drop db:create db:migrate --quiet > /dev/null"
|
51
|
+
end
|
53
52
|
|
54
|
-
|
53
|
+
sh "RAILS_ENV=test bundle exec rake db:drop db:create db:migrate --quiet > /dev/null"
|
55
54
|
|
56
|
-
|
55
|
+
update_files
|
57
56
|
|
58
|
-
|
59
|
-
|
57
|
+
# Run tests
|
58
|
+
sh "bundle exec rake"
|
59
|
+
end
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
@@ -7,9 +7,9 @@
|
|
7
7
|
return null;
|
8
8
|
} else {
|
9
9
|
var m = moment();
|
10
|
-
m.utc().year(matches[1]);
|
11
|
-
m.utc().month(matches[2]);
|
12
|
-
m.utc().date(matches[3]);
|
10
|
+
m.utc().year(parseInt(matches[1]));
|
11
|
+
m.utc().month(parseInt(matches[2])-1);
|
12
|
+
m.utc().date(parseInt(matches[3]));
|
13
13
|
return m;
|
14
14
|
}
|
15
15
|
}
|
@@ -68,13 +68,8 @@
|
|
68
68
|
return curMoment;
|
69
69
|
}
|
70
70
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
// Initializing the attribute view.
|
77
|
-
var init = function(formId) {
|
71
|
+
// Initializing the DateTime attribute view.
|
72
|
+
var initDateTime = function(formId) {
|
78
73
|
var dtSection = $("." + formId + ".datetime-attribute");
|
79
74
|
var hiddenInput = dtSection.find("input#" + formId + "[type=hidden]");
|
80
75
|
var dateInput = dtSection.find("#" + formId + "-date");
|
@@ -123,6 +118,35 @@
|
|
123
118
|
});
|
124
119
|
}
|
125
120
|
|
121
|
+
// Initializing the Date attribute view.
|
122
|
+
// TODO: Dry this up against DateTime
|
123
|
+
var initDate = function(formId) {
|
124
|
+
var dtSection = $("." + formId + ".date-attribute");
|
125
|
+
var hiddenInput = dtSection.find("input#" + formId + "[type=hidden]");
|
126
|
+
var dateInput = dtSection.find("#" + formId + "-date");
|
127
|
+
|
128
|
+
var dtMoment = moment(hiddenInput.val());
|
129
|
+
if (hiddenInput.val() == "") {
|
130
|
+
dtMoment = null;
|
131
|
+
}
|
132
|
+
|
133
|
+
var handleDateSelect = function() {
|
134
|
+
var newDateMoment = parseDate(dateInput.val());
|
135
|
+
setInputDate(newDateMoment, hiddenInput);
|
136
|
+
return newDateMoment;
|
137
|
+
}
|
138
|
+
|
139
|
+
// Create Date Picker
|
140
|
+
var datePicker = new Pikaday({ field: $("#" + formId + "-date")[0], onSelect: handleDateSelect });
|
141
|
+
|
142
|
+
dtSection.closest("form").submit(function(event) {
|
143
|
+
event.preventDefault();
|
144
|
+
|
145
|
+
handleDateSelect();
|
146
|
+
|
147
|
+
event.target.submit();
|
148
|
+
});
|
149
|
+
}
|
126
150
|
|
127
151
|
if (window.Upmin == null) {
|
128
152
|
window.Upmin = {};
|
@@ -130,5 +154,7 @@
|
|
130
154
|
if (window.Upmin.Attributes == null) {
|
131
155
|
window.Upmin.Attributes = {};
|
132
156
|
}
|
133
|
-
|
157
|
+
|
158
|
+
window.Upmin.Attributes.DateTime = initDateTime;
|
159
|
+
window.Upmin.Attributes.Date = initDate;
|
134
160
|
})();
|
@@ -52,10 +52,17 @@ body {
|
|
52
52
|
padding-top: 8px;
|
53
53
|
}
|
54
54
|
|
55
|
+
.page-entries-info {
|
56
|
+
margin: 5px 0px 15px;
|
57
|
+
}
|
58
|
+
|
55
59
|
.pagination:first-of-type {
|
56
|
-
margin
|
60
|
+
margin: 5px 0px 0px;
|
57
61
|
}
|
58
62
|
|
63
|
+
.pagination:last-of-type {
|
64
|
+
margin: 10px 0px 20px;
|
65
|
+
}
|
59
66
|
|
60
67
|
.wizard span {padding: 12px 12px 10px 12px; margin-right:5px; background:#efefef; position:relative; display:inline-block; }
|
61
68
|
.wizard span:before {width:0px; height:0px; border-top: 20px inset transparent; border-bottom: 20px inset transparent; border-left: 20px solid #fff; position: absolute; content: ""; top: 0; left: 0;}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
.panel .panel-heading {
|
3
|
+
border-bottom: 1px solid #d7d7d7;
|
4
|
+
color: #666;
|
5
|
+
font-size: 14px;
|
6
|
+
font-weight: 200;
|
7
|
+
padding: 7px 10px 4px;
|
8
|
+
}
|
9
|
+
|
10
|
+
.panel .panel-footer {
|
11
|
+
background: #fbfbfb;
|
12
|
+
border-top: 1px solid #e2e2e2;
|
13
|
+
color: #808080;
|
14
|
+
font-size: 12px;
|
15
|
+
padding: 8px 10px 5px;
|
16
|
+
}
|
@@ -24,6 +24,9 @@
|
|
24
24
|
> a {
|
25
25
|
color: $hex;
|
26
26
|
}
|
27
|
+
> a.delete {
|
28
|
+
color: #fff;
|
29
|
+
}
|
27
30
|
}
|
28
31
|
}
|
29
32
|
}
|
@@ -67,6 +70,10 @@
|
|
67
70
|
font-size: 1.1em;
|
68
71
|
}
|
69
72
|
|
73
|
+
.radio, .radio-inline input {
|
74
|
+
height: auto;
|
75
|
+
}
|
76
|
+
|
70
77
|
.well {
|
71
78
|
padding: 9px;
|
72
79
|
margin-bottom: 0;
|
@@ -2,8 +2,8 @@ require_dependency "upmin/application_controller"
|
|
2
2
|
|
3
3
|
module Upmin
|
4
4
|
class ModelsController < ApplicationController
|
5
|
-
before_filter :set_klass, only: [:new, :create, :show, :update, :search, :action]
|
6
|
-
before_filter :set_model, only: [:show, :update, :action]
|
5
|
+
before_filter :set_klass, only: [:new, :create, :show, :update, :destroy, :search, :action]
|
6
|
+
before_filter :set_model, only: [:show, :update, :destroy, :action]
|
7
7
|
|
8
8
|
before_filter :set_page, only: [:search]
|
9
9
|
before_filter :set_query, only: [:search]
|
@@ -12,9 +12,6 @@ module Upmin
|
|
12
12
|
before_filter :set_action, only: [:action]
|
13
13
|
before_filter :set_arguments, only: [:action]
|
14
14
|
|
15
|
-
def dashboard
|
16
|
-
end
|
17
|
-
|
18
15
|
# GET /:model_name/:id
|
19
16
|
def show
|
20
17
|
end
|
@@ -29,7 +26,7 @@ module Upmin
|
|
29
26
|
@model = @klass.new
|
30
27
|
raw_model = @model.model
|
31
28
|
|
32
|
-
args = params[@klass.underscore_name]
|
29
|
+
args = params[@klass.underscore_name] || []
|
33
30
|
|
34
31
|
args.each do |key, value|
|
35
32
|
# TODO(jon): Figure out a way to do transforms.
|
@@ -55,7 +52,6 @@ module Upmin
|
|
55
52
|
end
|
56
53
|
end
|
57
54
|
|
58
|
-
|
59
55
|
# PUT /:model_name/:id
|
60
56
|
def update
|
61
57
|
|
@@ -89,6 +85,25 @@ module Upmin
|
|
89
85
|
# @results = Upmin::Paginator.paginate(@q.result(distinct: true), @page, 30)
|
90
86
|
end
|
91
87
|
|
88
|
+
# DELETE /:model_name/:id
|
89
|
+
def destroy
|
90
|
+
raw_model = @model.model
|
91
|
+
#destroy does not work when using datamapper and have associations but destroy! works fine
|
92
|
+
#destroy! does not exist in ActiveRecord
|
93
|
+
if defined?(raw_model.destroy!)
|
94
|
+
@result = raw_model.destroy! #data mapper
|
95
|
+
else
|
96
|
+
@result = raw_model.destroy #active record
|
97
|
+
end
|
98
|
+
if @result
|
99
|
+
flash.now[:notice] = "#{@klass.humanized_name(:singular)} deleted successfully."
|
100
|
+
redirect_to @klass.search_path
|
101
|
+
else
|
102
|
+
flash.now[:alert] = "#{@klass.humanized_name(:singular)} was NOT deleted."
|
103
|
+
render(:show)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
92
107
|
def action
|
93
108
|
@response = @action.perform(@arguments)
|
94
109
|
|
@@ -128,9 +143,13 @@ module Upmin
|
|
128
143
|
@klass = Upmin::Model.find_class(params[:klass])
|
129
144
|
end
|
130
145
|
|
146
|
+
def set_klasses
|
147
|
+
@klasses = Upmin::Model.find_class(params[:klass])
|
148
|
+
end
|
149
|
+
|
131
150
|
def set_action
|
132
|
-
action_name = params[:method]
|
133
|
-
@action = @model.actions.select{ |action| action.name == action_name }.first
|
151
|
+
action_name = params[:method]
|
152
|
+
@action = @model.actions.select{ |action| action.name.to_s == action_name }.first
|
134
153
|
|
135
154
|
raise Upmin::InvalidAction.new(params[:method]) unless @action
|
136
155
|
end
|
@@ -1,16 +1,20 @@
|
|
1
1
|
!!!
|
2
2
|
%html
|
3
3
|
%head
|
4
|
+
%meta{ name: "viewport", content: "width=device-width, initial-scale=1.0" }
|
4
5
|
%title
|
5
6
|
Upmin Dashboard
|
6
7
|
= stylesheet_link_tag("upmin/application", media: "all")
|
8
|
+
%script{src: "//cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.3/moment.min.js"}
|
7
9
|
= javascript_include_tag("upmin/application")
|
8
10
|
= csrf_meta_tags
|
9
11
|
|
10
|
-
%link{href: "//cdn.jsdelivr.net/bootstrap/3.2.0/css/bootstrap.min.css", rel: "stylesheet"
|
11
|
-
|
12
|
+
%link{href: "//cdn.jsdelivr.net/bootstrap/3.2.0/css/bootstrap.min.css", rel: "stylesheet"}
|
13
|
+
-#%link{href: "//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css", rel: "stylesheet"}
|
12
14
|
%script{src: "//cdn.jsdelivr.net/bootstrap/3.2.0/js/bootstrap.min.js"}
|
13
15
|
%script{src: "//cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.3/moment.min.js"}
|
16
|
+
-# TODO (matt): Only include this on the dashboard page:
|
17
|
+
= javascript_include_tag "//www.google.com/jsapi", "chartkick"
|
14
18
|
|
15
19
|
- if content_for?(:head)
|
16
20
|
= yield(:head)
|
@@ -0,0 +1,9 @@
|
|
1
|
+
-limit ||= 30
|
2
|
+
.col-sm-6.col-md-4
|
3
|
+
.panel.panel-default
|
4
|
+
.panel-heading
|
5
|
+
#{model.humanized_name} created per #{model.model_class.grouping limit}
|
6
|
+
.panel-body
|
7
|
+
= column_chart model.model_class.group_by_best_fit limit
|
8
|
+
.panel-footer
|
9
|
+
Number of #{model.model_name.plural} created per #{model.model_class.grouping limit}, for all #{model.count} records.
|
@@ -0,0 +1,14 @@
|
|
1
|
+
-if defined?(DataMapper)
|
2
|
+
.container
|
3
|
+
.row
|
4
|
+
.jumbotron
|
5
|
+
%h2
|
6
|
+
Sorry, the default dashboard doesn't support DataMapper
|
7
|
+
%p
|
8
|
+
Please create a custom dashboard view in:
|
9
|
+
%code
|
10
|
+
app/views/upmin/dashboard/index.html.[haml|erb|etc]
|
11
|
+
-else
|
12
|
+
.container-fluid
|
13
|
+
.row
|
14
|
+
= render partial: 'chart', collection: @models, as: 'model', locals: { limit: 30 }
|
@@ -1,13 +1,29 @@
|
|
1
1
|
.container
|
2
|
+
- if notice
|
3
|
+
.alert.alert-dismissable.alert-info
|
4
|
+
%button.close{"data-dismiss" => "alert", type: "button"}
|
5
|
+
%span{"aria-hidden" => "true"} ×
|
6
|
+
= notice
|
7
|
+
- if alert
|
8
|
+
.alert.alert-dismissable.alert-danger
|
9
|
+
%button.close{"data-dismiss" => "alert", type: "button"}
|
10
|
+
%span{"aria-hidden" => "true"} ×
|
11
|
+
= alert
|
12
|
+
- if @model.errors.any?
|
13
|
+
%ul
|
14
|
+
- @model.errors.each do |field, error|
|
15
|
+
%li
|
16
|
+
%b
|
17
|
+
= field
|
18
|
+
= error
|
2
19
|
.row
|
3
20
|
.col-md-8
|
21
|
+
.page-entries-info
|
22
|
+
= page_entries_info(@query.paginated_results)
|
4
23
|
= up_paginate(@query.paginated_results)
|
5
|
-
-# TODO(jon): Add pagination w/ search results
|
6
24
|
= up_render(@query)
|
7
|
-
%br
|
8
25
|
= up_paginate(@query.paginated_results)
|
9
|
-
|
10
|
-
%br
|
26
|
+
|
11
27
|
.col-md-4
|
12
28
|
-# TODO(jon): Implement up_search_box
|
13
29
|
= up_render(@klass)
|
@@ -2,9 +2,4 @@
|
|
2
2
|
%label{for: attribute.form_id}
|
3
3
|
= attribute.label_name
|
4
4
|
|
5
|
-
|
6
|
-
= f.check_box(attribute.name, value: boolean, class: "boolean")
|
7
|
-
|
8
|
-
- else
|
9
|
-
%p.well
|
10
|
-
= attribute.value
|
5
|
+
= form_builder.check_box(attribute.name, value: boolean, class: "boolean", disabled: !attribute.editable?)
|