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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -18
  3. data/Rakefile +18 -18
  4. data/app/assets/javascripts/upmin/attributes/datetime.js +37 -11
  5. data/app/assets/stylesheets/upmin/application.css +0 -1
  6. data/app/assets/stylesheets/upmin/base.css.scss +8 -1
  7. data/app/assets/stylesheets/upmin/dashboard.css +16 -0
  8. data/app/assets/stylesheets/upmin/instances.css.scss +7 -0
  9. data/app/controllers/upmin/dashboard_controller.rb +11 -0
  10. data/app/controllers/upmin/models_controller.rb +28 -9
  11. data/app/views/layouts/upmin/application.html.haml +6 -2
  12. data/app/views/upmin/dashboard/_chart.html.haml +9 -0
  13. data/app/views/upmin/dashboard/index.html.haml +14 -0
  14. data/app/views/upmin/models/search.html.haml +20 -4
  15. data/app/views/upmin/partials/attributes/_boolean.html.haml +1 -6
  16. data/app/views/upmin/partials/attributes/_date.html.haml +26 -0
  17. data/app/views/upmin/partials/attributes/_enum.html.haml +9 -0
  18. data/app/views/upmin/partials/attributes/_money_cents.html.haml +10 -0
  19. data/app/views/upmin/partials/models/_model.html.haml +5 -6
  20. data/app/views/upmin/partials/models/_new_model.html.haml +1 -1
  21. data/app/views/upmin/partials/search_boxes/_ransack_search_box.html.haml +6 -1
  22. data/config/routes.rb +3 -5
  23. data/lib/generators/upmin/install_generator.rb +24 -0
  24. data/lib/generators/upmin/templates/initializer.rb +13 -0
  25. data/lib/upmin/active_record/model.rb +15 -1
  26. data/lib/upmin/admin.rb +2 -1
  27. data/lib/upmin/attribute.rb +4 -1
  28. data/lib/upmin/configuration.rb +1 -0
  29. data/lib/upmin/data_mapper/model.rb +10 -0
  30. data/lib/upmin/engine.rb +4 -3
  31. data/lib/upmin/model.rb +37 -5
  32. data/lib/upmin/railtie.rb +1 -0
  33. data/lib/upmin/railties/dashboard.rb +88 -0
  34. data/lib/upmin/railties/render_helpers.rb +2 -0
  35. data/lib/upmin/version.rb +1 -1
  36. data/spec/features/delete_model_spec.rb +38 -0
  37. data/spec/features/edit_model_spec.rb +1 -1
  38. data/spec/features/enum_attributes_spec.rb +24 -0
  39. data/spec/features/navbar_spec.rb +4 -4
  40. data/spec/features/new_model_spec.rb +1 -1
  41. data/spec/features/search_spec.rb +17 -27
  42. data/spec/lib/attribute_spec.rb +15 -0
  43. data/spec/lib/upmin/active_record/model_spec.rb +15 -0
  44. data/spec/spec_helper.rb +8 -0
  45. metadata +49 -4
  46. 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: 910d8396eb70b53feb5a498af6acc41edb1e3d1e
4
- data.tar.gz: 6e2d7366490c0dfb137a503a02fd6784111714c4
3
+ metadata.gz: 04a4f4f1edcfc6d6b2717175fcba3473962400d6
4
+ data.tar.gz: 40a38a4a7233b3a9ddb09e826731911b346c0286
5
5
  SHA512:
6
- metadata.gz: 4aea3404252228d686ed20f0a480e7d32898c70ef6edc895b387272bc14cfdb82bf6e06f8044fa15360fcf3ddc3dea147b6429c3cd6997460dff5d785e153e01
7
- data.tar.gz: bdb283f1c155465a8f94be4b5d290d21ff0c2883c9536323850b809a5e3a0223df65c2d3212f44bb073c89bd587c3b192e1d49f9ded56fe327a6dbdafc815df8
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 also a demo application you can test out here: [store_demo](https://github.com/upmin/store_demo). The repository is maintained and updated by [Upmin](https://www.upmin.com), but you are welcome to contribute to it.
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
- And then mount the engine in your `routes.rb` file:
26
+ Then run the generator:
33
27
 
34
28
  ```ruby
35
- mount Upmin::Engine => '/admin'
29
+ rails g upmin:install
36
30
  ```
37
31
 
38
- If you already have routes pointing to `/admin` you can use any path you want, for example you could use the following instead:
32
+ This mounts the engine in your `routes.rb` file:
39
33
 
40
34
  ```ruby
41
- mount Upmin::Engine => '/ice-ice-baby'
35
+ mount Upmin::Engine => '/admin'
42
36
  ```
43
37
 
44
- And you would access your admin page at `localhost:3000/ice-ice-baby` or `yoursite.com/ice-ice-baby`.
45
-
46
-
47
- ### Rails 4.2
38
+ And adds a configuration file at `config/initializers/upmin.rb`
48
39
 
49
- Add the following to your gemfile:
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
- gem 'ransack', github: 'activerecord-hackery/ransack', branch: 'rails-4.2'
43
+ mount Upmin::Engine => '/ice-ice-baby'
53
44
  ```
54
45
 
55
- `upmin-admin` currently depends on ransack, and you need to use the 4.2 branch of ransack due to changes in ActiveRecord.
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
- puts "Testing in #{`pwd`}"
40
- sh "bundle install --quiet"
41
- sh "bundle update --quiet"
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
- # Drop migrations and recreate
44
- sh "rm -rf db/migrate/*"
42
+ # Drop migrations and recreate
43
+ sh "rm -rf db/migrate/*"
45
44
 
46
- if gemfile != "data_mapper"
47
- sh "bundle exec rake railties:install:migrations > /dev/null"
48
- end
45
+ if gemfile != "data_mapper"
46
+ sh "bundle exec rake railties:install:migrations > /dev/null"
47
+ end
49
48
 
50
- if gemfile == "active_record_32"
51
- sh "bundle exec rake db:drop db:create db:migrate --quiet > /dev/null"
52
- end
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
- sh "RAILS_ENV=test bundle exec rake db:drop db:create db:migrate --quiet > /dev/null"
53
+ sh "RAILS_ENV=test bundle exec rake db:drop db:create db:migrate --quiet > /dev/null"
55
54
 
56
- update_files
55
+ update_files
57
56
 
58
- # Run tests
59
- sh "bundle exec rake"
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
- window.Upmin.Attributes.DateTime = init;
157
+
158
+ window.Upmin.Attributes.DateTime = initDateTime;
159
+ window.Upmin.Attributes.Date = initDate;
134
160
  })();
@@ -13,4 +13,3 @@
13
13
  *= require_tree .
14
14
  *= require_self
15
15
  */
16
-
@@ -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-bottom: 0px;
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;
@@ -0,0 +1,11 @@
1
+ require_dependency "upmin/application_controller"
2
+
3
+ module Upmin
4
+ class DashboardController < ApplicationController
5
+
6
+ def index
7
+ @models = Upmin::Model.all
8
+ end
9
+
10
+ end
11
+ end
@@ -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].to_sym
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", type: "text/css"}
11
- %link{href: "//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css", rel: "stylesheet"}
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"} &times;
6
+ = notice
7
+ - if alert
8
+ .alert.alert-dismissable.alert-danger
9
+ %button.close{"data-dismiss" => "alert", type: "button"}
10
+ %span{"aria-hidden" => "true"} &times;
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
- %br
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
- - if attribute.editable? && f = form_builder
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?)