kea-rails 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +3 -0
  4. data/Rakefile +34 -0
  5. data/app/assets/javascripts/kea/bindings/activity.js +24 -0
  6. data/app/assets/javascripts/kea/bindings/child_vm.js +32 -0
  7. data/app/assets/javascripts/kea/bindings/komplete.js +172 -0
  8. data/app/assets/javascripts/kea/bindings/sherlock.js +47 -0
  9. data/app/assets/javascripts/kea/bindings/sherlock_provider_search.js +57 -0
  10. data/app/assets/javascripts/kea/bindings/submit_button.js +33 -0
  11. data/app/assets/javascripts/kea/bindings/validation_state.js +38 -0
  12. data/app/assets/javascripts/kea/bindings/wait_for_vm.js +44 -0
  13. data/app/assets/javascripts/kea/extenders/equals.js +85 -0
  14. data/app/assets/javascripts/kea/extenders/external_validator.js +65 -0
  15. data/app/assets/javascripts/kea/extenders/min_length.js +39 -0
  16. data/app/assets/javascripts/kea/extenders/numeric_range.js +64 -0
  17. data/app/assets/javascripts/kea/extenders/required.js +39 -0
  18. data/app/assets/javascripts/kea/extenders/valid_date.js +32 -0
  19. data/app/assets/javascripts/kea/extenders/valid_time.js +41 -0
  20. data/app/assets/javascripts/kea/extenders/validator_base.js +75 -0
  21. data/app/assets/javascripts/kea/helpers/kea.activity_button.js +97 -0
  22. data/app/assets/javascripts/kea/helpers/kea.notify.js +46 -0
  23. data/app/assets/javascripts/kea/initializers/base.js +11 -0
  24. data/app/assets/javascripts/kea/kea.js +14 -0
  25. data/app/assets/javascripts/kea/kea_dependencies.js +20 -0
  26. data/app/assets/javascripts/kea/kea_init.js +24 -0
  27. data/app/assets/javascripts/kea/models/base.js +215 -0
  28. data/app/assets/javascripts/kea/overlay/child_vm_overlay.js +49 -0
  29. data/app/assets/javascripts/kea/overlay/overlay_control.js +87 -0
  30. data/app/assets/javascripts/kea/overlay/overlay_template.js +58 -0
  31. data/app/assets/javascripts/kea/services/base.js +227 -0
  32. data/app/assets/javascripts/kea/sherlock/base_provider.js +201 -0
  33. data/app/assets/javascripts/kea/viewmodels/base.js +150 -0
  34. data/app/assets/javascripts/kea/viewmodels/sherlock.js +230 -0
  35. data/app/assets/stylesheets/kea/kea.css.sass +16 -0
  36. data/app/helpers/kea/application_helper.rb +42 -0
  37. data/lib/generators/kea/install/USAGE +9 -0
  38. data/lib/generators/kea/install/install_generator.rb +197 -0
  39. data/lib/generators/kea/install/templates/_komplete.sass +17 -0
  40. data/lib/generators/kea/install/templates/_sherlock.sass +105 -0
  41. data/lib/generators/kea/install/templates/application.html.erb +38 -0
  42. data/lib/generators/kea/install/templates/global.js +7 -0
  43. data/lib/generators/kea/install/templates/init.js +18 -0
  44. data/lib/generators/kea/install/templates/main.js +18 -0
  45. data/lib/generators/kea/model/USAGE +7 -0
  46. data/lib/generators/kea/model/model_generator.rb +68 -0
  47. data/lib/generators/kea/model/templates/model.js.erb +96 -0
  48. data/lib/generators/kea/service/USAGE +7 -0
  49. data/lib/generators/kea/service/service_generator.rb +21 -0
  50. data/lib/generators/kea/service/templates/model.js.erb +58 -0
  51. data/lib/generators/kea/viewmodel/USAGE +6 -0
  52. data/lib/generators/kea/viewmodel/templates/viewmodel.js.erb +73 -0
  53. data/lib/generators/kea/viewmodel/viewmodel_generator.rb +21 -0
  54. data/lib/kea-rails/engine.rb +5 -0
  55. data/lib/kea-rails/version.rb +3 -0
  56. data/lib/kea-rails.rb +4 -0
  57. data/lib/tasks/kea_tasks.rake +4 -0
  58. metadata +115 -0
@@ -0,0 +1,197 @@
1
+ class Kea::InstallGenerator < Rails::Generators::Base
2
+ source_root File.expand_path('../templates', __FILE__)
3
+ argument :namespace, type: :string, required: false, default: nil
4
+
5
+ def init_js
6
+ copy_file "init.js", namespaced_path("app/assets/javascripts/", "init.js")
7
+ end
8
+
9
+ def directories
10
+ empty_directory namespaced_path("app/assets/javascripts", "bindings")
11
+ create_file namespaced_path("app/assets/javascripts", "bindings/.keep")
12
+ empty_directory namespaced_path("app/assets/javascripts", "extenders")
13
+ create_file namespaced_path("app/assets/javascripts", "extenders/.keep")
14
+ empty_directory namespaced_path("app/assets/javascripts", "initializers")
15
+ empty_directory namespaced_path("app/assets/javascripts", "models")
16
+ create_file namespaced_path("app/assets/javascripts", "models/.keep")
17
+ empty_directory namespaced_path("app/assets/javascripts", "services")
18
+ create_file namespaced_path("app/assets/javascripts", "services/.keep")
19
+ empty_directory namespaced_path("app/assets/javascripts", "viewmodels")
20
+ empty_directory namespaced_path("app/assets/javascripts", "sherlock")
21
+ create_file namespaced_path("app/assets/javascripts", "sherlock/.keep")
22
+ end
23
+
24
+ def global_initializer
25
+ copy_file "global.js", namespaced_path("app/assets/javascripts/", "initializers/global.js")
26
+ end
27
+
28
+ def main_viewmodel
29
+ copy_file "main.js", namespaced_path("app/assets/javascripts/", "viewmodels/main.js")
30
+ end
31
+
32
+ def application_js
33
+ insert_into_file namespaced_path("app/assets/javascripts", "application.js"), :after => "jquery_ujs\n" do <<-'JS'
34
+ //= require kea/kea_dependencies
35
+
36
+ //= require ./init
37
+
38
+ //= require kea/kea
39
+ //= require_directory ./bindings
40
+ //= require_directory ./extenders
41
+ //= require_directory ./models
42
+ //= require_directory ./services
43
+ //= require ./viewmodels/main
44
+ //= require_directory ./viewmodels
45
+
46
+ //= require_directory ./sherlock
47
+
48
+ //= require_directory ./initializers
49
+ JS
50
+ end
51
+
52
+ append_to_file namespaced_path("app/assets/javascripts", "application.js") do <<-'JS'
53
+
54
+
55
+ $(document).ready(function() {
56
+ "use strict";
57
+
58
+ $.ajaxSetup({
59
+ timeout: 30000
60
+ });
61
+
62
+ window.app.page.MainVm = new window.app.viewmodels.Main();
63
+
64
+ var $body = $('body');
65
+
66
+ app.initializers.forEach(function(initializer) {
67
+
68
+ if (initializer.selectors.length === 0) {
69
+ initializer.callback();
70
+ return;
71
+ }
72
+
73
+ initializer.selectors.forEach(function(selector) {
74
+ if (selector.charAt(0) === '#') {
75
+ if ($body.attr('id') === selector.slice(1, selector.length)) {
76
+ initializer.callback();
77
+ }
78
+
79
+ } else if (selector.charAt(0) === '.') {
80
+ if ($body.hasClass(selector)) {
81
+ initializer.callback();
82
+ }
83
+ }
84
+ });
85
+
86
+ });
87
+
88
+ ko.applyBindings(app.page.MainVm);
89
+
90
+ app.page.MainVm.pageInitComplete(true);
91
+
92
+ if (app.errors.length > 0) {
93
+ app.errors.forEach(function(error) {
94
+ kea.notify(error.message, error.level);
95
+ });
96
+ }
97
+
98
+ });
99
+ JS
100
+ end
101
+ end
102
+
103
+ def application_css
104
+ copy_file "_komplete.sass", namespaced_path("app/assets/stylesheets", "_komplete.sass")
105
+ copy_file "_sherlock.sass", namespaced_path("app/assets/stylesheets", "_sherlock.sass")
106
+
107
+ insert_into_file namespaced_path("app/assets/stylesheets", "application.css.sass"), "*= require kea/kea", :before => "*= require_self"
108
+
109
+ append_to_file namespaced_path("app/assets/stylesheets", "application.css.sass") do <<-'CSS'
110
+ +keyframes(overlay)
111
+ 0%
112
+ +transform(translateY(-100%) scale(0.8))
113
+ box-shadow: 0px 40px 20px 5px $grey-20
114
+ 50%
115
+ +transform(translateY(0%) scale(0.8))
116
+ box-shadow: 0px 0px 20px 5px $grey-20
117
+ 90%
118
+ +transform(translateY(0%) scale(0.8))
119
+ box-shadow: 0px 0px 20px 5px $grey-20
120
+ 100%
121
+ +transform(translateY(0%) scale(1))
122
+ box-shadow: 0px 0px 0px 0px $grey-20
123
+
124
+ // Imported elements
125
+
126
+ @import sherlock
127
+ @import komplete
128
+
129
+ .attache-popover
130
+ display: none
131
+ position: absolute
132
+ z-index: 2
133
+ padding: 1em
134
+ opacity: 0
135
+ transition: opacity 0.3s ease
136
+ +triangles(grey)
137
+ &.inactive
138
+ display: none
139
+ &.activating, &.active
140
+ display: block
141
+ &.active
142
+ opacity: 1
143
+ &.formerror
144
+ z-index: 11
145
+ background: opacify(red, 0.3)
146
+ border-color: red
147
+ color: white
148
+ +triangles(opacify(red, 0.3))
149
+
150
+ .veil-overlay
151
+ position: fixed
152
+ top: 0
153
+ left: 0
154
+ display: none
155
+ z-index: 10
156
+ // +transition(all 1s $cubic-transition)
157
+ // +transform(scale(0.5))
158
+ &.fullscreen
159
+ width: 100%
160
+ height: 100vh
161
+ padding: 2rem
162
+ &.activating, &.active, &.deactivating
163
+ display: block
164
+ visibility: visible
165
+ &.active
166
+ +animation(overlay 1s $cubic-transition 0s 1 normal forwards)
167
+ &.deactivating
168
+ +transform(scale(0))
169
+ // +animation(overlay 1s $cubic-transition 0s 1 reverse forwards)
170
+ CSS
171
+ end
172
+ end
173
+
174
+ def layout_setup
175
+ copy_file "application.html.erb", "app/views/layouts/#{namespace ? namespace.underscore : "application"}.html.erb"
176
+ end
177
+
178
+ def helpers
179
+ inject_into_class "app/controllers/application_controller.rb", ApplicationController do
180
+ " helper Kea::ApplicationHelper\n"
181
+ end
182
+ end
183
+
184
+ private
185
+
186
+ def namespaced_path(path, suffix = nil)
187
+ app_namespace = case namespace
188
+ when 'none', nil
189
+ nil
190
+ else
191
+ namespace.underscore
192
+ end
193
+
194
+ File.join [path, app_namespace, suffix].compact
195
+ end
196
+
197
+ end
@@ -0,0 +1,17 @@
1
+ .komplete
2
+ position: relative
3
+ .komplete-dropdown
4
+ position: absolute
5
+ left: 0
6
+ z-index: 2
7
+ background-color: white
8
+ border: 1px solid black
9
+ ul
10
+ margin: 0
11
+ padding: 0
12
+ list-style-type: none
13
+ li
14
+ padding: 0.5rem
15
+ border-bottom: 1px solid grey
16
+ &.has-focus, &:hover
17
+ background-color: lightgrey
@@ -0,0 +1,105 @@
1
+ $primary-highlight-color: #932F6D !default
2
+ $primary-highlight-hover-color: #420039 !default
3
+ $grey-10: #e0e0e0 !default
4
+ $grey-20: #c2c2c2 !default
5
+ $grey-30: #a3a3a3 !default
6
+ $grey-40: #858585 !default
7
+ $base-font-size: 16px !default
8
+ $light: white !default
9
+
10
+ $standard-action-color: $primary-highlight-color !default
11
+
12
+ $text-on-light: black !default
13
+ $subtle-text-on-light: $grey-30 !default
14
+
15
+ $text-on-dark: $light !default
16
+ $subtle-text-on-dark: $grey-30 !default
17
+
18
+ $standard-border-color-on-light: $grey-20 !default
19
+ $standard-border-color-on-dark: $grey-10 !default
20
+
21
+ .sherlock-search-bar
22
+ +display(flex)
23
+ +flex-flow(row wrap)
24
+ min-height: 2rem
25
+ padding: 0.5rem
26
+ border: 1px solid $grey-30
27
+ .fragment, .provider-search-field
28
+ +flex(0 0 auto)
29
+ .fragment
30
+ +display(flex)
31
+ +flex-flow(row nowrap)
32
+ height: 40px
33
+ margin-right: 0.5rem
34
+ border: 2px solid $primary-highlight-color
35
+ border-radius: 10px
36
+ .fragment-name, .fragment-predicate, .fragment-search-value, .fragment-remove
37
+ +flex(0 0 auto)
38
+ .fragment-name
39
+ padding: 0 1rem
40
+ background-color: $primary-highlight-color
41
+ color: $text-on-dark
42
+ line-height: 40px
43
+ .fragment-search-value
44
+ padding: 0 0.5rem
45
+ font-size: $base-font-size
46
+ border: none
47
+ color: $primary-highlight-color
48
+ border-left: 2px solid $primary-highlight-color
49
+ background-color: none
50
+ &:focus
51
+ outline: none
52
+ .fragment-search-value-display
53
+ padding: 0 1rem
54
+ font-size: $base-font-size
55
+ border: none
56
+ color: $primary-highlight-color
57
+ border-left: 2px solid $primary-highlight-color
58
+ background-color: none
59
+ line-height: 40px
60
+ select.fragment-search-value
61
+ +flex(0 1 auto)
62
+ .fragment-remove
63
+ i
64
+ color: $primary-highlight-color
65
+ &:hover
66
+ color: $primary-highlight-hover-color
67
+ .provider-search-field
68
+ position: relative
69
+ & > input
70
+ line-height: 40px
71
+ font-size: $base-font-size
72
+ border: none
73
+ &:focus
74
+ outline: none
75
+ .provider-search-dropdown
76
+ display: none
77
+ position: absolute
78
+ z-index: 2
79
+ width: 200px
80
+ background-color: $light
81
+ border: 1px solid $grey-30
82
+ &.active
83
+ display: block
84
+ ul
85
+ margin: 0
86
+ list-style-type: none
87
+ li
88
+ padding: 0.5rem
89
+ cursor: pointer
90
+ &.has-focus, &:hover
91
+ background-color: $standard-action-color
92
+ color: $text-on-dark
93
+ article
94
+ position: relative
95
+ h2
96
+ padding: 0.5rem
97
+ margin-bottom: 0
98
+ padding-bottom: 0
99
+ border-top: 1px solid $standard-border-color-on-light
100
+ font-size: $base-font-size
101
+ color: $subtle-text-on-light
102
+ .activity-indicator
103
+ position: absolute
104
+ top: 0.5rem
105
+ right: 0.5rem
@@ -0,0 +1,38 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+
7
+ <title><%= content_for?(:title) ? yield(:title) : "" %></title>
8
+
9
+ <%= stylesheet_link_tag "backend/application" %>
10
+ <%= csrf_meta_tags %>
11
+ </head>
12
+
13
+ <body id="<%= body_id %>" class="<%= body_class %> <%= yield(:body_class) if yield(:body_class) %>">
14
+ <%= yield %>
15
+
16
+ <%= content_for :knockout_templates if content_for? :knockout_templates %>
17
+
18
+ <script type="application/javascript">
19
+ <% unless Rails.env.production? %>
20
+ window.DEBUG = true;
21
+ <% else %>
22
+ window.DEBUG = false;
23
+ <% end %>
24
+
25
+ window.app = window.app || {};
26
+ window.app.config = window.app.config || {};
27
+ window.app.errors = window.app.errors || [];
28
+
29
+ <% flash.each do |key, message| %>
30
+ window.app.errors.push({level: "<%= key %>", message: "<%= message.html_safe %>"});
31
+ <% end %>
32
+
33
+ <%= content_for(:json_cache) if content_for?(:json_cache) %>
34
+ </script>
35
+
36
+ <%= javascript_include_tag "application" %>
37
+ </body>
38
+ </html>
@@ -0,0 +1,7 @@
1
+ (function(app, ko, $) {
2
+ "use strict";
3
+
4
+ app.initialize_on(function() {
5
+
6
+ });
7
+ })(window.app, ko, $);
@@ -0,0 +1,18 @@
1
+ window.app = window.app || {};
2
+ window.app.models = window.app.models || {};
3
+ window.app.services = window.app.services || {};
4
+ window.app.viewmodels = window.app.viewmodels || {};
5
+
6
+ window.app.initializers = window.app.initializers || [];
7
+ window.app.page = window.app.page || {};
8
+ window.app.paths = window.app.paths || {};
9
+
10
+ // window.app.paths.users = '/users';
11
+
12
+ window.app.sherlock = {
13
+ providers: []
14
+ };
15
+
16
+ moment.lang('de');
17
+
18
+ Veil.globalOptions.backdropMarkup = null;
@@ -0,0 +1,18 @@
1
+ (function(app, kea, ko) {
2
+ "use strict";
3
+
4
+ var Main = function Main() {
5
+ kea.viewmodels.Parent.apply(this);
6
+
7
+ var that = this;
8
+
9
+ this._viewmodelName = function _viewmodelName() { return "Main"; };
10
+
11
+ // this.listener = new window.keypress.Listener();
12
+
13
+ this.pageInitComplete = ko.observable(false);
14
+ };
15
+
16
+ app.viewmodels.Main = Main;
17
+
18
+ })(window.app, window.kea, ko);
@@ -0,0 +1,7 @@
1
+ Description:
2
+ Generate a Knockout data model, optionally in a namespace such as 'backend'
3
+
4
+ Example:
5
+ rails generate kea:model User
6
+
7
+ rails generate kea:model User backend
@@ -0,0 +1,68 @@
1
+ class Kea::ModelGenerator < Rails::Generators::NamedBase
2
+ source_root File.expand_path('../templates', __FILE__)
3
+ argument :namespace, type: :string, required: false, default: nil, banner: "APPLICATION NAMESPACE|none"
4
+ argument :attributes, type: :array, required: false, banner: "model_attribute1 model_attribute1 …"
5
+
6
+ class_option :validatable, type: :boolean, :aliases => "-v", desc: "add model validations", default: false
7
+
8
+ def install_templates
9
+ @klass = name.camelize.safe_constantize
10
+
11
+ if @klass
12
+ @model_attributes = reflected_model_attributes
13
+ @model_associations = reflected_model_associations
14
+ @attribute_initializers = attribute_initializers
15
+
16
+ if options[:validatable]
17
+ @validators = @klass.validators.select {|v| v.is_a?(ActiveRecord::Validations::PresenceValidator) }
18
+ end
19
+ end
20
+
21
+ template "model.js.erb", namespaced_path("app/assets/javascripts", "models/#{name.underscore}.js")
22
+ end
23
+
24
+ private
25
+
26
+ def namespaced_path(path, suffix = nil)
27
+ app_namespace = case namespace
28
+ when 'none', nil
29
+ nil
30
+ else
31
+ namespace.underscore
32
+ end
33
+
34
+ File.join [path, app_namespace, suffix].compact
35
+ end
36
+
37
+ def reflected_model_attributes
38
+ attributes.any? ? attributes.map(&:name) : @klass.attribute_names - ["id", "created_at", "updated_at"]
39
+ end
40
+
41
+ def reflected_model_associations
42
+ @klass.reflect_on_all_associations.select { |assoc| assoc.macro == :has_one || assoc.macro == :has_many }
43
+ end
44
+
45
+ def attribute_initializers
46
+ max_string_length = 0
47
+ attribute_initializers = []
48
+ association_initializers = []
49
+
50
+ attribute_initializers = @model_attributes.collect do |attribute_name|
51
+ ["this.#{attribute_name}", "ko.observable();"]
52
+ end
53
+
54
+ association_initializers = @model_associations.collect do |assoc|
55
+ if assoc.macro == :has_one
56
+ ["this.#{assoc.name}", "ko.observable();"]
57
+ elsif assoc.macro == :has_many
58
+ ["this.#{assoc.name}", "ko.observableArray([]);"]
59
+ end
60
+ end
61
+
62
+ initializers = attribute_initializers + association_initializers
63
+
64
+ max_string_length = initializers.map { |a| a.first.length }.max
65
+
66
+ initializers.map { |i| [i.first.ljust(max_string_length + 1), " = ", i.last].join('') }
67
+ end
68
+ end
@@ -0,0 +1,96 @@
1
+ (function(app, kea, ko) {
2
+ "use strict";
3
+
4
+ var model_name = '<%= name.camelize %>',
5
+ ModelClass;
6
+
7
+ ModelClass = function <%= name.camelize %>(json) {
8
+ <% if options[:validatable] -%>
9
+ kea.models.Validatable.call(this);
10
+ <% end -%>
11
+
12
+ var that = this;
13
+
14
+ this.id = null;
15
+ this.resource_path = null;
16
+
17
+ <% if @klass -%>
18
+ <% @attribute_initializers.each do |attribute| -%>
19
+ <%= attribute %>
20
+ <% end -%>
21
+ <% end -%>
22
+ <% if options[:validatable] && @validators.any? -%>
23
+
24
+ this.validatableFields = function validatableFields() {
25
+ return <%= @validators.collect(&:attributes).flatten.map(&:to_s).to_s %>;
26
+ };
27
+
28
+ this.attachValidators = function attachValidators() {
29
+ <% @validators.each do |validator| -%>
30
+
31
+ that.<%= validator.attributes.first %>.extend({
32
+ required: {
33
+ message: "Pflichtfeld"
34
+ }
35
+ });
36
+ <% end -%>
37
+ };
38
+ <% end -%>
39
+
40
+ this.fromJSON = function fromJSON(json) {
41
+ this.id = json.id;
42
+ this.resource_path = json.resource_path;
43
+
44
+ <% if @klass -%>
45
+ <% @model_attributes.each do |attribute| -%>
46
+ this.<%= attribute %>( json.<%= attribute %> );
47
+ <% end -%>
48
+ <% @model_associations.each do |assoc| -%>
49
+ <% if assoc.macro == :has_one -%>
50
+
51
+ if (json.<%= assoc.name %>) {
52
+ this.<%= assoc.name %>( new app.models.<%= assoc.name.to_s.singularize.camelize %>(json.<%= assoc.name %>) );
53
+ }
54
+ <% elsif assoc.macro == :has_many -%>
55
+
56
+ if (json.<%= assoc.name %>) {
57
+ this.<%= assoc.name %>.removeAll();
58
+
59
+ json.<%= assoc.name %>.forEach(function(<%= assoc.name.to_s.singularize %>) {
60
+ that.<%= assoc.name %>.push( new app.models.<%= assoc.name.to_s.singularize.camelize %>(<%= assoc.name.to_s.singularize %>) );
61
+ });
62
+ }
63
+ <% end -%>
64
+ <% end -%>
65
+ <% end -%>
66
+ };
67
+
68
+ this.serialize = function serialize() {
69
+ return {
70
+ <% if @klass -%>
71
+ <% @model_attributes.each do |attribute| -%>
72
+ <%= attribute %>: this.<%= attribute %>(),
73
+ <% end -%>
74
+ <% @model_associations.each do |assoc| -%>
75
+ <% if assoc.macro == :has_one -%>
76
+ <%= assoc.name %>: this.<%= assoc.name %>().serialize(),
77
+ <% elsif assoc.macro == :has_many -%>
78
+ <%= assoc.name %>: this.<%= assoc.name %>().map(function(<%= assoc.name.to_s.singularize %>) { <%= assoc.name.to_s.singularize %>.serialize(); }),
79
+ <% end -%>
80
+ <% end -%>
81
+ <% end -%>
82
+ };
83
+ };
84
+
85
+ if (json) {
86
+ this.fromJSON(json);
87
+ }
88
+ };
89
+
90
+ kea.u.inherit(ModelClass, kea.models.Base);
91
+
92
+ ModelClass.prototype._modelName = function _modelName() { return model_name; };
93
+
94
+ app.models[model_name] = ModelClass;
95
+
96
+ })(window.app, window.kea, ko);
@@ -0,0 +1,7 @@
1
+ Description:
2
+ Generate a Knockout service, optionally in a namespace such as 'backend'
3
+
4
+ Example:
5
+ rails generate kea:service User
6
+
7
+ rails generate kea:service User backend
@@ -0,0 +1,21 @@
1
+ class Kea::ServiceGenerator < Rails::Generators::NamedBase
2
+ source_root File.expand_path('../templates', __FILE__)
3
+ argument :namespace, type: :string, required: false, default: nil
4
+
5
+ def install_templates
6
+ template "service.js.erb", namespaced_path("app/assets/javascripts", "services/#{name.underscore}.js")
7
+ end
8
+
9
+ private
10
+
11
+ def namespaced_path(path, suffix = nil)
12
+ app_namespace = case namespace
13
+ when 'none', nil
14
+ nil
15
+ else
16
+ namespace.underscore
17
+ end
18
+
19
+ File.join [path, app_namespace, suffix].compact
20
+ end
21
+ end
@@ -0,0 +1,58 @@
1
+ (function(app, kea, ko) {
2
+ "use strict";
3
+
4
+ var model_name = "<%= name.camelize %>",
5
+ resourcePath,
6
+ collectionPath,
7
+ getCollection,
8
+ get,
9
+ refresh,
10
+ create,
11
+ update,
12
+ destroy;
13
+
14
+ resourcePath = function resourcePath(id) {
15
+ return collectionPath() + '/' + id;
16
+ };
17
+
18
+ collectionPath = function collectionPath() {
19
+ return app.paths.<%= name.underscore %>;
20
+ };
21
+
22
+ getCollection = function getCollection(params) {
23
+ return kea.services.Base.get(model_name, collectionPath(), params);
24
+ };
25
+
26
+ get = function get(id, params, try_cache) {
27
+ return kea.services.Base.get(model_name, resourcePath(id), params, try_cache);
28
+ };
29
+
30
+ refresh = function refresh(model_instance, params) {
31
+ return kea.services.Base.refresh(model_name, model_instance, params, resourcePath(model_instance.id));
32
+ };
33
+
34
+ create = function create(model_instance) {
35
+ return kea.services.Base.create(model_name, model_instance, collectionPath())
36
+ .fail(kea.services.Base.failure422Handler);
37
+ };
38
+
39
+ update = function update(model_instance, params) {
40
+ return kea.services.Base.update(model_name, model_instance, params, resourcePath(model_instance.id))
41
+ .fail(kea.services.Base.failure422Handler);
42
+ };
43
+
44
+ destroy = function destroy(model_instance) {
45
+ return kea.services.Base.destroy(model_name, model_instance, resourcePath(model_instance.id))
46
+ .fail(kea.services.Base.failure422Handler);
47
+ };
48
+
49
+ app.services[model_name] = {
50
+ getCollection: getCollection,
51
+ get: get,
52
+ refresh: refresh,
53
+ create: create,
54
+ update: update,
55
+ destroy: destroy
56
+ };
57
+
58
+ })(window.app, window.kea, ko);
@@ -0,0 +1,6 @@
1
+ Description:
2
+ Generate a Knockout viewmodel, optionally in a namespace such as 'backend'
3
+
4
+ Example:
5
+ rails generate kea:viewmodel UserEditor
6
+ rails generate kea:viewmodel UserEditor backend