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,215 @@
1
+ (function(app, kea, ko) {
2
+ "use strict";
3
+
4
+ var Base,
5
+ Validatable;
6
+
7
+ Base = function Base() {
8
+
9
+ };
10
+
11
+ Base.prototype._modelName = function _modelName() {
12
+ console.error("Model does not implement _modelName");
13
+ };
14
+
15
+ Base.prototype.service = function service() {
16
+ if (DEBUG) {
17
+ console.assert(app.services[ this._modelName() ], this._modelName() + " service does not exist");
18
+ }
19
+
20
+ return app.services[ this._modelName() ];
21
+ };
22
+
23
+ Base.prototype.fromJSON = function fromJSON(json) {
24
+ console.error("object does not implement fromJSON: %O", this);
25
+ };
26
+
27
+ Base.prototype.serialize = function serialize() {
28
+ console.error("object does not implement serialize: %O", this);
29
+ };
30
+
31
+ Base.prototype.update = function update(params) {
32
+ var that = this,
33
+ deferred;
34
+
35
+ deferred = this.service()
36
+ .update(that, params)
37
+ .done(function(data) {
38
+ that.fromJSON(data);
39
+ });
40
+
41
+ return deferred;
42
+ };
43
+
44
+ Base.prototype.destroy = function destroy() {
45
+ return $.ajax({
46
+ type: 'DELETE',
47
+ url: this.resource_path,
48
+ dataType: 'JSON'
49
+
50
+ }).fail(function(jqXHR, textStatus) {
51
+ window.kea.notify(textStatus, 'error');
52
+
53
+ });
54
+ };
55
+
56
+ kea.models.Base = Base;
57
+
58
+ Validatable = function Validatable() {
59
+ var that = this;
60
+
61
+ this.isValidatable = ko.observable(false);
62
+
63
+ this.makeValidatable = function makeValidatable() {
64
+ if (DEBUG) {
65
+ console.assert(this.attachValidators, "object does not implement attachValidators");
66
+ }
67
+
68
+ this.attachValidators();
69
+ this.isValidatable(true);
70
+ };
71
+
72
+ this.validatableFields = function validatableFields() {
73
+ return [];
74
+ };
75
+
76
+ this.validatableAssociations = function validatableAssociations() {
77
+ return [];
78
+ };
79
+
80
+ this.validatableAssociationLists = function validatableAssociationLists() {
81
+ return [];
82
+ };
83
+
84
+ this.forEachValidatableField = function forEachValidatableField(callback) {
85
+ ko.utils.arrayForEach(this.validatableFields(), function(field) {
86
+ if (that[field].isValidatable) {
87
+ callback.call(that, that[field]);
88
+ }
89
+ });
90
+ };
91
+
92
+ this.forEachValidatableAssociation = function forEachValidatableAssociation(callback) {
93
+ var association_list;
94
+
95
+ ko.utils.arrayForEach(this.validatableAssociations(), function(association_name) {
96
+ var association = that[association_name]();
97
+
98
+ if (association.isValidatable && association.isValidatable()) {
99
+ callback.call(that, association);
100
+ }
101
+ });
102
+
103
+ ko.utils.arrayForEach(this.validatableAssociationLists(), function(association_list_name) {
104
+ association_list = that[association_list_name];
105
+
106
+ ko.utils.arrayForEach(association_list(), function(association) {
107
+ if (association.isValidatable && association.isValidatable()) {
108
+ callback.call(that, association);
109
+ }
110
+ });
111
+ });
112
+ };
113
+
114
+ this.hasErrors = ko.computed(function hasErrors() {
115
+ var result = false;
116
+
117
+ that.forEachValidatableField(function(observable) {
118
+ if (observable.hasError()) {
119
+ result = true;
120
+ }
121
+ }, this);
122
+
123
+ if (result) {
124
+ return true;
125
+ }
126
+
127
+ that.forEachValidatableAssociation(function(association) {
128
+ if (association.hasErrors()) {
129
+ result = true;
130
+ }
131
+ });
132
+
133
+ return result;
134
+ }, this, {deferEvaluation: true});
135
+
136
+ this.validationMessages = ko.computed(function validationMessages() {
137
+ var messages = [];
138
+
139
+ that.forEachValidatableField(function(observable) {
140
+ if (observable.hasError()) {
141
+ messages.push(observable.validationMessage());
142
+ }
143
+ }, this);
144
+
145
+ that.forEachValidatableAssociation(function(association) {
146
+ if (association.hasErrors()) {
147
+ messages = messages.concat(association.validationMessages());
148
+ }
149
+ });
150
+
151
+ return messages;
152
+ }, this, {deferEvaluation: true});
153
+
154
+ this.isFullyValidated = ko.computed(function isFullyValidated() {
155
+ var result = true;
156
+
157
+ that.forEachValidatableField(function(observable) {
158
+ if (observable.isUnvalidated() || observable.validationInProgress()) {
159
+ result = false;
160
+ }
161
+ });
162
+
163
+ if (!result) {
164
+ return false;
165
+ }
166
+
167
+ that.forEachValidatableAssociation(function(association) {
168
+ if (!association.isFullyValidated() || association.hasValidationsInProgress()) {
169
+ result = false;
170
+ }
171
+ });
172
+
173
+ return result;
174
+ }, this, {deferEvaluation: true});
175
+
176
+ this.hasValidationsInProgress = ko.computed(function hasValidationsInProgress() {
177
+ var result = false;
178
+
179
+ that.forEachValidatableField(function(observable) {
180
+ if (observable.validationInProgress()) {
181
+ result = true;
182
+ }
183
+ });
184
+
185
+ if (result) {
186
+ return true;
187
+ }
188
+
189
+ that.forEachValidatableAssociation(function(association) {
190
+ if (association.hasValidationsInProgress()) {
191
+ result = true;
192
+ }
193
+ });
194
+
195
+ return result;
196
+ }, this, {deferEvaluation: true});
197
+
198
+ this.isValid = ko.computed(function isValid() {
199
+ return !this.hasErrors() && this.isFullyValidated();
200
+ }, this, {deferEvaluation: true});
201
+
202
+ this.validate = function validate() {
203
+ that.forEachValidatableField(function(observable) {
204
+ observable.validate();
205
+ });
206
+
207
+ that.forEachValidatableAssociation(function(association) {
208
+ association.validate();
209
+ });
210
+ };
211
+ };
212
+
213
+ kea.models.Validatable = Validatable;
214
+
215
+ })(window.app, window.kea, ko);
@@ -0,0 +1,49 @@
1
+ (function(ko, $, Veil, Overlay, app) {
2
+ "use strict";
3
+
4
+ ko.bindingHandlers.childVmOverlay = {
5
+ init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
6
+ var $element = $(element),
7
+ options = ko.unwrap(valueAccessor()),
8
+ overlayName = ko.unwrap(options.name),
9
+ vmName = ko.unwrap(options.vm),
10
+ parentVm = options.parentVm || bindingContext.$parent,
11
+ setup = options.setup,
12
+ overlayOptions = options.overlayOptions || {},
13
+ css = options.css;
14
+
15
+ overlayOptions.overlayClass = [overlayOptions.overlayClass, overlayName, css].join(' ');
16
+
17
+ $element.on('click', function() {
18
+ var childVm = parentVm.getVm(vmName),
19
+ overlay;
20
+
21
+ if (childVm.setup) {
22
+ childVm.setup(setup);
23
+ }
24
+
25
+ overlay = Overlay.control.createOverlay(overlayName, bindingContext, childVm, overlayOptions);
26
+
27
+ if (childVm.keyboardHandlerConfigs) {
28
+ childVm.keyboardHandlerConfigs.forEach(function(config) {
29
+ childVm.keyboardHandlers.push( app.page.MainVm.listener.register_combo(config) );
30
+ });
31
+
32
+ overlay.on('beforeClose', function() {
33
+ app.page.MainVm.listener.unregister_many(childVm.keyboardHandlers);
34
+ childVm.keyboardHandlers.length = 0;
35
+ });
36
+ }
37
+
38
+ if (childVm.exit) {
39
+ childVm.exit.subscribe(function() {
40
+ overlay.hide();
41
+ });
42
+ }
43
+
44
+ overlay.show();
45
+ });
46
+ }
47
+ };
48
+
49
+ })(ko, $, window.Veil, window.Overlay, window.app);
@@ -0,0 +1,87 @@
1
+ (function(app, ko) {
2
+ "use strict";
3
+
4
+ var OverlayControl,
5
+ Overlay;
6
+
7
+ OverlayControl = function OverlayControl() {
8
+ var that = this;
9
+
10
+ this.providers = {};
11
+ this.existingOverlays = {};
12
+
13
+ this.registerProvider = function registerProvider(name, createCallback) {
14
+ that.providers[name] = createCallback;
15
+ };
16
+
17
+ this.createOverlay = function createOverlay(name, ctx, ctxExtension, overlayOptions) {
18
+ var overlay;
19
+
20
+ if (DEBUG) { console.assert(that.providers[name], "%s is not an available overlay provider", name); }
21
+
22
+ if (that.existingOverlays[name]) {
23
+ overlay = that.existingOverlays[name];
24
+
25
+ overlay.update(ctx, ctxExtension);
26
+
27
+ } else {
28
+ overlay = that.providers[name](ctx, ctxExtension, overlayOptions);
29
+
30
+ that.existingOverlays[name] = overlay;
31
+ }
32
+
33
+ return overlay;
34
+ };
35
+ };
36
+
37
+ Overlay = function Overlay(name, veil) {
38
+ var that = this;
39
+
40
+ this.name = name;
41
+ this.veil = veil;
42
+
43
+ this.updateCallback = function noop() {};
44
+ this.destroyCallback = function noop() {};
45
+
46
+ this.callbacks = {
47
+ 'beforeShow' : [],
48
+ 'beforeClose': []
49
+ };
50
+
51
+ this.runCallbacks = function runCallbacks(name) {
52
+ that.callbacks[name].forEach(function(callback) {
53
+ callback.apply(that);
54
+ });
55
+ };
56
+
57
+ this.on = function on(callbackName, callback) {
58
+ that.callbacks[callbackName].push(callback);
59
+ };
60
+
61
+ this.update = function update() {
62
+ that.updateCallback.apply(that, arguments);
63
+ };
64
+
65
+ this.destroy = function destroy() {
66
+ that.runCallbacks('beforeClose');
67
+ that.destroyCallback.apply(that, arguments);
68
+ };
69
+
70
+ this.show = function show() {
71
+ that.runCallbacks('beforeShow');
72
+ that.veil.show();
73
+ };
74
+
75
+ this.hide = function hide() {
76
+ that.runCallbacks('beforeClose');
77
+ that.veil.hide();
78
+ };
79
+
80
+ };
81
+
82
+ window.Overlay = {
83
+ control: new OverlayControl(),
84
+ Overlay: Overlay
85
+ };
86
+
87
+ })(window.app, ko);
@@ -0,0 +1,58 @@
1
+ (function(ko, $, Veil, Overlay) {
2
+ "use strict";
3
+
4
+ ko.bindingHandlers.overlayTemplate = {
5
+ init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
6
+ var $container = $(element),
7
+ name = ko.unwrap(valueAccessor()),
8
+ newCtx,
9
+ createCallback;
10
+
11
+ // returns either current context extended, or an
12
+ // extended child context
13
+ newCtx = function newCtx(overlay, ctx, ctxExtension) {
14
+ if (ctxExtension) {
15
+ return ctx.createChildContext(
16
+ ctxExtension,
17
+ null, // optional alias for $data
18
+ function(context) {
19
+ ko.utils.extend(context, { overlay: overlay} );
20
+ });
21
+ } else {
22
+ return ctx.extend({ overlay: overlay});
23
+ }
24
+ };
25
+
26
+ createCallback = function createCallback(ctx, ctxExtension, veilOptions) {
27
+ var veil = new Veil(veilOptions),
28
+ overlay = new Overlay.Overlay(name, veil),
29
+ childCtx = newCtx(overlay, ctx, ctxExtension);
30
+
31
+ ko.bindingHandlers.template.init(veil.overlay().get(0), function() { return name; }, allBindingsAccessor, childCtx.$data, childCtx);
32
+ ko.bindingHandlers.template.update(veil.overlay().get(0), function() { return name; }, allBindingsAccessor, childCtx.$data, childCtx);
33
+
34
+ overlay.updateCallback = function updateCallback(ctx, ctxExtension) {
35
+ var updatedCtx = newCtx(this, ctx, ctxExtension);
36
+
37
+ ko.bindingHandlers.template.update(veil.overlay().get(0), function() { return name; }, allBindingsAccessor, updatedCtx.$data, updatedCtx);
38
+ };
39
+
40
+ overlay.destroyCallback = function destroyCallback() {
41
+ ko.virtualElements.emptyNode( veil.overlay().get(0) );
42
+ veil.destroy();
43
+ };
44
+
45
+ return overlay;
46
+ };
47
+
48
+ Overlay.control.registerProvider(name, createCallback);
49
+
50
+ ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
51
+ // listener.destroy();
52
+ });
53
+
54
+ return {controlsDescendantBindings: true};
55
+ }
56
+ };
57
+
58
+ })(ko, $, window.Veil, window.Overlay);
@@ -0,0 +1,227 @@
1
+ (function(app, kea, ko, URI) {
2
+ "use strict";
3
+
4
+ var _regex_uppercase = new RegExp('([A-Z])', 'g'),
5
+ _regex_underbar_prefix = new RegExp('^_'),
6
+ _lookupCache,
7
+ _request,
8
+ _defaultFailureHandler,
9
+ _modelnameToParameter,
10
+ _resourcePathForAction,
11
+ failure422Handler,
12
+ failure423Handler,
13
+ getCollection,
14
+ get,
15
+ refresh,
16
+ create,
17
+ update,
18
+ destroy;
19
+
20
+ _lookupCache = function _lookupCache(path) {
21
+ var cachedResult = app.cache[path];
22
+
23
+ if (DEBUG) { console.debug("looking up cache for %s: %o", path, cachedResult); }
24
+
25
+ return typeof cachedResult !== 'undefined' ? $.when(cachedResult) : undefined;
26
+ };
27
+
28
+ _request = function _request(type, path, params) {
29
+ return $.ajax({
30
+ type: type,
31
+ url: path,
32
+ data: params,
33
+ dataType: 'JSON'
34
+ });
35
+ };
36
+
37
+ _defaultFailureHandler = function _defaultFailureHandler(jqXHR, textStatus) {
38
+ if (DEBUG) {
39
+ console.error("%s %s failed: %s", this.type, this.url, textStatus, jqXHR);
40
+ }
41
+
42
+ if (jqXHR.status === 0 && jqXHR.statusText === 'timeout') {
43
+ kea.notify("Server antwortet nicht <p><small>Der Server hat nicht rechtzeitig geantwortet. Bitte versuchen Sie es erneut!</small></p>", 'error');
44
+
45
+ } else if (jqXHR.status === 500 || jqXHR.status === 400 || jqXHR.status === 404) {
46
+ kea.notify("Entschuldigung! Der Server hat Schluckauf. <p><small><pre>" + jqXHR.responseText + "</pre></small></p>", 'error');
47
+
48
+ } else if (jqXHR.status === 403) {
49
+ kea.notify("Das geht nun wirklich nicht! <p><small>Diese Aktion ist nicht erlaubt</small></p>", 'error');
50
+
51
+ }
52
+
53
+ };
54
+
55
+ failure422Handler = function failure422Handler(jqXHR, textStatus) {
56
+ if (jqXHR.status === 422) {
57
+ kea.notify(jqXHR.responseText, 'error');
58
+ }
59
+ };
60
+
61
+ failure423Handler = function failure423Handler(jqXHR, textStatus) {
62
+ if (jqXHR.status === 423) {
63
+ kea.notify(jqXHR.responseText, 'error');
64
+ }
65
+ };
66
+
67
+ // taken from https://code.google.com/p/inflection-js/source/browse/trunk/inflection.js
68
+ _modelnameToParameter = function _modelnameToParameter(name) {
69
+ name = name.replace(_regex_uppercase, '_$1');
70
+ name = name.replace(_regex_underbar_prefix, '');
71
+
72
+ return name.toLowerCase();
73
+ };
74
+
75
+ _resourcePathForAction = function _resourcePathForAction(action, modelObject) {
76
+ var pathMethod = action + 'Path';
77
+
78
+ if (typeof modelObject[pathMethod] === 'function') {
79
+ return modelObject[action + 'Path']();
80
+
81
+ } else if (modelObject.service() && typeof modelObject.service()[pathMethod] === 'function') {
82
+ return modelObject.service()[pathMethod]();
83
+
84
+ } else {
85
+ return modelObject.resource_path;
86
+ }
87
+ };
88
+
89
+ get = function get(modelName, path, params, cache_key) {
90
+ var responseProcessor,
91
+ deferred,
92
+ cachedResult;
93
+
94
+ params = params || {};
95
+
96
+ if (cache_key === true) {
97
+ cache_key = new URI(path).query(params).toString();
98
+ }
99
+
100
+ responseProcessor = function responseProcessor(data) {
101
+ if (DEBUG) { console.debug("received resource %s: %o", modelName, data); }
102
+
103
+ if ( $.isArray(data) ) {
104
+ return ko.utils.arrayMap(data, function(json) {
105
+ return new app.models[modelName](json);
106
+ });
107
+
108
+ } else {
109
+ return new app.models[modelName](data);
110
+ }
111
+ };
112
+
113
+ if (cache_key) {
114
+ cachedResult = _lookupCache(cache_key);
115
+ }
116
+
117
+ return (cachedResult || _request('GET', path, params))
118
+ .then(responseProcessor)
119
+ .fail(_defaultFailureHandler);
120
+ };
121
+
122
+ refresh = function refresh(modelName, modelObject, params, path) {
123
+ var responseProcessor,
124
+ deferred;
125
+
126
+ params = params || {};
127
+
128
+ responseProcessor = function responseProcessor(data) {
129
+ if (DEBUG) { console.debug("received resource %s for refresh: %o", modelName, data); }
130
+
131
+ if ( $.isArray(data) ) {
132
+ if (DEBUG) { console.error("received multiple resources when trying to refresh %s : %o", modelName, data); }
133
+
134
+ } else {
135
+
136
+ if (typeof modelObject.refreshFromJSON === 'function') {
137
+ modelObject.refresh(data);
138
+
139
+ } else {
140
+ modelObject.fromJSON(data);
141
+ }
142
+
143
+ return modelObject;
144
+ }
145
+ };
146
+
147
+ return _request('GET', path, params)
148
+ .then(responseProcessor)
149
+ .fail(_defaultFailureHandler);
150
+ };
151
+
152
+ create = function create(modelName, modelObject, path) {
153
+ var params = {};
154
+
155
+ if (!path) {
156
+ path = _resourcePathForAction('create', modelObject);
157
+ }
158
+
159
+ params[ _modelnameToParameter(modelName) ] = modelObject.serialize();
160
+
161
+ return $.ajax({
162
+ type: 'POST',
163
+ url: path,
164
+ data: params,
165
+ dataType: 'JSON'
166
+
167
+ }).then(function(data) {
168
+ if (DEBUG) { console.debug("POST %s: %o", path, data); }
169
+ return new app.models[modelName](data);
170
+
171
+ }).fail(_defaultFailureHandler);
172
+ };
173
+
174
+ update = function update(modelName, modelObject, attributeHash, path) {
175
+ var params = {};
176
+
177
+ if (!path) {
178
+ path = _resourcePathForAction('update', modelObject);
179
+ }
180
+
181
+ if (attributeHash) {
182
+ params[ _modelnameToParameter(modelName) ] = attributeHash;
183
+ } else {
184
+ params[ _modelnameToParameter(modelName) ] = modelObject.serialize();
185
+ }
186
+
187
+ return $.ajax({
188
+ type: 'PUT',
189
+ url: path,
190
+ data: params,
191
+ dataType: 'JSON'
192
+
193
+ }).then(function(data) {
194
+ if (DEBUG) { console.debug("PUT %s: %o", path, data); }
195
+ return data;
196
+
197
+ }).fail(_defaultFailureHandler);
198
+ };
199
+
200
+ destroy = function destroy(modelName, modelObject, path) {
201
+
202
+ if (!path) {
203
+ path = _resourcePathForAction('destroy', modelObject);
204
+ }
205
+
206
+ return $.ajax({
207
+ type: 'DELETE',
208
+ url: path,
209
+ dataType: 'JSON'
210
+
211
+ }).fail(_defaultFailureHandler);
212
+ };
213
+
214
+ kea.services.Base = {
215
+ getCollection: getCollection,
216
+ get: get,
217
+ refresh: refresh,
218
+ create: create,
219
+ update: update,
220
+ destroy: destroy,
221
+ failure422Handler: failure422Handler,
222
+ failure423Handler: failure423Handler,
223
+ _request: _request,
224
+ _defaultFailureHandler: _defaultFailureHandler
225
+ };
226
+
227
+ })(window.app, window.kea, ko, URI);