kea-rails 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +34 -0
- data/app/assets/javascripts/kea/bindings/activity.js +24 -0
- data/app/assets/javascripts/kea/bindings/child_vm.js +32 -0
- data/app/assets/javascripts/kea/bindings/komplete.js +172 -0
- data/app/assets/javascripts/kea/bindings/sherlock.js +47 -0
- data/app/assets/javascripts/kea/bindings/sherlock_provider_search.js +57 -0
- data/app/assets/javascripts/kea/bindings/submit_button.js +33 -0
- data/app/assets/javascripts/kea/bindings/validation_state.js +38 -0
- data/app/assets/javascripts/kea/bindings/wait_for_vm.js +44 -0
- data/app/assets/javascripts/kea/extenders/equals.js +85 -0
- data/app/assets/javascripts/kea/extenders/external_validator.js +65 -0
- data/app/assets/javascripts/kea/extenders/min_length.js +39 -0
- data/app/assets/javascripts/kea/extenders/numeric_range.js +64 -0
- data/app/assets/javascripts/kea/extenders/required.js +39 -0
- data/app/assets/javascripts/kea/extenders/valid_date.js +32 -0
- data/app/assets/javascripts/kea/extenders/valid_time.js +41 -0
- data/app/assets/javascripts/kea/extenders/validator_base.js +75 -0
- data/app/assets/javascripts/kea/helpers/kea.activity_button.js +97 -0
- data/app/assets/javascripts/kea/helpers/kea.notify.js +46 -0
- data/app/assets/javascripts/kea/initializers/base.js +11 -0
- data/app/assets/javascripts/kea/kea.js +14 -0
- data/app/assets/javascripts/kea/kea_dependencies.js +20 -0
- data/app/assets/javascripts/kea/kea_init.js +24 -0
- data/app/assets/javascripts/kea/models/base.js +215 -0
- data/app/assets/javascripts/kea/overlay/child_vm_overlay.js +49 -0
- data/app/assets/javascripts/kea/overlay/overlay_control.js +87 -0
- data/app/assets/javascripts/kea/overlay/overlay_template.js +58 -0
- data/app/assets/javascripts/kea/services/base.js +227 -0
- data/app/assets/javascripts/kea/sherlock/base_provider.js +201 -0
- data/app/assets/javascripts/kea/viewmodels/base.js +150 -0
- data/app/assets/javascripts/kea/viewmodels/sherlock.js +230 -0
- data/app/assets/stylesheets/kea/kea.css.sass +16 -0
- data/app/helpers/kea/application_helper.rb +42 -0
- data/lib/generators/kea/install/USAGE +9 -0
- data/lib/generators/kea/install/install_generator.rb +197 -0
- data/lib/generators/kea/install/templates/_komplete.sass +17 -0
- data/lib/generators/kea/install/templates/_sherlock.sass +105 -0
- data/lib/generators/kea/install/templates/application.html.erb +38 -0
- data/lib/generators/kea/install/templates/global.js +7 -0
- data/lib/generators/kea/install/templates/init.js +18 -0
- data/lib/generators/kea/install/templates/main.js +18 -0
- data/lib/generators/kea/model/USAGE +7 -0
- data/lib/generators/kea/model/model_generator.rb +68 -0
- data/lib/generators/kea/model/templates/model.js.erb +96 -0
- data/lib/generators/kea/service/USAGE +7 -0
- data/lib/generators/kea/service/service_generator.rb +21 -0
- data/lib/generators/kea/service/templates/model.js.erb +58 -0
- data/lib/generators/kea/viewmodel/USAGE +6 -0
- data/lib/generators/kea/viewmodel/templates/viewmodel.js.erb +73 -0
- data/lib/generators/kea/viewmodel/viewmodel_generator.rb +21 -0
- data/lib/kea-rails/engine.rb +5 -0
- data/lib/kea-rails/version.rb +3 -0
- data/lib/kea-rails.rb +4 -0
- data/lib/tasks/kea_tasks.rake +4 -0
- metadata +115 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
(function(ko, $) {
|
2
|
+
"use strict";
|
3
|
+
|
4
|
+
ko.extenders.minLength = function(target, options) {
|
5
|
+
ko.utils.validatorBase(target);
|
6
|
+
|
7
|
+
var defaults = {
|
8
|
+
message: "",
|
9
|
+
length: 0,
|
10
|
+
allowBlank: false
|
11
|
+
};
|
12
|
+
|
13
|
+
options = $.extend({}, defaults, options);
|
14
|
+
|
15
|
+
target.validate = function validate(newValue, newComparisonValue) {
|
16
|
+
var validatableValue = typeof newValue === 'undefined' ? target() : newValue;
|
17
|
+
|
18
|
+
if (options.allowBlank && (!validatableValue || validatableValue === '')) {
|
19
|
+
target.markValid();
|
20
|
+
|
21
|
+
return !target.hasError();
|
22
|
+
}
|
23
|
+
|
24
|
+
if (typeof validatableValue !== 'undefined' && validatableValue.length >= options.length) {
|
25
|
+
target.markValid();
|
26
|
+
} else {
|
27
|
+
target.markInvalid(options.message);
|
28
|
+
}
|
29
|
+
|
30
|
+
return !target.hasError();
|
31
|
+
};
|
32
|
+
|
33
|
+
target.subscribe(target.validate);
|
34
|
+
|
35
|
+
//return the original observable
|
36
|
+
return target;
|
37
|
+
};
|
38
|
+
|
39
|
+
})(ko, $);
|
@@ -0,0 +1,64 @@
|
|
1
|
+
(function(ko, $) {
|
2
|
+
"use strict";
|
3
|
+
|
4
|
+
ko.extenders.numericRange = function(target, options) {
|
5
|
+
ko.utils.validatorBase(target);
|
6
|
+
|
7
|
+
var defaults = {
|
8
|
+
message: "",
|
9
|
+
allowBlank: true,
|
10
|
+
requiredMessage: "",
|
11
|
+
if: null,
|
12
|
+
dependencies: []
|
13
|
+
};
|
14
|
+
|
15
|
+
options = $.extend({}, defaults, options);
|
16
|
+
|
17
|
+
target.validate = function validate(newValue) {
|
18
|
+
var validatableValue = typeof newValue === 'undefined' ? target() : newValue;
|
19
|
+
|
20
|
+
validatableValue = parseInt(validatableValue, 10);
|
21
|
+
|
22
|
+
if (typeof options.if === 'function' && options.if() === false) {
|
23
|
+
target.markValid();
|
24
|
+
return true;
|
25
|
+
}
|
26
|
+
|
27
|
+
if (!validatableValue && !options.allowBlank) {
|
28
|
+
target.markInvalid(options.requiredMessage);
|
29
|
+
return false;
|
30
|
+
}
|
31
|
+
|
32
|
+
if (typeof options.min !== 'undefined' && validatableValue < options.min) {
|
33
|
+
target.markInvalid(options.message);
|
34
|
+
return false;
|
35
|
+
}
|
36
|
+
|
37
|
+
if (typeof options.max !== 'undefined' && validatableValue > options.max) {
|
38
|
+
target.markInvalid(options.message);
|
39
|
+
return false;
|
40
|
+
}
|
41
|
+
|
42
|
+
target.markValid();
|
43
|
+
return true;
|
44
|
+
};
|
45
|
+
|
46
|
+
target.subscribe(target.validate);
|
47
|
+
|
48
|
+
if (ko.isObservable(options.if)) {
|
49
|
+
options.dependencies.push(options.if);
|
50
|
+
}
|
51
|
+
|
52
|
+
ko.utils.arrayForEach(options.dependencies, function(dependency) {
|
53
|
+
dependency.subscribe(function(newValue) {
|
54
|
+
if (!target.isUnvalidated()) {
|
55
|
+
target.validate();
|
56
|
+
}
|
57
|
+
});
|
58
|
+
});
|
59
|
+
|
60
|
+
//return the original observable
|
61
|
+
return target;
|
62
|
+
};
|
63
|
+
|
64
|
+
})(ko, $);
|
@@ -0,0 +1,39 @@
|
|
1
|
+
(function(ko, $) {
|
2
|
+
"use strict";
|
3
|
+
|
4
|
+
ko.extenders.required = function(target, options) {
|
5
|
+
ko.utils.validatorBase(target);
|
6
|
+
|
7
|
+
var defaults = {
|
8
|
+
message: "",
|
9
|
+
validate_if: null
|
10
|
+
};
|
11
|
+
|
12
|
+
options = $.extend({}, defaults, options);
|
13
|
+
|
14
|
+
target.isRequired = true;
|
15
|
+
|
16
|
+
target.validate = function validate(newValue) {
|
17
|
+
if (typeof options.validate_if === 'function' && !options.validate_if()) {
|
18
|
+
target.markValid();
|
19
|
+
return true;
|
20
|
+
}
|
21
|
+
|
22
|
+
var validatableValue = typeof newValue === 'undefined' ? target() : newValue;
|
23
|
+
|
24
|
+
if (validatableValue) {
|
25
|
+
target.markValid();
|
26
|
+
} else {
|
27
|
+
target.markInvalid(options.message);
|
28
|
+
}
|
29
|
+
|
30
|
+
return !target.hasError();
|
31
|
+
};
|
32
|
+
|
33
|
+
target.subscribe(target.validate);
|
34
|
+
|
35
|
+
//return the original observable
|
36
|
+
return target;
|
37
|
+
};
|
38
|
+
|
39
|
+
})(ko, $);
|
@@ -0,0 +1,32 @@
|
|
1
|
+
(function(ko, $, moment) {
|
2
|
+
"use strict";
|
3
|
+
|
4
|
+
ko.extenders.validDate = function(target, options) {
|
5
|
+
ko.utils.validatorBase(target);
|
6
|
+
|
7
|
+
var defaults = {
|
8
|
+
message: ""
|
9
|
+
};
|
10
|
+
|
11
|
+
options = $.extend({}, defaults, options);
|
12
|
+
|
13
|
+
target.validate = function validate(newValue) {
|
14
|
+
var validatableValue = typeof newValue === 'undefined' ? target() : newValue,
|
15
|
+
m = moment(validatableValue, ["DD MM", "DD MM YY", "DD MM YYYY"]);
|
16
|
+
|
17
|
+
if ( m === null || !m.isValid() || m.isBefore(moment().startOf('day')) ) {
|
18
|
+
target.markInvalid(options.message);
|
19
|
+
return false;
|
20
|
+
}
|
21
|
+
|
22
|
+
target.markValid();
|
23
|
+
return true;
|
24
|
+
};
|
25
|
+
|
26
|
+
target.subscribe(target.validate);
|
27
|
+
|
28
|
+
//return the original observable
|
29
|
+
return target;
|
30
|
+
};
|
31
|
+
|
32
|
+
})(ko, $, moment);
|
@@ -0,0 +1,41 @@
|
|
1
|
+
(function(ko, $) {
|
2
|
+
"use strict";
|
3
|
+
|
4
|
+
ko.extenders.validTime = function(target, options) {
|
5
|
+
ko.utils.validatorBase(target);
|
6
|
+
|
7
|
+
var defaults = {
|
8
|
+
message: ""
|
9
|
+
};
|
10
|
+
|
11
|
+
options = $.extend({}, defaults, options);
|
12
|
+
|
13
|
+
target.validate = function validate(newValue) {
|
14
|
+
var validatableValue = typeof newValue === 'undefined' ? target() : newValue,
|
15
|
+
hour,
|
16
|
+
minute;
|
17
|
+
|
18
|
+
if (validatableValue.indexOf(':') === -1) {
|
19
|
+
target.markInvalid(options.message);
|
20
|
+
return false;
|
21
|
+
}
|
22
|
+
|
23
|
+
hour = parseInt(validatableValue.split(':')[0], 10);
|
24
|
+
minute = parseInt(validatableValue.split(':')[1], 10);
|
25
|
+
|
26
|
+
if ( (hour < 0 || hour > 23) || (minute < 0 || minute > 59) ) {
|
27
|
+
target.markInvalid(options.message);
|
28
|
+
return false;
|
29
|
+
}
|
30
|
+
|
31
|
+
target.markValid();
|
32
|
+
return true;
|
33
|
+
};
|
34
|
+
|
35
|
+
target.subscribe(target.validate);
|
36
|
+
|
37
|
+
//return the original observable
|
38
|
+
return target;
|
39
|
+
};
|
40
|
+
|
41
|
+
})(ko, $);
|
@@ -0,0 +1,75 @@
|
|
1
|
+
(function(ko, $) {
|
2
|
+
"use strict";
|
3
|
+
|
4
|
+
ko.utils.validatorBase = function(target) {
|
5
|
+
if (typeof target.isValidatable === 'undefined') {
|
6
|
+
target.isValidatable = true;
|
7
|
+
}
|
8
|
+
|
9
|
+
if (typeof target.hasError === 'undefined') {
|
10
|
+
target.hasError = ko.observable();
|
11
|
+
}
|
12
|
+
|
13
|
+
if (typeof target.isUnvalidated === 'undefined') {
|
14
|
+
target.isUnvalidated = ko.observable(true);
|
15
|
+
}
|
16
|
+
|
17
|
+
if (typeof target.validationInProgress === 'undefined') {
|
18
|
+
target.validationInProgress = ko.observable(false);
|
19
|
+
}
|
20
|
+
|
21
|
+
if (typeof target.onNextValidationChange === 'undefined') {
|
22
|
+
target.onNextValidationChange = null;
|
23
|
+
}
|
24
|
+
|
25
|
+
if (typeof target.validationMessage === 'undefined') {
|
26
|
+
target.validationMessage = ko.observable();
|
27
|
+
}
|
28
|
+
|
29
|
+
if (typeof target.forceValidate === 'undefined') {
|
30
|
+
target.forceValidate = function forceValidate() {
|
31
|
+
var args = Array.prototype.slice.call(arguments);
|
32
|
+
|
33
|
+
target.validate.apply(target, args);
|
34
|
+
};
|
35
|
+
}
|
36
|
+
|
37
|
+
if (typeof target.markValid === 'undefined') {
|
38
|
+
target.markValid = function markValid() {
|
39
|
+
var hadError = target.hasError(),
|
40
|
+
wasUnvalidated = target.isUnvalidated();
|
41
|
+
|
42
|
+
target.hasError(false);
|
43
|
+
|
44
|
+
if (target.isUnvalidated()) {
|
45
|
+
target.isUnvalidated(false);
|
46
|
+
}
|
47
|
+
|
48
|
+
if ((hadError || wasUnvalidated) && target.onNextValidationChange) {
|
49
|
+
target.onNextValidationChange(true);
|
50
|
+
target.onNextValidationChange = null;
|
51
|
+
}
|
52
|
+
};
|
53
|
+
}
|
54
|
+
|
55
|
+
if (typeof target.markInvalid === 'undefined') {
|
56
|
+
target.markInvalid = function markInvalid(message) {
|
57
|
+
var hadError = target.hasError(),
|
58
|
+
wasUnvalidated = target.isUnvalidated();
|
59
|
+
|
60
|
+
target.hasError(true);
|
61
|
+
target.validationMessage(message);
|
62
|
+
|
63
|
+
if (target.isUnvalidated()) {
|
64
|
+
target.isUnvalidated(false);
|
65
|
+
}
|
66
|
+
|
67
|
+
if ((!hadError || wasUnvalidated) && target.onNextValidationChange) {
|
68
|
+
target.onNextValidationChange(false);
|
69
|
+
target.onNextValidationChange = null;
|
70
|
+
}
|
71
|
+
};
|
72
|
+
}
|
73
|
+
};
|
74
|
+
|
75
|
+
})(ko, $);
|
@@ -0,0 +1,97 @@
|
|
1
|
+
|
2
|
+
// Expose plugin as an AMD module if AMD loader is present:
|
3
|
+
(function (factory) {
|
4
|
+
'use strict';
|
5
|
+
|
6
|
+
if (typeof define === 'function' && define.amd) {
|
7
|
+
define(['jquery'], factory);
|
8
|
+
} else {
|
9
|
+
factory(jQuery);
|
10
|
+
}
|
11
|
+
|
12
|
+
}(function ($) {
|
13
|
+
'use strict';
|
14
|
+
|
15
|
+
function ActivityButton(button) {
|
16
|
+
this.$button = $(button);
|
17
|
+
this.isOn = false;
|
18
|
+
this.iconCache = null;
|
19
|
+
}
|
20
|
+
|
21
|
+
ActivityButton.prototype = (function() {
|
22
|
+
|
23
|
+
var on, off, active;
|
24
|
+
|
25
|
+
on = function on() {
|
26
|
+
if (this.isOn) {
|
27
|
+
return false;
|
28
|
+
}
|
29
|
+
|
30
|
+
var existingIcon = this.$button.find('[class^="icon-"]');
|
31
|
+
|
32
|
+
if (existingIcon.length > 0) {
|
33
|
+
this.iconCache = existingIcon.remove();
|
34
|
+
}
|
35
|
+
|
36
|
+
this.$button.prepend("<i class='icon-spin3 animate-spin'></i>");
|
37
|
+
|
38
|
+
this.isOn = true;
|
39
|
+
};
|
40
|
+
|
41
|
+
off = function off() {
|
42
|
+
if (!this.isOn) {
|
43
|
+
return false;
|
44
|
+
}
|
45
|
+
|
46
|
+
this.$button.find('.icon-spin3').remove();
|
47
|
+
|
48
|
+
if (this.iconCache) {
|
49
|
+
this.$button.prepend(this.iconCache);
|
50
|
+
this.iconCache = null;
|
51
|
+
}
|
52
|
+
|
53
|
+
this.isOn = false;
|
54
|
+
};
|
55
|
+
|
56
|
+
active = function active() {
|
57
|
+
return this.isOn;
|
58
|
+
};
|
59
|
+
|
60
|
+
return {
|
61
|
+
on: on,
|
62
|
+
off: off,
|
63
|
+
active: active
|
64
|
+
};
|
65
|
+
})();
|
66
|
+
|
67
|
+
// Create chainable jQuery plugin:
|
68
|
+
$.fn.activityButton = function (optionsOrFnName, args) {
|
69
|
+
var dataKey = 'activityButton';
|
70
|
+
|
71
|
+
// If function invoked without argument return
|
72
|
+
// instance of the first matched element
|
73
|
+
if (arguments.length === 0 && this.first().data(dataKey)) {
|
74
|
+
return this.first().data(dataKey);
|
75
|
+
}
|
76
|
+
|
77
|
+
return this.each(function () {
|
78
|
+
var inputElement = $(this),
|
79
|
+
instance = inputElement.data(dataKey);
|
80
|
+
|
81
|
+
if (typeof optionsOrFnName === 'string') {
|
82
|
+
if (instance && typeof instance[optionsOrFnName] === 'function') {
|
83
|
+
instance[optionsOrFnName](args);
|
84
|
+
}
|
85
|
+
|
86
|
+
} else {
|
87
|
+
// If instance already exists, destroy it:
|
88
|
+
if (instance && instance.dispose) {
|
89
|
+
instance.dispose();
|
90
|
+
}
|
91
|
+
|
92
|
+
instance = new ActivityButton(this, optionsOrFnName);
|
93
|
+
inputElement.data(dataKey, instance);
|
94
|
+
}
|
95
|
+
});
|
96
|
+
};
|
97
|
+
}));
|
@@ -0,0 +1,46 @@
|
|
1
|
+
window.kea.notify = (function() {
|
2
|
+
"use strict";
|
3
|
+
|
4
|
+
var addNotificationToDom,
|
5
|
+
displayNotifications,
|
6
|
+
notify,
|
7
|
+
notifications = {};
|
8
|
+
|
9
|
+
addNotificationToDom = function addNotificationToDom(text, type) {
|
10
|
+
var clickToClose = true,
|
11
|
+
timeout = 4000,
|
12
|
+
cssClass = 'humane-original-info';
|
13
|
+
|
14
|
+
if (type === 'alert' || type === 'error') {
|
15
|
+
timeout = 0;
|
16
|
+
cssClass = 'humane-original-error';
|
17
|
+
}
|
18
|
+
|
19
|
+
humane.log(text, { baseCls: 'humane-original', timeout: timeout, clickToClose: clickToClose, addnCls: cssClass });
|
20
|
+
};
|
21
|
+
|
22
|
+
displayNotifications = function displayNotifications() {
|
23
|
+
if (!$.isReady) {
|
24
|
+
return;
|
25
|
+
}
|
26
|
+
|
27
|
+
$.each(notifications, function(type, notificationsForType) {
|
28
|
+
$.each(notificationsForType, function(idx, text) {
|
29
|
+
addNotificationToDom(text, type);
|
30
|
+
});
|
31
|
+
|
32
|
+
notifications[type] = [];
|
33
|
+
});
|
34
|
+
};
|
35
|
+
|
36
|
+
notify = function notify(text, type) {
|
37
|
+
if (typeof notifications[type] === 'undefined') {
|
38
|
+
notifications[type] = [];
|
39
|
+
}
|
40
|
+
|
41
|
+
notifications[type].push(text);
|
42
|
+
displayNotifications();
|
43
|
+
};
|
44
|
+
|
45
|
+
return notify;
|
46
|
+
})();
|
@@ -0,0 +1,11 @@
|
|
1
|
+
(function(app, ko, $) {
|
2
|
+
"use strict";
|
3
|
+
|
4
|
+
app.initialize_on = function initialize_on() {
|
5
|
+
var selectors = Array.prototype.slice.call(arguments),
|
6
|
+
callback = selectors.pop();
|
7
|
+
|
8
|
+
app.initializers.push({selectors: selectors, callback: callback});
|
9
|
+
};
|
10
|
+
})(window.app, ko, $);
|
11
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
//= require_directory ./bindings
|
2
|
+
//= require_directory ./extenders
|
3
|
+
//= require ./models/base
|
4
|
+
//= require ./services/base
|
5
|
+
//= require ./viewmodels/base
|
6
|
+
|
7
|
+
//= require ./overlay/overlay_control
|
8
|
+
//= require ./overlay/overlay_template
|
9
|
+
//= require ./overlay/child_vm_overlay
|
10
|
+
|
11
|
+
//= require ./viewmodels/sherlock
|
12
|
+
//= require ./sherlock/base_provider
|
13
|
+
|
14
|
+
//= require ./initializers/base
|
@@ -0,0 +1,20 @@
|
|
1
|
+
//= require knockout-3.2.0-debug
|
2
|
+
|
3
|
+
//= require_directory ../../../../vendor/assets/javascripts/.
|
4
|
+
|
5
|
+
// Bower components
|
6
|
+
|
7
|
+
//= require attachejs/attache
|
8
|
+
//= require attachejs/attache-jquery
|
9
|
+
//= require veiljs/veil
|
10
|
+
//= require veiljs/veil-jquery
|
11
|
+
//= require uri.js/src/URI.js
|
12
|
+
//= require knockout-sortable/build/knockout-sortable
|
13
|
+
//= require humane-js/humane
|
14
|
+
//= require Keypress/keypress.js
|
15
|
+
|
16
|
+
//= require ./kea_init
|
17
|
+
|
18
|
+
// Internal helpers and plugins
|
19
|
+
|
20
|
+
//= require_directory ./helpers
|
@@ -0,0 +1,24 @@
|
|
1
|
+
window.kea = window.kea || {};
|
2
|
+
window.kea.models = window.kea.models || {};
|
3
|
+
window.kea.services = window.kea.services || {};
|
4
|
+
window.kea.viewmodels = window.kea.viewmodels || {};
|
5
|
+
|
6
|
+
window.kea.sherlock = {
|
7
|
+
providers: []
|
8
|
+
};
|
9
|
+
|
10
|
+
window.kea.u = {
|
11
|
+
inherit: function inherit(Child, Parent) {
|
12
|
+
"use strict";
|
13
|
+
|
14
|
+
Child.super_ = Parent;
|
15
|
+
Child.prototype = Object.create(Parent.prototype, {
|
16
|
+
constructor: {
|
17
|
+
value: Child,
|
18
|
+
enumerable: false,
|
19
|
+
writable: true,
|
20
|
+
configurable: true
|
21
|
+
}
|
22
|
+
});
|
23
|
+
}
|
24
|
+
};
|