upmin-admin 0.0.35

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +34 -0
  3. data/app/assets/images/upmin/logo_large.png +0 -0
  4. data/app/assets/images/upmin/logo_small.png +0 -0
  5. data/app/assets/javascripts/upmin/application.js +40 -0
  6. data/app/assets/javascripts/upmin/jquery-clockpicker.js +729 -0
  7. data/app/assets/javascripts/upmin/models.js +23 -0
  8. data/app/assets/javascripts/upmin/moment.js +2856 -0
  9. data/app/assets/javascripts/upmin/pikaday.js +997 -0
  10. data/app/assets/stylesheets/upmin/application.css +16 -0
  11. data/app/assets/stylesheets/upmin/attributes.css.scss +57 -0
  12. data/app/assets/stylesheets/upmin/base.css.scss +53 -0
  13. data/app/assets/stylesheets/upmin/button_mixins.scss +37 -0
  14. data/app/assets/stylesheets/upmin/colors.scss +20 -0
  15. data/app/assets/stylesheets/upmin/instances.css.scss +77 -0
  16. data/app/assets/stylesheets/upmin/jquery-clockpicker.css +370 -0
  17. data/app/assets/stylesheets/upmin/models.css.scss +207 -0
  18. data/app/assets/stylesheets/upmin/pikaday.css +196 -0
  19. data/app/controllers/upmin/application_controller.rb +4 -0
  20. data/app/controllers/upmin/models_controller.rb +90 -0
  21. data/app/helpers/upmin/application_helper.rb +28 -0
  22. data/app/helpers/upmin/instances_helper.rb +13 -0
  23. data/app/helpers/upmin/models_helper.rb +4 -0
  24. data/app/views/layouts/upmin/_navbar.html.haml +15 -0
  25. data/app/views/layouts/upmin/application.html.haml +27 -0
  26. data/app/views/upmin/models/dashboard.html.haml +9 -0
  27. data/app/views/upmin/models/search.html.haml +9 -0
  28. data/app/views/upmin/models/show.html.haml +21 -0
  29. data/app/views/upmin/partials/actions/_action.html.haml +13 -0
  30. data/app/views/upmin/partials/associations/_associations.html.haml +14 -0
  31. data/app/views/upmin/partials/attributes/_datetime.html.haml +95 -0
  32. data/app/views/upmin/partials/attributes/_integer.html.haml +7 -0
  33. data/app/views/upmin/partials/attributes/_progress_bar.html.haml +11 -0
  34. data/app/views/upmin/partials/attributes/_string.html.haml +7 -0
  35. data/app/views/upmin/partials/attributes/_unknown.html.haml +3 -0
  36. data/app/views/upmin/partials/models/_model.html.haml +67 -0
  37. data/app/views/upmin/partials/search_boxes/_ransack_search_box.html.haml +37 -0
  38. data/app/views/upmin/partials/search_results/_result.html.haml +8 -0
  39. data/app/views/upmin/partials/search_results/_results.html.haml +2 -0
  40. data/config/routes.rb +20 -0
  41. data/lib/tasks/accordive_rails_tasks.rake +4 -0
  42. data/lib/tasks/upmin_tasks.rake +4 -0
  43. data/lib/upmin.rb +18 -0
  44. data/lib/upmin/engine.rb +7 -0
  45. data/lib/upmin/klass.rb +165 -0
  46. data/lib/upmin/model.rb +133 -0
  47. data/lib/upmin/railtie.rb +19 -0
  48. data/lib/upmin/railties/active_record.rb +62 -0
  49. data/lib/upmin/railties/render.rb +120 -0
  50. data/lib/upmin/railties/render_helpers.rb +144 -0
  51. data/lib/upmin/version.rb +3 -0
  52. data/test/controllers/upmin/model_controller_test.rb +11 -0
  53. data/test/dummy/README.rdoc +28 -0
  54. data/test/dummy/Rakefile +6 -0
  55. data/test/dummy/app/assets/javascripts/application.js +13 -0
  56. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  57. data/test/dummy/app/controllers/application_controller.rb +5 -0
  58. data/test/dummy/app/helpers/application_helper.rb +2 -0
  59. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  60. data/test/dummy/bin/bundle +3 -0
  61. data/test/dummy/bin/rails +4 -0
  62. data/test/dummy/bin/rake +4 -0
  63. data/test/dummy/config.ru +4 -0
  64. data/test/dummy/config/application.rb +23 -0
  65. data/test/dummy/config/boot.rb +5 -0
  66. data/test/dummy/config/database.yml +25 -0
  67. data/test/dummy/config/environment.rb +5 -0
  68. data/test/dummy/config/environments/development.rb +37 -0
  69. data/test/dummy/config/environments/production.rb +83 -0
  70. data/test/dummy/config/environments/test.rb +39 -0
  71. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  72. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  73. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  74. data/test/dummy/config/initializers/inflections.rb +16 -0
  75. data/test/dummy/config/initializers/mime_types.rb +4 -0
  76. data/test/dummy/config/initializers/session_store.rb +3 -0
  77. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  78. data/test/dummy/config/locales/en.yml +23 -0
  79. data/test/dummy/config/routes.rb +4 -0
  80. data/test/dummy/config/secrets.yml +22 -0
  81. data/test/dummy/public/404.html +67 -0
  82. data/test/dummy/public/422.html +67 -0
  83. data/test/dummy/public/500.html +66 -0
  84. data/test/dummy/public/favicon.ico +0 -0
  85. data/test/helpers/upmin/model_helper_test.rb +6 -0
  86. data/test/integration/navigation_test.rb +10 -0
  87. data/test/test_helper.rb +15 -0
  88. data/test/upmin_test.rb +7 -0
  89. metadata +237 -0
@@ -0,0 +1,28 @@
1
+ module Upmin
2
+ module ApplicationHelper
3
+ def body_classes
4
+ ret = []
5
+
6
+ controller = "c-#{params[:controller].gsub(/_/, "-").gsub("upmin/", "")}"
7
+ ret << controller
8
+
9
+ action = "a-#{params[:action].gsub(/_/, "-")}"
10
+ ret << action
11
+
12
+ if params[:klass]
13
+ model = "m-#{params[:klass]}"
14
+ ret << model
15
+ end
16
+
17
+ return ret
18
+ end
19
+
20
+ def body_data
21
+ ret = {}
22
+ ret[:controller] = params[:controller].camelize.gsub("Upmin::", "")
23
+ ret[:action] = params[:action].camelize
24
+ return ret
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,13 @@
1
+ module Upmin
2
+ module InstancesHelper
3
+
4
+ def models_path
5
+ return "#{root_path}models/"
6
+ end
7
+
8
+ def instance_path(instance)
9
+ return "#{models_path}#{instance.class.name}/#{instance.id}"
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,4 @@
1
+ module Upmin
2
+ module ModelsHelper
3
+ end
4
+ end
@@ -0,0 +1,15 @@
1
+ .navbar.navbar-default.navbar-static-top
2
+ .container
3
+ .navbar-header
4
+ %a.navbar-brand{href: root_path}
5
+ Upmin
6
+ %button.navbar-toggle{"data-target" => "#navbar-main", "data-toggle" => "collapse", type: "button"}
7
+ %span.icon-bar
8
+ %span.icon-bar
9
+ %span.icon-bar
10
+ #navbar-main.navbar-collapse.collapse
11
+ %ul.nav.navbar-nav
12
+ - Upmin::Klass.all.each do |m|
13
+ %li
14
+ %a{href: upmin_search_path(klass: m.name)}
15
+ = m.name.pluralize
@@ -0,0 +1,27 @@
1
+ !!!
2
+ %html
3
+ %head
4
+ %title
5
+ Upmin Dashboard
6
+ = stylesheet_link_tag("upmin/application", media: "all")
7
+ = javascript_include_tag("upmin/application")
8
+ = csrf_meta_tags
9
+
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
+ %script{:src => "//cdn.jsdelivr.net/bootstrap/3.2.0/js/bootstrap.min.js"}
13
+
14
+ - if content_for?(:head)
15
+ = yield(:head)
16
+
17
+
18
+ %body{ class: body_classes, data: body_data.merge(root_path: root_path) }
19
+ .page-wrap
20
+ = render('layouts/upmin/navbar')
21
+ -# = render('layouts/flash')
22
+ = yield
23
+
24
+ -# = render('layouts/footer')
25
+
26
+ - if content_for?(:javascript)
27
+ = yield(:javascript)
@@ -0,0 +1,9 @@
1
+ .container
2
+ .row
3
+ .col-sm-12
4
+ %h1
5
+ Uh oh! The Dashboard isn't implemented yet.
6
+ %small
7
+ This is embarrassing. :(
8
+ %h3
9
+ ^ Click one of those links up top to use features that are working. ^
@@ -0,0 +1,9 @@
1
+ .container
2
+ .row
3
+ .col-md-8
4
+ -# TODO(jon): Add pagination w/ search results
5
+ = up_search_results(@q, @results)
6
+
7
+ .col-md-4
8
+ -# TODO(jon): Implement up_search_box
9
+ = up_search_box(@klass)
@@ -0,0 +1,21 @@
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 @instance.errors.any?
13
+ %ul
14
+ - @instance.errors.each do |field, error|
15
+ %li
16
+ %b
17
+ = field
18
+ = error
19
+ .row
20
+ .col-sm-12
21
+ = up_model(@model.instance)
@@ -0,0 +1,13 @@
1
+ .well
2
+ = form_tag(upmin_action_path(upmin_model.path_hash.merge(method: action_name))) do
3
+ - upmin_model.action_parameters(action_name).each do |param_type, param_name|
4
+
5
+ - next if param_type == :block # Skip blocks
6
+
7
+ .form-group
8
+ = label(action_name, param_name, param_name.to_s.capitalize.gsub("_", " "))
9
+ = text_field(action_name, param_name, class: "form-control")
10
+ - if param_type == :opt
11
+ %small
12
+ * Optional
13
+ = submit_tag("Submit", class: "btn btn-primary")
@@ -0,0 +1,14 @@
1
+ - if associations.any?
2
+ %p
3
+ - associations.each do |u|
4
+ - nested_upmin_model = Upmin::Model.new(u)
5
+ %a.active-tag-link{href: upmin_model_path(nested_upmin_model.path_hash)}
6
+ %span.label{class: nested_upmin_model.color}
7
+ = nested_upmin_model.title
8
+
9
+ - else
10
+ %p.well
11
+ None
12
+
13
+
14
+
@@ -0,0 +1,95 @@
1
+ - datetime ||= nil
2
+ - if editable && f = form_builder
3
+ = f.hidden_field(attr_name, value: datetime)
4
+ - # TODO(jon): Figure out a better way to do transforms. This works for now though.
5
+ = f.hidden_field("transforms[#{attr_name}]", value: "DateTime#parse")
6
+ .row
7
+ .col-xs-12.col-md-4
8
+ .input-group.pikadate
9
+ %input.form-control{type: :text, value: datetime, id: "#{form_id}-date"}
10
+ %span.input-group-addon
11
+ %span.glyphicon.glyphicon-calendar
12
+ .col-xs-12.col-md-4
13
+ .input-group.clockpicker{"data-align" => "top", "data-autoclose" => "true", "data-placement" => "right"}
14
+ %input.form-control{:type => "text", :value => datetime, id: "#{form_id}-time"}
15
+ %span.input-group-addon
16
+ %span.glyphicon.glyphicon-time
17
+
18
+
19
+
20
+ - content_for(:javascript) do
21
+ :javascript
22
+ (function() {
23
+ var datePicker,
24
+ hiddenInput = $('##{form_id}'),
25
+ date = new Date(hiddenInput.val());
26
+
27
+ // Date Specific Code
28
+ var handleDateSelect = function() {
29
+ var pickerDate = datePicker.getDate();
30
+ console.log("Setting the date from " + date + " to " + pickerDate);
31
+
32
+ date.setUTCFullYear(pickerDate.getUTCFullYear());
33
+ date.setUTCMonth(pickerDate.getUTCMonth());
34
+ date.setUTCDate(pickerDate.getUTCDate());
35
+
36
+ hiddenInput.val(date.toUTCString());
37
+ }
38
+
39
+ datePicker = new Pikaday({ field: $('##{form_id}-date')[0], onSelect: handleDateSelect });
40
+
41
+ // Time Specific Code
42
+ var timeInput = $('##{form_id}-time');
43
+
44
+ var parseTime = function(timeString) {
45
+ var ret = new Date();
46
+
47
+ var time = timeString.match(/(\d+)(?::(\d\d))?\s*(p?)/i);
48
+ if (!time) {
49
+ return NaN;
50
+ }
51
+ var hours = parseInt(time[1], 10);
52
+ if (hours == 12 && !time[3]) {
53
+ hours = 0;
54
+ } else {
55
+ hours += (hours < 12 && time[3]) ? 12 : 0;
56
+ }
57
+
58
+ ret.setHours(hours);
59
+ ret.setMinutes(parseInt(time[2], 10) || 0);
60
+ ret.setSeconds(0, 0);
61
+ return ret;
62
+ }
63
+
64
+ var handleTimeSelect = function() {
65
+ var time = parseTime(timeInput.val());
66
+
67
+ date.setUTCHours(time.getUTCHours());
68
+ date.setUTCMinutes(time.getUTCMinutes());
69
+
70
+ hiddenInput.val(date.toUTCString());
71
+ }
72
+
73
+ timeInput.clockpicker({
74
+ autoclose: true,
75
+ donetext: "Done",
76
+ twelvehour: true,
77
+ afterDone: handleTimeSelect,
78
+ default: date.getHours() + ":" + date.getMinutes()
79
+ });
80
+
81
+ timeInput.val(date.getHours() + ":" + date.getMinutes());
82
+
83
+
84
+ // Make sure we set times when the form is input in case the user typed in values.
85
+ timeInput.closest("form").submit(function(event) {
86
+ // TODO(jon): Add code to handle typed in dates.
87
+ handleTimeSelect();
88
+ });
89
+ })();
90
+
91
+
92
+ - else
93
+ %p.well
94
+ -# TODO(jon): Make this show an uneditable date and time field.
95
+ = datetime
@@ -0,0 +1,7 @@
1
+ - integer ||= nil
2
+ - if editable && f = form_builder
3
+ = f.number_field(attr_name, value: integer, class: "form-control")
4
+
5
+ - else
6
+ %p.well
7
+ = integer
@@ -0,0 +1,11 @@
1
+ - state ||= nil
2
+ - states ||= []
3
+ %ol.progbar{data: { "progbar-steps" => states.length }}
4
+ - index = states.find_index(state) || -1
5
+ - states.each_with_index do |cur_state, cur_index|
6
+ - if index >= cur_index
7
+ %li.progbar-done
8
+ = cur_state.to_s.humanize
9
+ - else
10
+ %li.progbar-todo
11
+ = cur_state.to_s.humanize
@@ -0,0 +1,7 @@
1
+ - string ||= nil
2
+ - if editable && f = form_builder
3
+ = f.text_field(attr_name, value: string, class: "form-control")
4
+
5
+ - else
6
+ %p.well
7
+ = string
@@ -0,0 +1,3 @@
1
+ - unknown ||= nil
2
+ %p.well
3
+ = unknown
@@ -0,0 +1,67 @@
1
+ -# The following are all available to you here:
2
+ -# unknown - This is the model passed into the up_model method.
3
+ -# This attribute is always present in any partial rendered
4
+ -# by Upmin, and will always match the name of the partial
5
+ -# *UNLESS* nil, true, or false are passed in.
6
+ -# upmin_model - This is an Upmin::Model instantiated with unknown
7
+ -# and is always present.
8
+ -#
9
+ -# In general, the upmin_model makes it significantly easier to
10
+ -# render a view, so I suggest using it. It is way simpler than
11
+ -# trying to find all associations for a model on your own.
12
+ -#
13
+ -# Just an FYI: upmin_model.instance == unknown
14
+
15
+ .upmin-model{class: upmin_model.color}
16
+ -# Display the model title as "Model # ID"
17
+ %h3
18
+ = upmin_model.title
19
+
20
+ %br
21
+ %br
22
+ %h3{style: "color: #333;"}
23
+ Attributes
24
+ %hr
25
+ -# Create a form to wrap the attributes in.
26
+ -# TODO(jon): Update the URL with a decent helper?
27
+ = form_for(upmin_model.instance, url: upmin_model_path(upmin_model.path_hash), html: { method: :put }) do |f|
28
+
29
+ -# Render each attribute
30
+ - upmin_model.klass.attributes.each do |attribute|
31
+ .form-group
32
+ -# = f.label(attribute.to_s) # Not using this because it drops _id and this isn't always desirable
33
+
34
+ %label{for: upmin_model.attribute_form_id(attribute)}
35
+ = upmin_model.attribute_label_name(attribute)
36
+ = up_attribute(upmin_model.instance, attribute, locals: { form_builder: f })
37
+
38
+ = f.submit("Save", class: "btn btn-primary")
39
+
40
+
41
+
42
+ - if upmin_model.klass.associations.any?
43
+ %br
44
+ %br
45
+ %br
46
+ %h3{style: "color: #333;"}
47
+ Associations
48
+ %hr
49
+ - upmin_model.klass.associations.each do |association|
50
+ %h5
51
+ = association.to_s.humanize
52
+ = up_association(upmin_model.instance, association, limit: 5)
53
+
54
+ - if upmin_model.klass.actions.any?
55
+ %br
56
+ %br
57
+ %br
58
+ %h3{style: "color: #333;"}
59
+ Actions
60
+ %hr
61
+ - upmin_model.klass.actions.each do |action|
62
+ %h4{style: "color: #333;"}
63
+ = action.to_s.capitalize.humanize
64
+ = up_action(upmin_model.instance, action)
65
+
66
+
67
+
@@ -0,0 +1,37 @@
1
+ %h4
2
+ Search
3
+ = klass.humanized_name
4
+
5
+ -# Upmin default search uses the ransack gem, see: https://github.com/activerecord-hackery/ransack
6
+ = form_tag(upmin_search_path(klass: klass.name), method: :get) do
7
+ - klass.attributes.each do |attr_name|
8
+ - type = klass.attribute_type(attr_name)
9
+
10
+ -# TODO(jon): Make sure these retain their data on a search
11
+ -# TODO(jon): Break these into partials possibly?
12
+ - if type == :string
13
+ .form-group
14
+ = label(:q, "#{attr_name}_cont", attr_name.to_s.capitalize.gsub("_", " "))
15
+ = text_field(:q, "#{attr_name}_cont", class: "form-control")
16
+
17
+ - if type == :integer
18
+ .form-group
19
+ = label(:q, "#{attr_name}_cont", attr_name.to_s.capitalize.gsub("_", " "))
20
+ .input-group
21
+ .input-group-addon From
22
+ = number_field(:q, "#{attr_name}_gteq", class: "form-control")
23
+ .input-group-addon to
24
+ = number_field(:q, "#{attr_name}_lteq", class: "form-control")
25
+
26
+ - if type == :datetime && Rails::VERSION::MAJOR == 4
27
+ -# TODO(jon): Add date fields to search boxes for Rails 3
28
+ .form-group
29
+ = label(:q, "#{attr_name}_cont", attr_name.to_s.capitalize.gsub("_", " "))
30
+ %br
31
+ From
32
+ = date_field(:q, "#{attr_name}_gteq", class: "form-control")
33
+ To
34
+ = date_field(:q, "#{attr_name}_lteq", class: "form-control")
35
+
36
+ = submit_tag("Search", class: "btn btn-primary btn-block")
37
+ = link_to("Clear All", upmin_search_path(klass: klass.name), class: "btn btn-default btn-block")
@@ -0,0 +1,8 @@
1
+ %a.search-result-link{href: upmin_model_path(upmin_model.path_hash)}
2
+ .upmin-model{class: upmin_model.color}
3
+ %dl.dl-horizontal
4
+ - @klass.attributes.each do |attribute|
5
+ %dt
6
+ = upmin_model.attribute_label_name(attribute)
7
+ %dd
8
+ = upmin_model.attribute(attribute)
@@ -0,0 +1,2 @@
1
+ - results.each do |result|
2
+ = up_search_result(result)
data/config/routes.rb ADDED
@@ -0,0 +1,20 @@
1
+ Upmin::Engine.routes.draw do
2
+ root to: "models#dashboard"
3
+
4
+ # TODO(jon): Add support for dashboards (or some other main page).
5
+ # TODO(jon): Move dashboards to an appropriate controller
6
+ get "/", as: :upmin_dashboard, controller: :models, action: :dashboard
7
+
8
+ scope :m do
9
+ scope "/:klass" do
10
+ match "/", as: :upmin_search, controller: :models, action: :search, via: [:get, :post]
11
+
12
+ scope "/:id" do
13
+ get "/", as: :upmin_model, controller: :models, action: :show
14
+ put "/", controller: :models, action: :update
15
+
16
+ post "/:method", as: :upmin_action, controller: :models, action: :action
17
+ end
18
+ end
19
+ end
20
+ end