kea-rails 1.0.0

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 (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