upmin 0.0.34
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Rakefile +34 -0
- data/app/assets/images/upmin/logo_large.png +0 -0
- data/app/assets/images/upmin/logo_small.png +0 -0
- data/app/assets/javascripts/upmin/application.js +38 -0
- data/app/assets/javascripts/upmin/jquery-clockpicker.js +729 -0
- data/app/assets/javascripts/upmin/models.js +23 -0
- data/app/assets/javascripts/upmin/pikaday.js +997 -0
- data/app/assets/stylesheets/upmin/application.css +16 -0
- data/app/assets/stylesheets/upmin/base.css.scss +24 -0
- data/app/assets/stylesheets/upmin/button_mixins.scss +37 -0
- data/app/assets/stylesheets/upmin/colors.scss +20 -0
- data/app/assets/stylesheets/upmin/instances.css.scss +91 -0
- data/app/assets/stylesheets/upmin/jquery-clockpicker.css +370 -0
- data/app/assets/stylesheets/upmin/models.css.scss +207 -0
- data/app/assets/stylesheets/upmin/pikaday.css +196 -0
- data/app/controllers/upmin/application_controller.rb +4 -0
- data/app/controllers/upmin/models_controller.rb +94 -0
- data/app/helpers/upmin/application_helper.rb +17 -0
- data/app/helpers/upmin/instances_helper.rb +13 -0
- data/app/helpers/upmin/models_helper.rb +4 -0
- data/app/views/layouts/upmin/_navbar.html.haml +15 -0
- data/app/views/layouts/upmin/application.html.haml +24 -0
- data/app/views/upmin/models/_search_result.html.haml +25 -0
- data/app/views/upmin/models/dashboard.html.haml +9 -0
- data/app/views/upmin/models/search.html.haml +20 -0
- data/app/views/upmin/models/show.html.haml +21 -0
- data/app/views/upmin/search_boxes/_unknown.html.haml +31 -0
- data/app/views/upmin/search_fields/_string.html.haml +3 -0
- data/app/views/upmin/types/_datetime.html.haml +95 -0
- data/app/views/upmin/types/_integer.html.haml +6 -0
- data/app/views/upmin/types/_string.html.haml +7 -0
- data/app/views/upmin/types/_unknown.html.haml +2 -0
- data/app/views/upmin/types/_unknown_collection.html.haml +18 -0
- data/app/views/upmin/types/_unknown_model.html.haml +57 -0
- data/app/views/upmin/types/_unknown_model_badge.html.haml +3 -0
- data/app/views/upmin/types/_unknown_model_nested.html.haml +24 -0
- data/app/views/upmin/types/_unknown_model_search_result.html.haml +31 -0
- data/config/routes.rb +19 -0
- data/lib/tasks/accordive_rails_tasks.rake +4 -0
- data/lib/tasks/upmin_tasks.rake +4 -0
- data/lib/upmin.rb +44 -0
- data/lib/upmin/engine.rb +7 -0
- data/lib/upmin/graph/collection_node.rb +72 -0
- data/lib/upmin/graph/data_node.rb +69 -0
- data/lib/upmin/graph/model_node.rb +151 -0
- data/lib/upmin/graph/node.rb +98 -0
- data/lib/upmin/model.rb +131 -0
- data/lib/upmin/railtie.rb +19 -0
- data/lib/upmin/railties/active_record.rb +156 -0
- data/lib/upmin/railties/render.rb +56 -0
- data/lib/upmin/railties/render_helpers.rb +57 -0
- data/lib/upmin/version.rb +3 -0
- data/test/controllers/upmin/model_controller_test.rb +11 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +15 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +23 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +83 -0
- data/test/dummy/config/environments/test.rb +39 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +4 -0
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/helpers/upmin/model_helper_test.rb +6 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/test_helper.rb +15 -0
- data/test/upmin_test.rb +7 -0
- metadata +253 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
module Upmin
|
2
|
+
module ApplicationHelper
|
3
|
+
def body_classes
|
4
|
+
controller = "c-#{params[:controller].gsub(/_/, "-").gsub("upmin/", "")}"
|
5
|
+
action = "a-#{params[:action].gsub(/_/, "-")}"
|
6
|
+
return [controller, action]
|
7
|
+
end
|
8
|
+
|
9
|
+
def body_data
|
10
|
+
ret = {}
|
11
|
+
ret[:controller] = params[:controller].camelize.gsub("Upmin::", "")
|
12
|
+
ret[:action] = params[:action].camelize
|
13
|
+
return ret
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
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::Model.all.each do |m|
|
13
|
+
%li
|
14
|
+
%a{href: upmin_search_path(model_name: m.name)}
|
15
|
+
= m.name.pluralize
|
@@ -0,0 +1,24 @@
|
|
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
|
+
|
15
|
+
%body{ class: body_classes, data: body_data.merge(root_path: root_path) }
|
16
|
+
.page-wrap
|
17
|
+
= render('layouts/upmin/navbar')
|
18
|
+
-# = render('layouts/flash')
|
19
|
+
= yield
|
20
|
+
|
21
|
+
-# = render('layouts/footer')
|
22
|
+
|
23
|
+
- if content_for?(:javascript)
|
24
|
+
= yield(:javascript)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
- model_name ||= " "
|
2
|
+
- model_id ||= ""
|
3
|
+
- model_data ||= {}
|
4
|
+
- hidden = false unless hidden
|
5
|
+
|
6
|
+
%a.search-result-link{href: '#'}
|
7
|
+
.search-result.well{ class: hidden ? "hidden" : "", id: html_id }
|
8
|
+
.icon-outer
|
9
|
+
.icon-upper
|
10
|
+
.icon-letter
|
11
|
+
|
12
|
+
= model_name[0] || ""
|
13
|
+
.icon-name
|
14
|
+
= model_name
|
15
|
+
.icon-lower
|
16
|
+
ID:
|
17
|
+
%span.icon-id
|
18
|
+
= model_id
|
19
|
+
%dl.dl-horizontal{ id: "search-dl-1" }
|
20
|
+
- model_data.each do |k, v|
|
21
|
+
%dt
|
22
|
+
= k
|
23
|
+
%dd
|
24
|
+
= v.html_safe # for ems
|
25
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
.container
|
2
|
+
.row
|
3
|
+
.col-md-8
|
4
|
+
- @results.each do |r|
|
5
|
+
%a.search-result-link{href: upmin_model_path(model_name: params[:model_name], id: r.id)}
|
6
|
+
.upmin-model{class: r.upmin_color}
|
7
|
+
%dl.dl-horizontal
|
8
|
+
- r.upmin_attributes.each do |u_attr|
|
9
|
+
%dt
|
10
|
+
= u_attr.to_s.capitalize.gsub("_", " ")
|
11
|
+
%dd
|
12
|
+
= r.send(u_attr)
|
13
|
+
|
14
|
+
|
15
|
+
.col-md-4
|
16
|
+
.well
|
17
|
+
= upmin_render_search_box(@model, {})
|
18
|
+
|
19
|
+
|
20
|
+
|
@@ -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"} ×
|
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 @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
|
+
= upmin_render(@instance)
|
@@ -0,0 +1,31 @@
|
|
1
|
+
%h4
|
2
|
+
Search
|
3
|
+
= upmin_model.u_name
|
4
|
+
|
5
|
+
= form_tag(upmin_search_path(model_name: params[:model_name]), method: :get) do
|
6
|
+
- upmin_model.attributes.each do |u_attr, info|
|
7
|
+
|
8
|
+
- if info[:type] == :string
|
9
|
+
.form-group
|
10
|
+
= label(:q, "#{u_attr}_cont", u_attr.to_s.capitalize.gsub("_", " "))
|
11
|
+
= text_field(:q, "#{u_attr}_cont", class: "form-control")
|
12
|
+
|
13
|
+
- if info[:type] == :integer
|
14
|
+
.form-group
|
15
|
+
= label(:q, "#{u_attr}_cont", u_attr.to_s.capitalize.gsub("_", " "))
|
16
|
+
.input-group
|
17
|
+
.input-group-addon From
|
18
|
+
= number_field(:q, "#{u_attr}_gteq", class: "form-control")
|
19
|
+
.input-group-addon to
|
20
|
+
= number_field(:q, "#{u_attr}_lteq", class: "form-control")
|
21
|
+
- if info[:type] == :datetime
|
22
|
+
.form-group
|
23
|
+
= label(:q, "#{u_attr}_cont", u_attr.to_s.capitalize.gsub("_", " "))
|
24
|
+
%br
|
25
|
+
From
|
26
|
+
= date_field(:q, "#{u_attr}_gteq", class: "form-control")
|
27
|
+
To
|
28
|
+
= date_field(:q, "#{u_attr}_lteq", class: "form-control")
|
29
|
+
|
30
|
+
= submit_tag("Search", class: "btn btn-primary btn-block")
|
31
|
+
= link_to("Clear All", upmin_search_path(model_name: params[:model_name]), class: "btn btn-default btn-block")
|
@@ -0,0 +1,95 @@
|
|
1
|
+
- if node.editable? && f = options[:form_builder]
|
2
|
+
|
3
|
+
= f.hidden_field(node.method_name, value: datetime)
|
4
|
+
- # TODO(jon): Figure out a better way to do transforms. This works for now though.
|
5
|
+
= f.hidden_field("transforms[#{node.method_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: "#{node.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: "#{node.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
|
+
date = new Date($('##{node.form_id}').val()),
|
25
|
+
hiddenInput = $('##{node.form_id}');
|
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: $('##{node.form_id}-date')[0], onSelect: handleDateSelect });
|
40
|
+
|
41
|
+
// Time Specific Code
|
42
|
+
var timeInput = $('##{node.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,18 @@
|
|
1
|
+
|
2
|
+
-if node.nodes.any?
|
3
|
+
%p
|
4
|
+
- node.nodes.each do |c_node|
|
5
|
+
= upmin_render(c_node, options)
|
6
|
+
|
7
|
+
%a.btn.btn-xs.btn-default{class: "btn-#{node.nodes.first.color}", href: '#'}
|
8
|
+
%i.fa.fa-plus{style: "padding-right: 3px;"}
|
9
|
+
= node.type.to_s.gsub(/_collection/, "").humanize
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
- if node.nodes.empty?
|
14
|
+
%p.well
|
15
|
+
None
|
16
|
+
|
17
|
+
|
18
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
.upmin-model{class: node.color}
|
2
|
+
-# Display the model title as "Model # ID"
|
3
|
+
%h3
|
4
|
+
= node.title
|
5
|
+
|
6
|
+
-# For each model attribute, render the DataNode inside of a form.
|
7
|
+
= form_for(unknown_model, as: node.name.underscore, url: upmin_model_path(node.path_hash), html: { method: :put }) do |f|
|
8
|
+
- node.attributes.each do |key, data_node|
|
9
|
+
.form-group
|
10
|
+
-# TODO(jon): Make the key already pretty if I can easily.
|
11
|
+
= f.label(key.to_s.capitalize.gsub("_", " "))
|
12
|
+
= upmin_render(data_node, form_builder: f)
|
13
|
+
= f.submit("Save", class: "btn btn-primary")
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
-# Render each child node
|
19
|
+
%br
|
20
|
+
%br
|
21
|
+
%h3{style: "color: #333;"}
|
22
|
+
Relationships
|
23
|
+
%hr
|
24
|
+
|
25
|
+
- node.children.each do |key, node|
|
26
|
+
%h5
|
27
|
+
= key.to_s.humanize
|
28
|
+
- if node.is_a?(Upmin::Graph::CollectionNode)
|
29
|
+
= upmin_render(node, options)
|
30
|
+
- else
|
31
|
+
%p
|
32
|
+
= upmin_render(node, options)
|
33
|
+
|
34
|
+
%br
|
35
|
+
%br
|
36
|
+
%h3{style: "color: #333;"}
|
37
|
+
Actions
|
38
|
+
%hr
|
39
|
+
- unknown_model.class.upmin_methods.each do |method|
|
40
|
+
%h4{style: "color: #333;"}
|
41
|
+
= method.to_s.capitalize.humanize
|
42
|
+
.well
|
43
|
+
= form_tag(upmin_action_path(model_name: params[:model_name], id: params[:id], method: method)) do
|
44
|
+
- unknown_model.method(method).parameters.each do |a_type, a_name|
|
45
|
+
- next if a_type == :block # Skip blocks
|
46
|
+
.form-group
|
47
|
+
= label(method, a_name, a_name.to_s.capitalize.gsub("_", " "))
|
48
|
+
= text_field(method, a_name, class: "form-control")
|
49
|
+
- if a_type == :opt
|
50
|
+
%small
|
51
|
+
* Optional
|
52
|
+
= submit_tag("Submit \"#{method.to_s.humanize}\"", class: "btn btn-primary")
|
53
|
+
|
54
|
+
|
55
|
+
-# - if node.editable?
|
56
|
+
|
57
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
%a.active-tag-link{href: upmin_model_path(node.path_hash)}
|
2
|
+
%span.label{class: node.color}
|
3
|
+
= node.title
|
4
|
+
|
5
|
+
|
6
|
+
-# .upmin-model{class: node.color}
|
7
|
+
-# -# Display the model title as "Model # ID"
|
8
|
+
-# %h4
|
9
|
+
-# %a{href: upmin_model_path(node.path_hash)}
|
10
|
+
-# = node.title
|
11
|
+
|
12
|
+
-# -# For each model attribute, render the DataNode
|
13
|
+
-# - node.attributes.each do |key, data_node|
|
14
|
+
-# %h6
|
15
|
+
-# = key.to_s.humanize
|
16
|
+
|
17
|
+
-# = upmin_render(data_node, options)
|
18
|
+
|
19
|
+
-# -# Render each child node
|
20
|
+
-# - node.children.each do |key, node|
|
21
|
+
-# %h5
|
22
|
+
-# = key.to_s.humanize
|
23
|
+
-# = upmin_render(node, options)
|
24
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
- provide(:subtitle, node.name)
|
2
|
+
|
3
|
+
.upmin-model{class: node.color}
|
4
|
+
-# Display the model title as "Model # ID"
|
5
|
+
%h3
|
6
|
+
= node.title
|
7
|
+
-# = unknown_model.upmin_name(:singular)
|
8
|
+
-# \#
|
9
|
+
-# = unknown_model.id
|
10
|
+
|
11
|
+
-# For each model attribute, render the DataNode
|
12
|
+
- node.attributes.each do |key, data_node|
|
13
|
+
%h5
|
14
|
+
= key.to_s.capitalize.gsub("_", " ")
|
15
|
+
|
16
|
+
= upmin_render(data_node, options)
|
17
|
+
|
18
|
+
-# Render each child node
|
19
|
+
- node.children.each do |key, node|
|
20
|
+
%h5
|
21
|
+
= key.to_s.humanize
|
22
|
+
= upmin_render(node, options)
|
23
|
+
|
24
|
+
|
25
|
+
- if node.editable?
|
26
|
+
%br
|
27
|
+
%button.btn.btn-primary{type: :button}
|
28
|
+
Save
|
29
|
+
|
30
|
+
|
31
|
+
|