UI Cleanup - Updated Instrumentation, jQuery and Mixins subtrees.
This commit is contained in:
parent
44928c8f64
commit
70bfad4e6a
|
@ -2,30 +2,33 @@ var $ = require('jquery');
|
||||||
var vent = require('vent');
|
var vent = require('vent');
|
||||||
var HotkeysView = require('./HotkeysView');
|
var HotkeysView = require('./HotkeysView');
|
||||||
|
|
||||||
module.exports = (function(){
|
|
||||||
$(document).on('keypress', function(e) {
|
$(document).on('keypress', function(e) {
|
||||||
if ($(e.target).is('input') || $(e.target).is('textarea')) {
|
if ($(e.target).is('input') || $(e.target).is('textarea')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.charCode === 63) {
|
if (e.charCode === 63) {
|
||||||
vent.trigger(vent.Commands.OpenModalCommand, new HotkeysView());
|
vent.trigger(vent.Commands.OpenModalCommand, new HotkeysView());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).on('keydown', function(e) {
|
$(document).on('keydown', function(e) {
|
||||||
if (e.ctrlKey && e.keyCode === 83) {
|
if (e.ctrlKey && e.keyCode === 83) {
|
||||||
vent.trigger(vent.Hotkeys.SaveSettings);
|
vent.trigger(vent.Hotkeys.SaveSettings);
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($(e.target).is('input') || $(e.target).is('textarea')) {
|
if ($(e.target).is('input') || $(e.target).is('textarea')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.ctrlKey || e.metaKey || e.altKey) {
|
if (e.ctrlKey || e.metaKey || e.altKey) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.keyCode === 84) {
|
if (e.keyCode === 84) {
|
||||||
vent.trigger(vent.Hotkeys.NavbarSearch);
|
vent.trigger(vent.Hotkeys.NavbarSearch);
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}).call(this);
|
|
|
@ -1,4 +1,6 @@
|
||||||
var vent = require('vent');
|
var vent = require('vent');
|
||||||
var Marionette = require('marionette');
|
var Marionette = require('marionette');
|
||||||
|
|
||||||
module.exports = Marionette.ItemView.extend({template : 'Hotkeys/HotkeysViewTemplate'});
|
module.exports = Marionette.ItemView.extend({
|
||||||
|
template : 'Hotkeys/HotkeysViewTemplate'
|
||||||
|
});
|
|
@ -1,69 +1,86 @@
|
||||||
var $ = require('jquery');
|
var $ = require('jquery');
|
||||||
var Messenger = require('messenger');
|
var Messenger = require('messenger');
|
||||||
|
|
||||||
module.exports = (function(){
|
|
||||||
'use strict';
|
|
||||||
window.alert = function(message) {
|
window.alert = function(message) {
|
||||||
new Messenger().post(message);
|
new Messenger().post(message);
|
||||||
};
|
};
|
||||||
|
|
||||||
var addError = function(message) {
|
var addError = function(message) {
|
||||||
$('#errors').append('<div>' + message + '</div>');
|
$('#errors').append('<div>' + message + '</div>');
|
||||||
};
|
};
|
||||||
|
|
||||||
window.onerror = function(msg, url, line) {
|
window.onerror = function(msg, url, line) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
var a = document.createElement('a');
|
var a = document.createElement('a');
|
||||||
a.href = url;
|
a.href = url;
|
||||||
var filename = a.pathname.split('/').pop();
|
var filename = a.pathname.split('/').pop();
|
||||||
|
|
||||||
|
//Suppress Firefox debug errors when console window is closed
|
||||||
if (filename.toLowerCase() === 'markupview.jsm' || filename.toLowerCase() === 'markup-view.js') {
|
if (filename.toLowerCase() === 'markupview.jsm' || filename.toLowerCase() === 'markup-view.js') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var messageText = filename + ' : ' + line + '</br>' + msg;
|
var messageText = filename + ' : ' + line + '</br>' + msg;
|
||||||
|
|
||||||
var message = {
|
var message = {
|
||||||
message : messageText,
|
message : messageText,
|
||||||
type : 'error',
|
type : 'error',
|
||||||
hideAfter : 1000,
|
hideAfter : 1000,
|
||||||
showCloseButton : true
|
showCloseButton : true
|
||||||
};
|
};
|
||||||
|
|
||||||
new Messenger().post(message);
|
new Messenger().post(message);
|
||||||
|
|
||||||
addError(message.message);
|
addError(message.message);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
console.log('An error occurred while reporting error. ' + error);
|
console.log('An error occurred while reporting error. ' + error);
|
||||||
console.log(msg);
|
console.log(msg);
|
||||||
new Messenger().post('Couldn\'t report JS error. ' + msg);
|
new Messenger().post('Couldn\'t report JS error. ' + msg);
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
return false; //don't suppress default alerts and logs.
|
||||||
};
|
};
|
||||||
|
|
||||||
$(document).ajaxError(function(event, xmlHttpRequest, ajaxOptions) {
|
$(document).ajaxError(function(event, xmlHttpRequest, ajaxOptions) {
|
||||||
|
|
||||||
|
//don't report 200 error codes
|
||||||
if (xmlHttpRequest.status >= 200 && xmlHttpRequest.status <= 300) {
|
if (xmlHttpRequest.status >= 200 && xmlHttpRequest.status <= 300) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//don't report aborted requests
|
||||||
if (xmlHttpRequest.statusText === 'abort') {
|
if (xmlHttpRequest.statusText === 'abort') {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
var message = {
|
var message = {
|
||||||
type : 'error',
|
type : 'error',
|
||||||
hideAfter : 1000,
|
hideAfter : 1000,
|
||||||
showCloseButton : true
|
showCloseButton : true
|
||||||
};
|
};
|
||||||
|
|
||||||
if (xmlHttpRequest.status === 0 && xmlHttpRequest.readyState === 0) {
|
if (xmlHttpRequest.status === 0 && xmlHttpRequest.readyState === 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xmlHttpRequest.status === 400 && ajaxOptions.isValidatedCall) {
|
if (xmlHttpRequest.status === 400 && ajaxOptions.isValidatedCall) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xmlHttpRequest.status === 503) {
|
if (xmlHttpRequest.status === 503) {
|
||||||
message.message = xmlHttpRequest.responseJSON.message;
|
message.message = xmlHttpRequest.responseJSON.message;
|
||||||
}
|
} else if (xmlHttpRequest.status === 409) {
|
||||||
if(xmlHttpRequest.status === 409) {
|
|
||||||
message.message = xmlHttpRequest.responseJSON.message;
|
message.message = xmlHttpRequest.responseJSON.message;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
message.message = '[{0}] {1} : {2}'.format(ajaxOptions.type, xmlHttpRequest.statusText, ajaxOptions.url);
|
message.message = '[{0}] {1} : {2}'.format(ajaxOptions.type, xmlHttpRequest.statusText, ajaxOptions.url);
|
||||||
}
|
}
|
||||||
|
|
||||||
new Messenger().post(message);
|
new Messenger().post(message);
|
||||||
addError(message.message);
|
addError(message.message);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}).call(this);
|
|
|
@ -1,11 +1,12 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
String.prototype.format = function() {
|
String.prototype.format = function() {
|
||||||
var args = arguments;
|
var args = arguments;
|
||||||
|
|
||||||
return this.replace(/{(\d+)}/g, function(match, number) {
|
return this.replace(/{(\d+)}/g, function(match, number) {
|
||||||
if (typeof args[number] !== 'undefined') {
|
if (typeof args[number] !== 'undefined') {
|
||||||
return args[number];
|
return args[number];
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,16 +1,22 @@
|
||||||
module.exports = function() {
|
module.exports = function() {
|
||||||
var originalInit = this.prototype.initialize;
|
var originalInit = this.prototype.initialize;
|
||||||
|
|
||||||
this.prototype.initialize = function() {
|
this.prototype.initialize = function() {
|
||||||
|
|
||||||
this.isSaved = true;
|
this.isSaved = true;
|
||||||
|
|
||||||
this.on('change', function() {
|
this.on('change', function() {
|
||||||
this.isSaved = false;
|
this.isSaved = false;
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
this.on('sync', function() {
|
this.on('sync', function() {
|
||||||
this.isSaved = true;
|
this.isSaved = true;
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
if (originalInit) {
|
if (originalInit) {
|
||||||
originalInit.call(this);
|
originalInit.call(this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
|
@ -3,73 +3,98 @@ var AppLayout = require('../AppLayout');
|
||||||
module.exports = function() {
|
module.exports = function() {
|
||||||
var originalInitialize = this.prototype.initialize;
|
var originalInitialize = this.prototype.initialize;
|
||||||
var originalOnBeforeClose = this.prototype.onBeforeClose;
|
var originalOnBeforeClose = this.prototype.onBeforeClose;
|
||||||
|
|
||||||
var saveInternal = function() {
|
var saveInternal = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.ui.indicator.show();
|
this.ui.indicator.show();
|
||||||
|
|
||||||
if (this._onBeforeSave) {
|
if (this._onBeforeSave) {
|
||||||
this._onBeforeSave.call(this);
|
this._onBeforeSave.call(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
var promise = this.model.save();
|
var promise = this.model.save();
|
||||||
|
|
||||||
promise.always(function() {
|
promise.always(function() {
|
||||||
if (!self.isClosed) {
|
if (!self.isClosed) {
|
||||||
self.ui.indicator.hide();
|
self.ui.indicator.hide();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
promise.done(function() {
|
promise.done(function() {
|
||||||
self.originalModelData = JSON.stringify(self.model.toJSON());
|
self.originalModelData = JSON.stringify(self.model.toJSON());
|
||||||
});
|
});
|
||||||
|
|
||||||
return promise;
|
return promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.prototype.initialize = function(options) {
|
this.prototype.initialize = function(options) {
|
||||||
|
|
||||||
if (!this.model) {
|
if (!this.model) {
|
||||||
throw 'View has no model';
|
throw 'View has no model';
|
||||||
}
|
}
|
||||||
|
|
||||||
this.originalModelData = JSON.stringify(this.model.toJSON());
|
this.originalModelData = JSON.stringify(this.model.toJSON());
|
||||||
|
|
||||||
this.events = this.events || {};
|
this.events = this.events || {};
|
||||||
this.events['click .x-save'] = '_save';
|
this.events['click .x-save'] = '_save';
|
||||||
this.events['click .x-save-and-add'] = '_saveAndAdd';
|
this.events['click .x-save-and-add'] = '_saveAndAdd';
|
||||||
this.events['click .x-test'] = '_test';
|
this.events['click .x-test'] = '_test';
|
||||||
this.events['click .x-delete'] = '_delete';
|
this.events['click .x-delete'] = '_delete';
|
||||||
|
|
||||||
this.ui = this.ui || {};
|
this.ui = this.ui || {};
|
||||||
this.ui.indicator = '.x-indicator';
|
this.ui.indicator = '.x-indicator';
|
||||||
|
|
||||||
if (originalInitialize) {
|
if (originalInitialize) {
|
||||||
originalInitialize.call(this, options);
|
originalInitialize.call(this, options);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.prototype._save = function() {
|
this.prototype._save = function() {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
var promise = saveInternal.call(this);
|
var promise = saveInternal.call(this);
|
||||||
|
|
||||||
promise.done(function() {
|
promise.done(function() {
|
||||||
if (self._onAfterSave) {
|
if (self._onAfterSave) {
|
||||||
self._onAfterSave.call(self);
|
self._onAfterSave.call(self);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.prototype._saveAndAdd = function() {
|
this.prototype._saveAndAdd = function() {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
var promise = saveInternal.call(this);
|
var promise = saveInternal.call(this);
|
||||||
|
|
||||||
promise.done(function() {
|
promise.done(function() {
|
||||||
if (self._onAfterSaveAndAdd) {
|
if (self._onAfterSaveAndAdd) {
|
||||||
self._onAfterSaveAndAdd.call(self);
|
self._onAfterSaveAndAdd.call(self);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.prototype._test = function() {
|
this.prototype._test = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
this.ui.indicator.show();
|
this.ui.indicator.show();
|
||||||
|
|
||||||
this.model.test().always(function() {
|
this.model.test().always(function() {
|
||||||
self.ui.indicator.hide();
|
self.ui.indicator.hide();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.prototype._delete = function() {
|
this.prototype._delete = function() {
|
||||||
var view = new this._deleteView({ model : this.model });
|
var view = new this._deleteView({ model : this.model });
|
||||||
AppLayout.modalRegion.show(view);
|
AppLayout.modalRegion.show(view);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.prototype.onBeforeClose = function() {
|
this.prototype.onBeforeClose = function() {
|
||||||
this.model.set(JSON.parse(this.originalModelData));
|
this.model.set(JSON.parse(this.originalModelData));
|
||||||
|
|
||||||
if (originalOnBeforeClose) {
|
if (originalOnBeforeClose) {
|
||||||
originalOnBeforeClose.call(this);
|
originalOnBeforeClose.call(this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
|
@ -5,13 +5,14 @@ module.exports = function(){
|
||||||
|
|
||||||
this.prototype.setFilter = function(filter, options) {
|
this.prototype.setFilter = function(filter, options) {
|
||||||
options = _.extend({ reset : true }, options || {});
|
options = _.extend({ reset : true }, options || {});
|
||||||
|
|
||||||
this.state.filterKey = filter[0];
|
this.state.filterKey = filter[0];
|
||||||
this.state.filterValue = filter[1];
|
this.state.filterValue = filter[1];
|
||||||
|
|
||||||
if (options.reset) {
|
if (options.reset) {
|
||||||
if (this.mode !== 'server') {
|
if (this.mode !== 'server') {
|
||||||
this.fullCollection.resetFiltered();
|
this.fullCollection.resetFiltered();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return this.fetch();
|
return this.fetch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,12 +26,13 @@ module.exports = function(){
|
||||||
|
|
||||||
this.prototype._makeFullCollection = function(models, options) {
|
this.prototype._makeFullCollection = function(models, options) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.shadowCollection = originalMakeFullCollection.call(this, models, options);
|
self.shadowCollection = originalMakeFullCollection.call(this, models, options);
|
||||||
|
|
||||||
var filterModel = function(model) {
|
var filterModel = function(model) {
|
||||||
if (!self.state.filterKey || !self.state.filterValue) {
|
if (!self.state.filterKey || !self.state.filterValue) {
|
||||||
return true;
|
return true;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return model.get(self.state.filterKey) === self.state.filterValue;
|
return model.get(self.state.filterKey) === self.state.filterValue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -53,13 +55,16 @@ module.exports = function(){
|
||||||
|
|
||||||
return fullCollection;
|
return fullCollection;
|
||||||
};
|
};
|
||||||
|
|
||||||
_.extend(this.prototype.state, {
|
_.extend(this.prototype.state, {
|
||||||
filterKey : null,
|
filterKey : null,
|
||||||
filterValue : null
|
filterValue : null
|
||||||
});
|
});
|
||||||
|
|
||||||
_.extend(this.prototype.queryParams, {
|
_.extend(this.prototype.queryParams, {
|
||||||
filterKey : 'filterKey',
|
filterKey : 'filterKey',
|
||||||
filterValue : 'filterValue'
|
filterValue : 'filterValue'
|
||||||
});
|
});
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
|
@ -1,35 +1,46 @@
|
||||||
var ModelBinder = require('backbone.modelbinder');
|
var ModelBinder = require('backbone.modelbinder');
|
||||||
|
|
||||||
module.exports = function() {
|
module.exports = function() {
|
||||||
|
|
||||||
var originalOnRender = this.prototype.onRender;
|
var originalOnRender = this.prototype.onRender;
|
||||||
var originalBeforeClose = this.prototype.onBeforeClose;
|
var originalBeforeClose = this.prototype.onBeforeClose;
|
||||||
|
|
||||||
this.prototype.onRender = function() {
|
this.prototype.onRender = function() {
|
||||||
|
|
||||||
if (!this.model) {
|
if (!this.model) {
|
||||||
throw 'View has no model for binding';
|
throw 'View has no model for binding';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this._modelBinder) {
|
if (!this._modelBinder) {
|
||||||
this._modelBinder = new ModelBinder();
|
this._modelBinder = new ModelBinder();
|
||||||
}
|
}
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
changeTriggers : {
|
changeTriggers : {
|
||||||
"" : 'change typeahead:selected typeahead:autocompleted',
|
'' : 'change typeahead:selected typeahead:autocompleted',
|
||||||
"[contenteditable]" : 'blur',
|
'[contenteditable]' : 'blur',
|
||||||
"[data-onkeyup]" : 'keyup'
|
'[data-onkeyup]' : 'keyup'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this._modelBinder.bind(this.model, this.el, null, options);
|
this._modelBinder.bind(this.model, this.el, null, options);
|
||||||
|
|
||||||
if (originalOnRender) {
|
if (originalOnRender) {
|
||||||
originalOnRender.call(this);
|
originalOnRender.call(this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.prototype.onBeforeClose = function() {
|
this.prototype.onBeforeClose = function() {
|
||||||
|
|
||||||
if (this._modelBinder) {
|
if (this._modelBinder) {
|
||||||
this._modelBinder.unbind();
|
this._modelBinder.unbind();
|
||||||
delete this._modelBinder;
|
delete this._modelBinder;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (originalBeforeClose) {
|
if (originalBeforeClose) {
|
||||||
originalBeforeClose.call(this);
|
originalBeforeClose.call(this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
|
@ -8,10 +8,12 @@ module.exports = function(){
|
||||||
if (template) {
|
if (template) {
|
||||||
return template.toLocaleLowerCase().replace('template', '').replace(regex, '-');
|
return template.toLocaleLowerCase().replace('template', '').replace(regex, '-');
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
var originalOnRender = this.onRender;
|
var originalOnRender = this.onRender;
|
||||||
|
|
||||||
this.onRender = function() {
|
this.onRender = function() {
|
||||||
|
|
||||||
if (window.NzbDrone.NameViews) {
|
if (window.NzbDrone.NameViews) {
|
||||||
|
|
|
@ -2,22 +2,30 @@ var _ = require('underscore');
|
||||||
var Config = require('../Config');
|
var Config = require('../Config');
|
||||||
|
|
||||||
module.exports = function() {
|
module.exports = function() {
|
||||||
|
|
||||||
var originalInit = this.prototype.initialize;
|
var originalInit = this.prototype.initialize;
|
||||||
this.prototype.initialize = function(options) {
|
this.prototype.initialize = function(options) {
|
||||||
|
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
if (options.tableName) {
|
if (options.tableName) {
|
||||||
this.tableName = options.tableName;
|
this.tableName = options.tableName;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.tableName && !options.tableName) {
|
if (!this.tableName && !options.tableName) {
|
||||||
throw 'tableName is required';
|
throw 'tableName is required';
|
||||||
}
|
}
|
||||||
|
|
||||||
_setInitialState.call(this);
|
_setInitialState.call(this);
|
||||||
|
|
||||||
this.on('backgrid:sort', _storeStateFromBackgrid, this);
|
this.on('backgrid:sort', _storeStateFromBackgrid, this);
|
||||||
this.on('drone:sort', _storeState, this);
|
this.on('drone:sort', _storeState, this);
|
||||||
|
|
||||||
if (originalInit) {
|
if (originalInit) {
|
||||||
originalInit.call(this, options);
|
originalInit.call(this, options);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!this.prototype._getSortMapping) {
|
if (!this.prototype._getSortMapping) {
|
||||||
this.prototype._getSortMapping = function(key) {
|
this.prototype._getSortMapping = function(key) {
|
||||||
return {
|
return {
|
||||||
|
@ -26,30 +34,39 @@ module.exports = function(){
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var _setInitialState = function() {
|
var _setInitialState = function() {
|
||||||
var key = Config.getValue('{0}.sortKey'.format(this.tableName), this.state.sortKey);
|
var key = Config.getValue('{0}.sortKey'.format(this.tableName), this.state.sortKey);
|
||||||
var direction = Config.getValue('{0}.sortDirection'.format(this.tableName), this.state.order);
|
var direction = Config.getValue('{0}.sortDirection'.format(this.tableName), this.state.order);
|
||||||
var order = parseInt(direction, 10);
|
var order = parseInt(direction, 10);
|
||||||
|
|
||||||
this.state.sortKey = this._getSortMapping(key).sortKey;
|
this.state.sortKey = this._getSortMapping(key).sortKey;
|
||||||
this.state.order = order;
|
this.state.order = order;
|
||||||
};
|
};
|
||||||
|
|
||||||
var _storeStateFromBackgrid = function(column, sortDirection) {
|
var _storeStateFromBackgrid = function(column, sortDirection) {
|
||||||
var order = _convertDirectionToInt(sortDirection);
|
var order = _convertDirectionToInt(sortDirection);
|
||||||
var sortKey = this._getSortMapping(column.get('name')).sortKey;
|
var sortKey = this._getSortMapping(column.get('name')).sortKey;
|
||||||
|
|
||||||
Config.setValue('{0}.sortKey'.format(this.tableName), sortKey);
|
Config.setValue('{0}.sortKey'.format(this.tableName), sortKey);
|
||||||
Config.setValue('{0}.sortDirection'.format(this.tableName), order);
|
Config.setValue('{0}.sortDirection'.format(this.tableName), order);
|
||||||
};
|
};
|
||||||
|
|
||||||
var _storeState = function(sortModel, sortDirection) {
|
var _storeState = function(sortModel, sortDirection) {
|
||||||
var order = _convertDirectionToInt(sortDirection);
|
var order = _convertDirectionToInt(sortDirection);
|
||||||
var sortKey = this._getSortMapping(sortModel.get('name')).sortKey;
|
var sortKey = this._getSortMapping(sortModel.get('name')).sortKey;
|
||||||
|
|
||||||
Config.setValue('{0}.sortKey'.format(this.tableName), sortKey);
|
Config.setValue('{0}.sortKey'.format(this.tableName), sortKey);
|
||||||
Config.setValue('{0}.sortDirection'.format(this.tableName), order);
|
Config.setValue('{0}.sortDirection'.format(this.tableName), order);
|
||||||
};
|
};
|
||||||
|
|
||||||
var _convertDirectionToInt = function(dir) {
|
var _convertDirectionToInt = function(dir) {
|
||||||
if (dir === 'ascending') {
|
if (dir === 'ascending') {
|
||||||
return '-1';
|
return '-1';
|
||||||
}
|
}
|
||||||
|
|
||||||
return '1';
|
return '1';
|
||||||
};
|
};
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
|
@ -2,14 +2,20 @@ var _ = require('underscore');
|
||||||
var Config = require('../Config');
|
var Config = require('../Config');
|
||||||
|
|
||||||
module.exports = function() {
|
module.exports = function() {
|
||||||
|
|
||||||
var originalSetSorting = this.prototype.setSorting;
|
var originalSetSorting = this.prototype.setSorting;
|
||||||
|
|
||||||
this.prototype.setSorting = function(sortKey, order, options) {
|
this.prototype.setSorting = function(sortKey, order, options) {
|
||||||
var sortMapping = this._getSortMapping(sortKey);
|
var sortMapping = this._getSortMapping(sortKey);
|
||||||
|
|
||||||
options = _.defaults({ sortValue : sortMapping.sortValue }, options || {});
|
options = _.defaults({ sortValue : sortMapping.sortValue }, options || {});
|
||||||
|
|
||||||
return originalSetSorting.call(this, sortMapping.sortKey, order, options);
|
return originalSetSorting.call(this, sortMapping.sortKey, order, options);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.prototype._getSortMappings = function() {
|
this.prototype._getSortMappings = function() {
|
||||||
var result = {};
|
var result = {};
|
||||||
|
|
||||||
if (this.sortMappings) {
|
if (this.sortMappings) {
|
||||||
_.each(this.sortMappings, function(values, key) {
|
_.each(this.sortMappings, function(values, key) {
|
||||||
var item = {
|
var item = {
|
||||||
|
@ -21,80 +27,104 @@ module.exports = function(){
|
||||||
result[item.sortKey] = item;
|
result[item.sortKey] = item;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.prototype._getSortMapping = function(key) {
|
this.prototype._getSortMapping = function(key) {
|
||||||
var sortMappings = this._getSortMappings();
|
var sortMappings = this._getSortMappings();
|
||||||
|
|
||||||
return sortMappings[key] || {
|
return sortMappings[key] || {
|
||||||
name : key,
|
name : key,
|
||||||
sortKey : key
|
sortKey : key
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
this.prototype._getSecondarySorting = function() {
|
this.prototype._getSecondarySorting = function() {
|
||||||
var sortKey = this.state.secondarySortKey;
|
var sortKey = this.state.secondarySortKey;
|
||||||
var sortOrder = this.state.secondarySortOrder || -1;
|
var sortOrder = this.state.secondarySortOrder || -1;
|
||||||
|
|
||||||
if (!sortKey || sortKey === this.state.sortKey) {
|
if (!sortKey || sortKey === this.state.sortKey) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var sortMapping = this._getSortMapping(sortKey);
|
var sortMapping = this._getSortMapping(sortKey);
|
||||||
|
|
||||||
if (!sortMapping.sortValue) {
|
if (!sortMapping.sortValue) {
|
||||||
sortMapping.sortValue = function(model, attr) {
|
sortMapping.sortValue = function(model, attr) {
|
||||||
return model.get(attr);
|
return model.get(attr);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
key : sortKey,
|
key : sortKey,
|
||||||
order : sortOrder,
|
order : sortOrder,
|
||||||
sortValue : sortMapping.sortValue
|
sortValue : sortMapping.sortValue
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
this.prototype._makeComparator = function(sortKey, order, sortValue) {
|
this.prototype._makeComparator = function(sortKey, order, sortValue) {
|
||||||
var state = this.state;
|
var state = this.state;
|
||||||
var secondarySorting = this._getSecondarySorting();
|
var secondarySorting = this._getSecondarySorting();
|
||||||
|
|
||||||
sortKey = sortKey || state.sortKey;
|
sortKey = sortKey || state.sortKey;
|
||||||
order = order || state.order;
|
order = order || state.order;
|
||||||
|
|
||||||
if (!sortKey || !order) {
|
if (!sortKey || !order) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sortValue) {
|
if (!sortValue) {
|
||||||
sortValue = function(model, attr) {
|
sortValue = function(model, attr) {
|
||||||
return model.get(attr);
|
return model.get(attr);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return function(left, right) {
|
return function(left, right) {
|
||||||
var l = sortValue(left, sortKey, order);
|
var l = sortValue(left, sortKey, order);
|
||||||
var r = sortValue(right, sortKey, order);
|
var r = sortValue(right, sortKey, order);
|
||||||
var t;
|
var t;
|
||||||
|
|
||||||
if (order === 1) {
|
if (order === 1) {
|
||||||
t = l;
|
t = l;
|
||||||
l = r;
|
l = r;
|
||||||
r = t;
|
r = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (l === r) {
|
if (l === r) {
|
||||||
|
|
||||||
if (secondarySorting) {
|
if (secondarySorting) {
|
||||||
var ls = secondarySorting.sortValue(left, secondarySorting.key, order);
|
var ls = secondarySorting.sortValue(left, secondarySorting.key, order);
|
||||||
var rs = secondarySorting.sortValue(right, secondarySorting.key, order);
|
var rs = secondarySorting.sortValue(right, secondarySorting.key, order);
|
||||||
var ts;
|
var ts;
|
||||||
|
|
||||||
if (secondarySorting.order === 1) {
|
if (secondarySorting.order === 1) {
|
||||||
ts = ls;
|
ts = ls;
|
||||||
ls = rs;
|
ls = rs;
|
||||||
rs = ts;
|
rs = ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ls === rs) {
|
if (ls === rs) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ls < rs) {
|
if (ls < rs) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (l < r) {
|
else if (l < r) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
|
@ -2,19 +2,23 @@ module.exports = function(){
|
||||||
this.prototype.appendHtml = function(collectionView, itemView, index) {
|
this.prototype.appendHtml = function(collectionView, itemView, index) {
|
||||||
var childrenContainer = collectionView.itemViewContainer ? collectionView.$(collectionView.itemViewContainer) : collectionView.$el;
|
var childrenContainer = collectionView.itemViewContainer ? collectionView.$(collectionView.itemViewContainer) : collectionView.$el;
|
||||||
var collection = collectionView.collection;
|
var collection = collectionView.collection;
|
||||||
|
|
||||||
|
// If the index of the model is at the end of the collection append, else insert at proper index
|
||||||
if (index >= collection.size() - 1) {
|
if (index >= collection.size() - 1) {
|
||||||
childrenContainer.append(itemView.el);
|
childrenContainer.append(itemView.el);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
var previousModel = collection.at(index + 1);
|
var previousModel = collection.at(index + 1);
|
||||||
var previousView = this.children.findByModel(previousModel);
|
var previousView = this.children.findByModel(previousModel);
|
||||||
|
|
||||||
if (previousView) {
|
if (previousView) {
|
||||||
previousView.$el.before(itemView.$el);
|
previousView.$el.before(itemView.$el);
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
childrenContainer.append(itemView.el);
|
childrenContainer.append(itemView.el);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
|
@ -4,28 +4,33 @@ var _ = require('underscore');
|
||||||
module.exports = (function() {
|
module.exports = (function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
return function() {
|
return function() {
|
||||||
|
|
||||||
var originalInitialize = this.prototype.initialize;
|
var originalInitialize = this.prototype.initialize;
|
||||||
var originalOnRender = this.prototype.onRender;
|
var originalOnRender = this.prototype.onRender;
|
||||||
var originalBeforeClose = this.prototype.onBeforeClose;
|
var originalBeforeClose = this.prototype.onBeforeClose;
|
||||||
|
|
||||||
var errorHandler = function(response) {
|
var errorHandler = function(response) {
|
||||||
if (this.model) {
|
if (this.model) {
|
||||||
this.model.trigger('validation:failed', response);
|
this.model.trigger('validation:failed', response);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
this.trigger('validation:failed', response);
|
this.trigger('validation:failed', response);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var validatedSync = function(method, model, options) {
|
var validatedSync = function(method, model, options) {
|
||||||
model.trigger('validation:sync');
|
model.trigger('validation:sync');
|
||||||
|
|
||||||
arguments[2].isValidatedCall = true;
|
arguments[2].isValidatedCall = true;
|
||||||
return model._originalSync.apply(this, arguments).fail(errorHandler.bind(this));
|
return model._originalSync.apply(this, arguments).fail(errorHandler.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
var bindToModel = function(model) {
|
var bindToModel = function(model) {
|
||||||
if (!model._originalSync) {
|
if (!model._originalSync) {
|
||||||
model._originalSync = model.sync;
|
model._originalSync = model.sync;
|
||||||
model.sync = validatedSync.bind(this);
|
model.sync = validatedSync.bind(this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var validationFailed = function(response) {
|
var validationFailed = function(response) {
|
||||||
if (response.status === 400) {
|
if (response.status === 400) {
|
||||||
var view = this;
|
var view = this;
|
||||||
|
@ -35,43 +40,54 @@ module.exports = (function(){
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.prototype.initialize = function(options) {
|
this.prototype.initialize = function(options) {
|
||||||
if (this.model) {
|
if (this.model) {
|
||||||
this.listenTo(this.model, 'validation:sync', function() {
|
this.listenTo(this.model, 'validation:sync', function() {
|
||||||
this.$el.removeAllErrors();
|
this.$el.removeAllErrors();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.listenTo(this.model, 'validation:failed', validationFailed);
|
this.listenTo(this.model, 'validation:failed', validationFailed);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
this.listenTo(this, 'validation:sync', function() {
|
this.listenTo(this, 'validation:sync', function() {
|
||||||
this.$el.removeAllErrors();
|
this.$el.removeAllErrors();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.listenTo(this, 'validation:failed', validationFailed);
|
this.listenTo(this, 'validation:failed', validationFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (originalInitialize) {
|
if (originalInitialize) {
|
||||||
originalInitialize.call(this, options);
|
originalInitialize.call(this, options);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.prototype.onRender = function() {
|
this.prototype.onRender = function() {
|
||||||
Validation.bind(this);
|
Validation.bind(this);
|
||||||
this.bindToModelValidation = bindToModel.bind(this);
|
this.bindToModelValidation = bindToModel.bind(this);
|
||||||
|
|
||||||
if (this.model) {
|
if (this.model) {
|
||||||
this.bindToModelValidation(this.model);
|
this.bindToModelValidation(this.model);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (originalOnRender) {
|
if (originalOnRender) {
|
||||||
originalOnRender.call(this);
|
originalOnRender.call(this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.prototype.onBeforeClose = function() {
|
this.prototype.onBeforeClose = function() {
|
||||||
if (this.model) {
|
if (this.model) {
|
||||||
Validation.unbind(this);
|
Validation.unbind(this);
|
||||||
|
|
||||||
|
//If we don't do this the next time the model is used the sync is bound to an old view
|
||||||
this.model.sync = this.model._originalSync;
|
this.model.sync = this.model._originalSync;
|
||||||
this.model._originalSync = undefined;
|
this.model._originalSync = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (originalBeforeClose) {
|
if (originalBeforeClose) {
|
||||||
originalBeforeClose.call(this);
|
originalBeforeClose.call(this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
}).call(this);
|
}).call(this);
|
|
@ -1,17 +1,19 @@
|
||||||
var $ = require('jquery');
|
var $ = require('jquery');
|
||||||
require('typeahead');
|
require('typeahead');
|
||||||
|
|
||||||
module.exports = (function(){
|
|
||||||
$.fn.autoComplete = function(options) {
|
$.fn.autoComplete = function(options) {
|
||||||
if (!options) {
|
if (!options) {
|
||||||
throw 'options are required';
|
throw 'options are required';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!options.resource) {
|
if (!options.resource) {
|
||||||
throw 'resource is required';
|
throw 'resource is required';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!options.query) {
|
if (!options.query) {
|
||||||
throw 'query is required';
|
throw 'query is required';
|
||||||
}
|
}
|
||||||
|
|
||||||
$(this).typeahead({
|
$(this).typeahead({
|
||||||
hint : true,
|
hint : true,
|
||||||
highlight : true,
|
highlight : true,
|
||||||
|
@ -31,14 +33,15 @@ module.exports = (function(){
|
||||||
success : function(response) {
|
success : function(response) {
|
||||||
if (options.filter) {
|
if (options.filter) {
|
||||||
options.filter.call(this, filter, response, callback);
|
options.filter.call(this, filter, response, callback);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
var matches = [];
|
var matches = [];
|
||||||
|
|
||||||
$.each(response, function(i, d) {
|
$.each(response, function(i, d) {
|
||||||
if (d[options.query] && d[options.property].startsWith(filter)) {
|
if (d[options.query] && d[options.property].startsWith(filter)) {
|
||||||
matches.push({ value : d[options.property] });
|
matches.push({ value : d[options.property] });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
callback(matches);
|
callback(matches);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,4 +49,3 @@ module.exports = (function(){
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}).call(this);
|
|
|
@ -1,21 +1,22 @@
|
||||||
var $ = require('jquery');
|
var $ = require('jquery');
|
||||||
require('./AutoComplete');
|
require('./AutoComplete');
|
||||||
|
|
||||||
module.exports = (function(){
|
|
||||||
$.fn.directoryAutoComplete = function() {
|
$.fn.directoryAutoComplete = function() {
|
||||||
var query = 'path';
|
var query = 'path';
|
||||||
|
|
||||||
$(this).autoComplete({
|
$(this).autoComplete({
|
||||||
resource : '/filesystem',
|
resource : '/filesystem',
|
||||||
query : query,
|
query : query,
|
||||||
filter : function(filter, response, callback) {
|
filter : function(filter, response, callback) {
|
||||||
var matches = [];
|
var matches = [];
|
||||||
|
|
||||||
$.each(response.directories, function(i, d) {
|
$.each(response.directories, function(i, d) {
|
||||||
if (d[query] && d[query].startsWith(filter)) {
|
if (d[query] && d[query].startsWith(filter)) {
|
||||||
matches.push({ value : d[query] });
|
matches.push({ value : d[query] });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
callback(matches);
|
callback(matches);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}).call(this);
|
|
|
@ -1,29 +1,31 @@
|
||||||
var $ = require('jquery');
|
var $ = require('jquery');
|
||||||
var vent = require('vent');
|
var vent = require('vent');
|
||||||
require('../Shared/FileBrowser/FileBrowserLayout');
|
require('../Shared/FileBrowser/FileBrowserLayout');
|
||||||
require('./DirectoryAutoComplete');
|
require('./DirectoryAutoComplete');
|
||||||
|
|
||||||
module.exports = (function(){
|
|
||||||
$.fn.fileBrowser = function(options) {
|
$.fn.fileBrowser = function(options) {
|
||||||
var inputs = $(this);
|
var inputs = $(this);
|
||||||
|
|
||||||
inputs.each(function() {
|
inputs.each(function() {
|
||||||
var input = $(this);
|
var input = $(this);
|
||||||
var inputOptions = $.extend({ input : input }, options);
|
var inputOptions = $.extend({ input : input }, options);
|
||||||
var inputGroup = $('<div class="input-group"></div>');
|
var inputGroup = $('<div class="input-group"></div>');
|
||||||
var inputGroupButton = $('<span class="input-group-btn "></span>');
|
var inputGroupButton = $('<span class="input-group-btn "></span>');
|
||||||
|
|
||||||
var button = $('<button class="btn btn-primary x-file-browser" title="Browse"><i class="icon-folder-open"/></button>');
|
var button = $('<button class="btn btn-primary x-file-browser" title="Browse"><i class="icon-folder-open"/></button>');
|
||||||
|
|
||||||
if (input.parent('.input-group').length > 0) {
|
if (input.parent('.input-group').length > 0) {
|
||||||
input.parent('.input-group').find('.input-group-btn').prepend(button);
|
input.parent('.input-group').find('.input-group-btn').prepend(button);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
inputGroupButton.append(button);
|
inputGroupButton.append(button);
|
||||||
input.wrap(inputGroup);
|
input.wrap(inputGroup);
|
||||||
input.after(inputGroupButton);
|
input.after(inputGroupButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
button.on('click', function() {
|
button.on('click', function() {
|
||||||
vent.trigger(vent.Commands.ShowFileBrowser, inputOptions);
|
vent.trigger(vent.Commands.ShowFileBrowser, inputOptions);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
inputs.directoryAutoComplete();
|
inputs.directoryAutoComplete();
|
||||||
};
|
};
|
||||||
}).call(this);
|
|
|
@ -4,50 +4,88 @@ var TagCollection = require('../Tags/TagCollection');
|
||||||
var TagModel = require('../Tags/TagModel');
|
var TagModel = require('../Tags/TagModel');
|
||||||
require('bootstrap.tagsinput');
|
require('bootstrap.tagsinput');
|
||||||
|
|
||||||
module.exports = (function(){
|
var substringMatcher = function() {
|
||||||
|
return function findMatches (q, cb) {
|
||||||
|
var matches = _.select(TagCollection.toJSON(), function(tag) {
|
||||||
|
return tag.label.toLowerCase().indexOf(q.toLowerCase()) > -1;
|
||||||
|
});
|
||||||
|
cb(matches);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
var getExistingTags = function(tagValues) {
|
||||||
|
return _.select(TagCollection.toJSON(), function(tag) {
|
||||||
|
return _.contains(tagValues, tag.id);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var testTag = function(item) {
|
||||||
|
var tagLimitations = new RegExp('[^-_a-z0-9]', 'i');
|
||||||
|
try {
|
||||||
|
return !tagLimitations.test(item);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var originalAdd = $.fn.tagsinput.Constructor.prototype.add;
|
var originalAdd = $.fn.tagsinput.Constructor.prototype.add;
|
||||||
var originalRemove = $.fn.tagsinput.Constructor.prototype.remove;
|
var originalRemove = $.fn.tagsinput.Constructor.prototype.remove;
|
||||||
var originalBuild = $.fn.tagsinput.Constructor.prototype.build;
|
var originalBuild = $.fn.tagsinput.Constructor.prototype.build;
|
||||||
|
|
||||||
$.fn.tagsinput.Constructor.prototype.add = function(item, dontPushVal) {
|
$.fn.tagsinput.Constructor.prototype.add = function(item, dontPushVal) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if (typeof item === 'string' && this.options.tag) {
|
if (typeof item === 'string' && this.options.tag) {
|
||||||
var test = testTag(item);
|
var test = testTag(item);
|
||||||
if (item === null || item === '' || !testTag(item)) {
|
if (item === null || item === '' || !testTag(item)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var existing = _.find(TagCollection.toJSON(), { label : item });
|
var existing = _.find(TagCollection.toJSON(), { label : item });
|
||||||
|
|
||||||
if (existing) {
|
if (existing) {
|
||||||
originalAdd.call(this, existing, dontPushVal);
|
originalAdd.call(this, existing, dontPushVal);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
var newTag = new TagModel();
|
var newTag = new TagModel();
|
||||||
newTag.set({ label : item.toLowerCase() });
|
newTag.set({ label : item.toLowerCase() });
|
||||||
TagCollection.add(newTag);
|
TagCollection.add(newTag);
|
||||||
|
|
||||||
newTag.save().done(function() {
|
newTag.save().done(function() {
|
||||||
item = newTag.toJSON();
|
item = newTag.toJSON();
|
||||||
originalAdd.call(self, item, dontPushVal);
|
originalAdd.call(self, item, dontPushVal);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
originalAdd.call(this, item, dontPushVal);
|
originalAdd.call(this, item, dontPushVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.options.tag) {
|
if (this.options.tag) {
|
||||||
self.$input.typeahead('val', '');
|
self.$input.typeahead('val', '');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$.fn.tagsinput.Constructor.prototype.remove = function(item, dontPushVal) {
|
$.fn.tagsinput.Constructor.prototype.remove = function(item, dontPushVal) {
|
||||||
if (item === null) {
|
if (item === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
originalRemove.call(this, item, dontPushVal);
|
originalRemove.call(this, item, dontPushVal);
|
||||||
};
|
};
|
||||||
|
|
||||||
$.fn.tagsinput.Constructor.prototype.build = function(options) {
|
$.fn.tagsinput.Constructor.prototype.build = function(options) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var defaults = {
|
var defaults = {
|
||||||
confirmKeys : [9, 13, 32, 44, 59]
|
confirmKeys : [
|
||||||
|
9,
|
||||||
|
13,
|
||||||
|
32,
|
||||||
|
44,
|
||||||
|
59
|
||||||
|
] //tab, enter, space, comma, semi-colon
|
||||||
};
|
};
|
||||||
|
|
||||||
options = $.extend({}, defaults, options);
|
options = $.extend({}, defaults, options);
|
||||||
|
|
||||||
self.$input.on('keydown', function(event) {
|
self.$input.on('keydown', function(event) {
|
||||||
if (event.which === 9) {
|
if (event.which === 9) {
|
||||||
var e = $.Event('keypress');
|
var e = $.Event('keypress');
|
||||||
|
@ -56,17 +94,21 @@ module.exports = (function(){
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
self.$input.on('focusout', function() {
|
self.$input.on('focusout', function() {
|
||||||
self.add(self.$input.val());
|
self.add(self.$input.val());
|
||||||
self.$input.val('');
|
self.$input.val('');
|
||||||
});
|
});
|
||||||
|
|
||||||
originalBuild.call(this, options);
|
originalBuild.call(this, options);
|
||||||
};
|
};
|
||||||
|
|
||||||
$.fn.tagInput = function(options) {
|
$.fn.tagInput = function(options) {
|
||||||
var input = this;
|
var input = this;
|
||||||
var model = options.model;
|
var model = options.model;
|
||||||
var property = options.property;
|
var property = options.property;
|
||||||
var tags = getExistingTags(model.get(property));
|
var tags = getExistingTags(model.get(property));
|
||||||
|
|
||||||
var tagInput = $(this).tagsinput({
|
var tagInput = $(this).tagsinput({
|
||||||
tag : true,
|
tag : true,
|
||||||
freeInput : true,
|
freeInput : true,
|
||||||
|
@ -79,7 +121,11 @@ module.exports = (function(){
|
||||||
source : substringMatcher()
|
source : substringMatcher()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//Override the free input being set to false because we're using objects
|
||||||
$(tagInput)[0].options.freeInput = true;
|
$(tagInput)[0].options.freeInput = true;
|
||||||
|
|
||||||
|
//Remove any existing tags and re-add them
|
||||||
$(this).tagsinput('removeAll');
|
$(this).tagsinput('removeAll');
|
||||||
_.each(tags, function(tag) {
|
_.each(tags, function(tag) {
|
||||||
$(input).tagsinput('add', tag);
|
$(input).tagsinput('add', tag);
|
||||||
|
@ -98,26 +144,3 @@ module.exports = (function(){
|
||||||
model.set(property, tags);
|
model.set(property, tags);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
var substringMatcher = function(){
|
|
||||||
return function findMatches (q, cb){
|
|
||||||
var matches = _.select(TagCollection.toJSON(), function(tag){
|
|
||||||
return tag.label.toLowerCase().indexOf(q.toLowerCase()) > -1;
|
|
||||||
});
|
|
||||||
cb(matches);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
var getExistingTags = function(tagValues){
|
|
||||||
return _.select(TagCollection.toJSON(), function(tag){
|
|
||||||
return _.contains(tagValues, tag.id);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
var testTag = function(item){
|
|
||||||
var tagLimitations = new RegExp('[^-_a-z0-9]', 'i');
|
|
||||||
try {
|
|
||||||
return !tagLimitations.test(item);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}).call(this);
|
|
|
@ -6,26 +6,36 @@ require('signalR');
|
||||||
|
|
||||||
module.exports = _.extend(Backbone.Collection.prototype, {
|
module.exports = _.extend(Backbone.Collection.prototype, {
|
||||||
bindSignalR : function(bindOptions) {
|
bindSignalR : function(bindOptions) {
|
||||||
|
|
||||||
var collection = this;
|
var collection = this;
|
||||||
bindOptions = bindOptions || {};
|
bindOptions = bindOptions || {};
|
||||||
|
|
||||||
var processMessage = function(options) {
|
var processMessage = function(options) {
|
||||||
if (options.action === 'sync') {
|
if (options.action === 'sync') {
|
||||||
console.log('sync received, re-fetching collection');
|
console.log('sync received, re-fetching collection');
|
||||||
collection.fetch();
|
collection.fetch();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.action === 'deleted') {
|
if (options.action === 'deleted') {
|
||||||
collection.remove(new collection.model(options.resource, { parse : true }));
|
collection.remove(new collection.model(options.resource, { parse : true }));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var model = new collection.model(options.resource, { parse : true });
|
var model = new collection.model(options.resource, { parse : true });
|
||||||
|
|
||||||
|
//updateOnly will prevent the collection from adding a new item
|
||||||
if (bindOptions.updateOnly && !collection.get(model.get('id'))) {
|
if (bindOptions.updateOnly && !collection.get(model.get('id'))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
collection.add(model, {
|
collection.add(model, {
|
||||||
merge : true,
|
merge : true,
|
||||||
changeSource : 'signalr'
|
changeSource : 'signalr'
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(options.action + ': {0}}'.format(options.resource));
|
console.log(options.action + ': {0}}'.format(options.resource));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,46 +2,64 @@ var Backbone = require('backbone');
|
||||||
var $ = require('jquery');
|
var $ = require('jquery');
|
||||||
var StatusModel = require('../System/StatusModel');
|
var StatusModel = require('../System/StatusModel');
|
||||||
|
|
||||||
|
//This module will automatically route all relative links through backbone router rather than
|
||||||
|
//causing links to reload pages.
|
||||||
|
|
||||||
var routeBinder = {
|
var routeBinder = {
|
||||||
|
|
||||||
bind : function() {
|
bind : function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
$(document).on('click', 'a[href]', function(event) {
|
$(document).on('click', 'a[href]', function(event) {
|
||||||
self._handleClick(event);
|
self._handleClick(event);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_handleClick : function(event) {
|
_handleClick : function(event) {
|
||||||
var $target = $(event.target);
|
var $target = $(event.target);
|
||||||
|
|
||||||
|
//check if tab nav
|
||||||
if ($target.parents('.nav-tabs').length) {
|
if ($target.parents('.nav-tabs').length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($target.hasClass('no-router')) {
|
if ($target.hasClass('no-router')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var href = event.target.getAttribute('href');
|
var href = event.target.getAttribute('href');
|
||||||
|
|
||||||
if (!href && $target.closest('a') && $target.closest('a')[0]) {
|
if (!href && $target.closest('a') && $target.closest('a')[0]) {
|
||||||
|
|
||||||
var linkElement = $target.closest('a')[0];
|
var linkElement = $target.closest('a')[0];
|
||||||
|
|
||||||
if ($(linkElement).hasClass('no-router')) {
|
if ($(linkElement).hasClass('no-router')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
href = linkElement.getAttribute('href');
|
href = linkElement.getAttribute('href');
|
||||||
}
|
}
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
if (!href) {
|
if (!href) {
|
||||||
throw 'couldn\'t find route target';
|
throw 'couldn\'t find route target';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!href.startsWith('http')) {
|
if (!href.startsWith('http')) {
|
||||||
if (event.ctrlKey) {
|
if (event.ctrlKey) {
|
||||||
window.open(href, '_blank');
|
window.open(href, '_blank');
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
var relativeHref = href.replace(StatusModel.get('urlBase'), '');
|
var relativeHref = href.replace(StatusModel.get('urlBase'), '');
|
||||||
|
|
||||||
Backbone.history.navigate(relativeHref, { trigger : true });
|
Backbone.history.navigate(relativeHref, { trigger : true });
|
||||||
}
|
}
|
||||||
}
|
} else if (href.contains('#')) {
|
||||||
else if(href.contains('#')) {
|
//Open in new tab without dereferer (since it doesn't support fragments)
|
||||||
window.open(href, '_blank');
|
window.open(href, '_blank');
|
||||||
}
|
} else {
|
||||||
else {
|
//Open in new tab
|
||||||
window.open('http://www.dereferer.org/?' + encodeURI(href), '_blank');
|
window.open('http://www.dereferer.org/?' + encodeURI(href), '_blank');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
var $ = require('jquery');
|
var $ = require('jquery');
|
||||||
var _ = require('underscore');
|
var _ = require('underscore');
|
||||||
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
var _window = $(window);
|
var _window = $(window);
|
||||||
var _scrollButton = $('#scroll-up');
|
var _scrollButton = $('#scroll-up');
|
||||||
|
@ -9,8 +8,7 @@ $(document).ready(function(){
|
||||||
var _scrollHandler = function() {
|
var _scrollHandler = function() {
|
||||||
if (_window.scrollTop() > 100) {
|
if (_window.scrollTop() > 100) {
|
||||||
_scrollButton.fadeIn();
|
_scrollButton.fadeIn();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
_scrollButton.fadeOut();
|
_scrollButton.fadeOut();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,8 +8,7 @@ module.exports = function(){
|
||||||
if (xhr && xhr.data && xhr.type === 'DELETE') {
|
if (xhr && xhr.data && xhr.type === 'DELETE') {
|
||||||
if (xhr.url.contains('?')) {
|
if (xhr.url.contains('?')) {
|
||||||
xhr.url += '&';
|
xhr.url += '&';
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
xhr.url += '?';
|
xhr.url += '?';
|
||||||
}
|
}
|
||||||
xhr.url += $.param(xhr.data);
|
xhr.url += $.param(xhr.data);
|
||||||
|
|
|
@ -5,43 +5,56 @@ module.exports = function(){
|
||||||
|
|
||||||
$.fn.spinForPromise = function(promise) {
|
$.fn.spinForPromise = function(promise) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if (!promise || promise.state() !== 'pending') {
|
if (!promise || promise.state() !== 'pending') {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
promise.always(function() {
|
promise.always(function() {
|
||||||
self.stopSpin();
|
self.stopSpin();
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.startSpin();
|
return this.startSpin();
|
||||||
};
|
};
|
||||||
|
|
||||||
$.fn.startSpin = function() {
|
$.fn.startSpin = function() {
|
||||||
var icon = this.find('i').andSelf('i');
|
var icon = this.find('i').andSelf('i');
|
||||||
|
|
||||||
if (!icon || !icon.attr('class')) {
|
if (!icon || !icon.attr('class')) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
var iconClasses = icon.attr('class').match(/(?:^|\s)icon\-.+?(?:$|\s)/);
|
var iconClasses = icon.attr('class').match(/(?:^|\s)icon\-.+?(?:$|\s)/);
|
||||||
|
|
||||||
if (iconClasses.length === 0) {
|
if (iconClasses.length === 0) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
var iconClass = $.trim(iconClasses[0]);
|
var iconClass = $.trim(iconClasses[0]);
|
||||||
|
|
||||||
this.addClass('disabled');
|
this.addClass('disabled');
|
||||||
|
|
||||||
if (icon.hasClass('icon-can-spin')) {
|
if (icon.hasClass('icon-can-spin')) {
|
||||||
icon.addClass('icon-spin');
|
icon.addClass('icon-spin');
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
icon.attr('data-idle-icon', iconClass);
|
icon.attr('data-idle-icon', iconClass);
|
||||||
icon.removeClass(iconClass);
|
icon.removeClass(iconClass);
|
||||||
icon.addClass('icon-nd-spinner');
|
icon.addClass('icon-nd-spinner');
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
$.fn.stopSpin = function() {
|
$.fn.stopSpin = function() {
|
||||||
var icon = this.find('i').andSelf('i');
|
var icon = this.find('i').andSelf('i');
|
||||||
|
|
||||||
this.removeClass('disabled');
|
this.removeClass('disabled');
|
||||||
icon.removeClass('icon-spin icon-nd-spinner');
|
icon.removeClass('icon-spin icon-nd-spinner');
|
||||||
var idleIcon = icon.attr('data-idle-icon');
|
var idleIcon = icon.attr('data-idle-icon');
|
||||||
|
|
||||||
if (idleIcon) {
|
if (idleIcon) {
|
||||||
icon.addClass(idleIcon);
|
icon.addClass(idleIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
};
|
};
|
|
@ -3,52 +3,71 @@ module.exports = function(){
|
||||||
var $ = this;
|
var $ = this;
|
||||||
$.fn.processServerError = function(error) {
|
$.fn.processServerError = function(error) {
|
||||||
var validationName = error.propertyName.toLowerCase();
|
var validationName = error.propertyName.toLowerCase();
|
||||||
|
|
||||||
var errorMessage = this.formatErrorMessage(error);
|
var errorMessage = this.formatErrorMessage(error);
|
||||||
|
|
||||||
this.find('.validation-errors').addClass('alert alert-danger').append('<div><i class="icon-exclamation-sign"></i>' + errorMessage + '</div>');
|
this.find('.validation-errors').addClass('alert alert-danger').append('<div><i class="icon-exclamation-sign"></i>' + errorMessage + '</div>');
|
||||||
|
|
||||||
if (!validationName || validationName === '') {
|
if (!validationName || validationName === '') {
|
||||||
this.addFormError(error);
|
this.addFormError(error);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
var input = this.find('[name]').filter(function() {
|
var input = this.find('[name]').filter(function() {
|
||||||
return this.name.toLowerCase() === validationName;
|
return this.name.toLowerCase() === validationName;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (input.length === 0) {
|
if (input.length === 0) {
|
||||||
input = this.find('[validation-name]').filter(function() {
|
input = this.find('[validation-name]').filter(function() {
|
||||||
return $(this).attr('validation-name').toLowerCase() === validationName;
|
return $(this).attr('validation-name').toLowerCase() === validationName;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//still not found?
|
||||||
if (input.length === 0) {
|
if (input.length === 0) {
|
||||||
this.addFormError(error);
|
this.addFormError(error);
|
||||||
console.error('couldn\'t find input for ' + error.propertyName);
|
console.error('couldn\'t find input for ' + error.propertyName);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var formGroup = input.parents('.form-group');
|
var formGroup = input.parents('.form-group');
|
||||||
|
|
||||||
if (formGroup.length === 0) {
|
if (formGroup.length === 0) {
|
||||||
formGroup = input.parent();
|
formGroup = input.parent();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
var inputGroup = formGroup.find('.input-group');
|
var inputGroup = formGroup.find('.input-group');
|
||||||
|
|
||||||
if (inputGroup.length === 0) {
|
if (inputGroup.length === 0) {
|
||||||
formGroup.append('<span class="help-inline validation-error">' + errorMessage + '</span>');
|
formGroup.append('<span class="help-inline validation-error">' + errorMessage + '</span>');
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
inputGroup.parent().append('<span class="help-block validation-error">' + errorMessage + '</span>');
|
inputGroup.parent().append('<span class="help-block validation-error">' + errorMessage + '</span>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
formGroup.addClass('has-error');
|
formGroup.addClass('has-error');
|
||||||
|
|
||||||
return formGroup.find('.help-inline').text();
|
return formGroup.find('.help-inline').text();
|
||||||
};
|
};
|
||||||
|
|
||||||
$.fn.processClientError = function(error) {
|
$.fn.processClientError = function(error) {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$.fn.addFormError = function(error) {
|
$.fn.addFormError = function(error) {
|
||||||
|
|
||||||
var errorMessage = this.formatErrorMessage(error);
|
var errorMessage = this.formatErrorMessage(error);
|
||||||
|
|
||||||
if (this.find('.modal-body')) {
|
if (this.find('.modal-body')) {
|
||||||
this.find('.modal-body').prepend('<div class="alert alert-danger validation-error">' + errorMessage + '</div>');
|
this.find('.modal-body').prepend('<div class="alert alert-danger validation-error">' + errorMessage + '</div>');
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
this.prepend('<div class="alert alert-danger validation-error">' + errorMessage + '</div>');
|
this.prepend('<div class="alert alert-danger validation-error">' + errorMessage + '</div>');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$.fn.removeAllErrors = function() {
|
$.fn.removeAllErrors = function() {
|
||||||
this.find('.has-error').removeClass('has-error');
|
this.find('.has-error').removeClass('has-error');
|
||||||
this.find('.error').removeClass('error');
|
this.find('.error').removeClass('error');
|
||||||
|
@ -56,19 +75,21 @@ module.exports = function(){
|
||||||
this.find('.validation-error').remove();
|
this.find('.validation-error').remove();
|
||||||
return this.find('.help-inline.error-message').remove();
|
return this.find('.help-inline.error-message').remove();
|
||||||
};
|
};
|
||||||
|
|
||||||
$.fn.formatErrorMessage = function(error) {
|
$.fn.formatErrorMessage = function(error) {
|
||||||
|
|
||||||
var errorMessage = error.errorMessage;
|
var errorMessage = error.errorMessage;
|
||||||
|
|
||||||
if (error.infoLink) {
|
if (error.infoLink) {
|
||||||
if (error.detailedDescription) {
|
if (error.detailedDescription) {
|
||||||
errorMessage += ' <a class="no-router" target="_blank" href="' + error.infoLink + '"><i class="icon-external-link" title="' + error.detailedDescription + '"></i></a>';
|
errorMessage += ' <a class="no-router" target="_blank" href="' + error.infoLink + '"><i class="icon-external-link" title="' + error.detailedDescription + '"></i></a>';
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
errorMessage += ' <a class="no-router" target="_blank" href="' + error.infoLink + '"><i class="icon-external-link"></i></a>';
|
errorMessage += ' <a class="no-router" target="_blank" href="' + error.infoLink + '"><i class="icon-external-link"></i></a>';
|
||||||
}
|
}
|
||||||
}
|
} else if (error.detailedDescription) {
|
||||||
else if(error.detailedDescription) {
|
|
||||||
errorMessage += ' <i class="icon-nd-form-info" title="' + error.detailedDescription + '"></i>';
|
errorMessage += ' <i class="icon-nd-form-info" title="' + error.detailedDescription + '"></i>';
|
||||||
}
|
}
|
||||||
|
|
||||||
return errorMessage;
|
return errorMessage;
|
||||||
};
|
};
|
||||||
};
|
};
|
Loading…
Reference in New Issue