summaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
Diffstat (limited to 'module')
-rw-r--r--module/PluginManager.py2
-rw-r--r--module/api/ConfigApi.py5
-rw-r--r--module/web/static/css/default/settings.less28
-rwxr-xr-x[-rw-r--r--]module/web/static/css/select2.css58
-rwxr-xr-xmodule/web/static/img/select2-spinner.gifbin0 -> 1849 bytes
-rwxr-xr-xmodule/web/static/img/select2.pngbin0 -> 613 bytes
-rwxr-xr-xmodule/web/static/img/select2x2.pngbin0 -> 845 bytes
-rw-r--r--module/web/static/js/config.js2
-rw-r--r--module/web/static/js/default.js2
-rwxr-xr-x[-rw-r--r--]module/web/static/js/libs/select2-3.3.2.js (renamed from module/web/static/js/libs/select2-3.3.1.js)199
-rw-r--r--module/web/static/js/views/abstract/modalView.js2
-rw-r--r--module/web/static/js/views/dashboard/fileView.js6
-rw-r--r--module/web/static/js/views/settings/configSectionView.js (renamed from module/web/static/js/views/configSectionView.js)2
-rw-r--r--module/web/static/js/views/settings/pluginChooserModal.js66
-rw-r--r--module/web/static/js/views/settings/settingsView.js (renamed from module/web/static/js/views/settingsView.js)29
-rwxr-xr-xmodule/web/templates/default/backbone/pluginChooserDialog.html23
-rw-r--r--module/web/templates/default/settings.html6
17 files changed, 327 insertions, 103 deletions
diff --git a/module/PluginManager.py b/module/PluginManager.py
index dac857059..ea4b7cdb3 100644
--- a/module/PluginManager.py
+++ b/module/PluginManager.py
@@ -392,7 +392,7 @@ class PluginManager:
def getCategory(self, plugin):
if plugin in self.plugins["addons"]:
- return self.plugins["addons"][plugin] or "addon"
+ return self.plugins["addons"][plugin].category or "addon"
def loadIcon(self, name):
""" load icon for single plugin, base64 encoded"""
diff --git a/module/api/ConfigApi.py b/module/api/ConfigApi.py
index 309400808..d5577f7c3 100644
--- a/module/api/ConfigApi.py
+++ b/module/api/ConfigApi.py
@@ -83,11 +83,14 @@ class ConfigApi(ApiComponent):
:rtype: list of PluginInfo
"""
# TODO: filter user_context / addons when not allowed
- return [ConfigInfo(name, config.name, config.description,
+ plugins = [ConfigInfo(name, config.name, config.description,
self.core.pluginManager.getCategory(name),
self.core.pluginManager.isUserPlugin(name))
for name, config, values in self.core.config.iterSections(self.user)]
+
+ return plugins
+
@RequirePerm(Permission.Plugins)
def loadConfig(self, name):
"""Get complete config options for desired section
diff --git a/module/web/static/css/default/settings.less b/module/web/static/css/default/settings.less
index 2501e2d0d..44eeddc5f 100644
--- a/module/web/static/css/default/settings.less
+++ b/module/web/static/css/default/settings.less
@@ -61,4 +61,32 @@
padding-left: 200px;
}
+}
+
+/*
+ Plugin select
+*/
+
+.plugin-select {
+ background-position: left 2px;
+ background-repeat: no-repeat;
+ background-size: 20px 20px;
+ padding-left: 24px;
+
+ font-weight: bold;
+ span {
+ line-height: 14px;
+ font-size: small;
+ font-weight: normal;
+ }
+
+}
+
+.logo-select {
+ width: 20px;
+ height: 20px;
+}
+
+.select2-container {
+ min-width: 206px; // same as other input fields
} \ No newline at end of file
diff --git a/module/web/static/css/select2.css b/module/web/static/css/select2.css
index 1ff2abb1b..6cd945dbc 100644..100755
--- a/module/web/static/css/select2.css
+++ b/module/web/static/css/select2.css
@@ -1,5 +1,5 @@
/*
-Version: 3.3.1 Timestamp: Wed Feb 20 09:57:22 PST 2013
+Version: 3.3.2 Timestamp: Mon Mar 25 12:14:18 PDT 2013
*/
.select2-container {
position: relative;
@@ -7,7 +7,7 @@ Version: 3.3.1 Timestamp: Wed Feb 20 09:57:22 PST 2013
/* inline-block for ie7 */
zoom: 1;
*display: inline;
- vertical-align: top;
+ vertical-align: middle;
}
.select2-container,
@@ -105,7 +105,7 @@ Version: 3.3.1 Timestamp: Wed Feb 20 09:57:22 PST 2013
text-decoration: none;
border: 0;
- background: url('select2.png') right top no-repeat;
+ background: url('../img/select2.png') right top no-repeat;
cursor: pointer;
outline: 0;
}
@@ -119,7 +119,11 @@ Version: 3.3.1 Timestamp: Wed Feb 20 09:57:22 PST 2013
left: 0;
top: 0;
z-index: 9998;
+ background-color: #fff;
opacity: 0;
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; /* works in IE 8 */
+ filter: "alpha(opacity=0)"; /* expected to work in IE 8 */
+ filter: alpha(opacity=0); /* IE 4-7 */
}
.select2-drop {
@@ -188,7 +192,7 @@ Version: 3.3.1 Timestamp: Wed Feb 20 09:57:22 PST 2013
display: block;
width: 100%;
height: 100%;
- background: url('select2.png') no-repeat 0 1px;
+ background: url('../img/select2.png') no-repeat 0 1px;
}
.select2-search {
@@ -231,13 +235,13 @@ Version: 3.3.1 Timestamp: Wed Feb 20 09:57:22 PST 2013
-moz-box-shadow: none;
box-shadow: none;
- background: #fff url('select2.png') no-repeat 100% -22px;
- background: url('select2.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));
- background: url('select2.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);
- background: url('select2.png') no-repeat 100% -22px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%);
- background: url('select2.png') no-repeat 100% -22px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%);
- background: url('select2.png') no-repeat 100% -22px, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%);
- background: url('select2.png') no-repeat 100% -22px, linear-gradient(top, #ffffff 85%, #eeeeee 99%);
+ background: #fff url('../img/select2.png') no-repeat 100% -22px;
+ background: url('../img/select2.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));
+ background: url('../img/select2.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);
+ background: url('../img/select2.png') no-repeat 100% -22px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%);
+ background: url('../img/select2.png') no-repeat 100% -22px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%);
+ background: url('../img/select2.png') no-repeat 100% -22px, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%);
+ background: url('../img/select2.png') no-repeat 100% -22px, linear-gradient(top, #ffffff 85%, #eeeeee 99%);
}
.select2-drop.select2-drop-above .select2-search input {
@@ -245,13 +249,13 @@ Version: 3.3.1 Timestamp: Wed Feb 20 09:57:22 PST 2013
}
.select2-search input.select2-active {
- background: #fff url('select2-spinner.gif') no-repeat 100%;
- background: url('select2-spinner.gif') no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));
- background: url('select2-spinner.gif') no-repeat 100%, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);
- background: url('select2-spinner.gif') no-repeat 100%, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%);
- background: url('select2-spinner.gif') no-repeat 100%, -o-linear-gradient(bottom, white 85%, #eeeeee 99%);
- background: url('select2-spinner.gif') no-repeat 100%, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%);
- background: url('select2-spinner.gif') no-repeat 100%, linear-gradient(top, #ffffff 85%, #eeeeee 99%);
+ background: #fff url('../img/select2-spinner.gif') no-repeat 100%;
+ background: url('../img/select2-spinner.gif') no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));
+ background: url('../img/select2-spinner.gif') no-repeat 100%, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);
+ background: url('../img/select2-spinner.gif') no-repeat 100%, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%);
+ background: url('../img/select2-spinner.gif') no-repeat 100%, -o-linear-gradient(bottom, white 85%, #eeeeee 99%);
+ background: url('../img/select2-spinner.gif') no-repeat 100%, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%);
+ background: url('../img/select2-spinner.gif') no-repeat 100%, linear-gradient(top, #ffffff 85%, #eeeeee 99%);
}
.select2-container-active .select2-choice,
@@ -335,6 +339,8 @@ Version: 3.3.1 Timestamp: Wed Feb 20 09:57:22 PST 2013
margin: 0;
cursor: pointer;
+ min-height: 1em;
+
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
@@ -390,7 +396,7 @@ disabled look for disabled choices in the results dropdown
}
.select2-more-results.select2-active {
- background: #f4f4f4 url('select2-spinner.gif') no-repeat 100%;
+ background: #f4f4f4 url('../img/select2-spinner.gif') no-repeat 100%;
}
.select2-more-results {
@@ -482,7 +488,7 @@ disabled look for disabled choices in the results dropdown
}
.select2-container-multi .select2-choices .select2-search-field input.select2-active {
- background: #fff url('select2-spinner.gif') no-repeat 100% !important;
+ background: #fff url('../img/select2-spinner.gif') no-repeat 100% !important;
}
.select2-default {
@@ -544,7 +550,7 @@ disabled look for disabled choices in the results dropdown
font-size: 1px;
outline: none;
- background: url('select2.png') right top no-repeat;
+ background: url('../img/select2.png') right top no-repeat;
}
.select2-container-multi .select2-search-choice-close {
@@ -585,15 +591,21 @@ disabled look for disabled choices in the results dropdown
}
.select2-offscreen {
+ border: 0;
+ clip: rect(0 0 0 0);
+ height: 1px;
+ margin: -1px;
+ overflow: hidden;
+ padding: 0;
position: absolute;
- left: -10000px;
+ width: 1px;
}
/* Retina-ize icons */
@media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-resolution: 144dpi) {
.select2-search input, .select2-search-choice-close, .select2-container .select2-choice abbr, .select2-container .select2-choice div b {
- background-image: url('select2x2.png') !important;
+ background-image: url('../img/select2x2.png') !important;
background-repeat: no-repeat !important;
background-size: 60px 40px !important;
}
diff --git a/module/web/static/img/select2-spinner.gif b/module/web/static/img/select2-spinner.gif
new file mode 100755
index 000000000..5b33f7e54
--- /dev/null
+++ b/module/web/static/img/select2-spinner.gif
Binary files differ
diff --git a/module/web/static/img/select2.png b/module/web/static/img/select2.png
new file mode 100755
index 000000000..1d804ffb9
--- /dev/null
+++ b/module/web/static/img/select2.png
Binary files differ
diff --git a/module/web/static/img/select2x2.png b/module/web/static/img/select2x2.png
new file mode 100755
index 000000000..4bdd5c961
--- /dev/null
+++ b/module/web/static/img/select2x2.png
Binary files differ
diff --git a/module/web/static/js/config.js b/module/web/static/js/config.js
index 474a77dc3..d920698c4 100644
--- a/module/web/static/js/config.js
+++ b/module/web/static/js/config.js
@@ -10,7 +10,7 @@ require.config({
transit: "libs/jquery.transit-0.9.9",
animate: "libs/jquery.animate-enhanced-0.99",
omniwindow: "libs/jquery.omniwindow",
- select2: "libs/select2-3.3.1",
+ select2: "libs/select2-3.3.2",
bootstrap: "libs/bootstrap-2.3",
underscore: "libs/lodash-1.0.1",
diff --git a/module/web/static/js/default.js b/module/web/static/js/default.js
index 44c8842fa..62b2ef9b6 100644
--- a/module/web/static/js/default.js
+++ b/module/web/static/js/default.js
@@ -14,7 +14,7 @@ define('default', ['require', 'jquery', 'app', 'views/headerView', 'views/dashbo
};
App.initSettingsView = function() {
- require(['views/settingsView'], function(SettingsView) {
+ require(['views/settings/settingsView'], function(SettingsView) {
App.settingsView = new SettingsView();
App.settingsView.render();
});
diff --git a/module/web/static/js/libs/select2-3.3.1.js b/module/web/static/js/libs/select2-3.3.2.js
index 8be2c7e9f..093d7fbd7 100644..100755
--- a/module/web/static/js/libs/select2-3.3.1.js
+++ b/module/web/static/js/libs/select2-3.3.2.js
@@ -1,7 +1,7 @@
/*
Copyright 2012 Igor Vaynberg
-Version: 3.3.1 Timestamp: Wed Feb 20 09:57:22 PST 2013
+Version: 3.3.2 Timestamp: Mon Mar 25 12:14:18 PDT 2013
This software is licensed under the Apache License, Version 2.0 (the "Apache License") or the GNU
General Public License version 2 (the "GPL License"). You may choose either license to govern your
@@ -118,8 +118,8 @@ the specific language governing permissions and limitations under the Apache Lic
if (a === b) return true;
if (a === undefined || b === undefined) return false;
if (a === null || b === null) return false;
- if (a.constructor === String) return a === b+'';
- if (b.constructor === String) return b === a+'';
+ if (a.constructor === String) return a+'' === b+''; // IE requires a+'' instead of just a
+ if (b.constructor === String) return b+'' === a+''; // IE requires b+'' instead of just b
return false;
}
@@ -229,20 +229,22 @@ the specific language governing permissions and limitations under the Apache Lic
$el.focus();
- /* after the focus is set move the caret to the end, necessary when we val()
- just before setting focus */
- if(el.setSelectionRange)
- {
- el.setSelectionRange(pos, pos);
- }
- else if (el.createTextRange) {
- range = el.createTextRange();
- range.collapse(true);
- range.moveEnd('character', pos);
- range.moveStart('character', pos);
- range.select();
- }
+ /* make sure el received focus so we do not error out when trying to manipulate the caret.
+ sometimes modals or others listeners may steal it after its set */
+ if ($el.is(":visible") && el === document.activeElement) {
+ /* after the focus is set move the caret to the end, necessary when we val()
+ just before setting focus */
+ if(el.setSelectionRange)
+ {
+ el.setSelectionRange(pos, pos);
+ }
+ else if (el.createTextRange) {
+ range = el.createTextRange();
+ range.collapse(false);
+ range.select();
+ }
+ }
}, 0);
}
@@ -282,7 +284,8 @@ the specific language governing permissions and limitations under the Apache Lic
var classes, replacements = [], adapted;
classes = dest.attr("class");
- if (typeof classes === "string") {
+ if (classes) {
+ classes = '' + classes; // for IE which returns object
$(classes.split(" ")).each2(function() {
if (this.indexOf("select2-") === 0) {
replacements.push(this);
@@ -290,11 +293,12 @@ the specific language governing permissions and limitations under the Apache Lic
});
}
classes = src.attr("class");
- if (typeof classes === "string") {
+ if (classes) {
+ classes = '' + classes; // for IE which returns object
$(classes.split(" ")).each2(function() {
if (this.indexOf("select2-") !== 0) {
adapted = adapter(this);
- if (typeof adapted === "string" && adapted.length > 0) {
+ if (adapted) {
replacements.push(this);
}
}
@@ -790,7 +794,7 @@ the specific language governing permissions and limitations under the Apache Lic
if ("tags" in opts) {
throw "tags specified as both an attribute 'data-select2-tags' and in options of Select2 " + opts.element.attr("id");
}
- opts.tags=opts.element.attr("data-select2-tags");
+ opts.tags=opts.element.data("select2Tags");
}
if (select) {
@@ -1119,9 +1123,7 @@ the specific language governing permissions and limitations under the Apache Lic
this.dropdown.attr("id", "select2-drop");
// show the elements
- mask.css({
- width: document.documentElement.scrollWidth,
- height: document.documentElement.scrollHeight});
+ mask.css(_makeMaskCss());
mask.show();
this.dropdown.show();
this.positionDropdown();
@@ -1134,14 +1136,19 @@ the specific language governing permissions and limitations under the Apache Lic
var that = this;
this.container.parents().add(window).each(function () {
$(this).bind(resize+" "+scroll+" "+orient, function (e) {
- $("#select2-drop-mask").css({
- width:document.documentElement.scrollWidth,
- height:document.documentElement.scrollHeight});
+ $("#select2-drop-mask").css(_makeMaskCss());
that.positionDropdown();
});
});
this.focusSearch();
+
+ function _makeMaskCss() {
+ return {
+ width : Math.max(document.documentElement.scrollWidth, $(window).width()),
+ height : Math.max(document.documentElement.scrollHeight, $(window).height())
+ }
+ }
},
// abstract
@@ -1164,7 +1171,7 @@ the specific language governing permissions and limitations under the Apache Lic
this.container.removeClass("select2-dropdown-open");
this.results.empty();
this.clearSearch();
-
+ this.search.removeClass("select2-active");
this.opts.element.trigger($.Event("close"));
},
@@ -1315,6 +1322,7 @@ the specific language governing permissions and limitations under the Apache Lic
self.opts.populateResults.call(this, results, data.results, {term: term, page: page, context:context});
+ self.postprocessResults(data, false, false);
if (data.more===true) {
more.detach().appendTo(results).text(self.opts.formatLoadMore(page+1));
@@ -1341,15 +1349,25 @@ the specific language governing permissions and limitations under the Apache Lic
*/
// abstract
updateResults: function (initial) {
- var search = this.search, results = this.results, opts = this.opts, data, self=this, input;
+ var search = this.search,
+ results = this.results,
+ opts = this.opts,
+ data,
+ self = this,
+ input,
+ term = search.val(),
+ lastTerm=$.data(this.container, "select2-last-term");
+
+ // prevent duplicate queries against the same term
+ if (initial !== true && lastTerm && equal(term, lastTerm)) return;
+
+ $.data(this.container, "select2-last-term", term);
// if the search is currently hidden we do not alter the results
if (initial !== true && (this.showSearchInput === false || !this.opened())) {
return;
}
- search.addClass("select2-active");
-
function postRender() {
results.scrollTop(0);
search.removeClass("select2-active");
@@ -1378,9 +1396,6 @@ the specific language governing permissions and limitations under the Apache Lic
}
return;
}
- else if (opts.formatSearching() && initial===true) {
- render("<li class='select2-searching'>" + opts.formatSearching() + "</li>");
- }
if (opts.maximumInputLength && search.val().length > opts.maximumInputLength) {
if (checkFormatter(opts.formatInputTooLong, "formatInputTooLong")) {
@@ -1391,6 +1406,12 @@ the specific language governing permissions and limitations under the Apache Lic
return;
}
+ if (opts.formatSearching && this.findHighlightableChoices().length === 0) {
+ render("<li class='select2-searching'>" + opts.formatSearching() + "</li>");
+ }
+
+ search.addClass("select2-active");
+
// give the tokenizer a chance to pre-process the input
input = this.tokenize();
if (input != undefined && input != null) {
@@ -1409,7 +1430,10 @@ the specific language governing permissions and limitations under the Apache Lic
var def; // default choice
// ignore a response if the select2 has been closed before it was received
- if (!this.opened()) return;
+ if (!this.opened()) {
+ this.search.removeClass("select2-active");
+ return;
+ }
// save context, if any
this.context = (data.context===undefined) ? null : data.context;
@@ -1442,6 +1466,8 @@ the specific language governing permissions and limitations under the Apache Lic
this.postprocessResults(data, initial);
postRender();
+
+ this.opts.element.trigger({ type: "loaded", data:data });
})});
},
@@ -1635,6 +1661,11 @@ the specific language governing permissions and limitations under the Apache Lic
this.focusser = container.find(".select2-focusser");
+ // rewrite labels from original element to focusser
+ this.focusser.attr("id", "s2id_autogen"+nextUid());
+ $("label[for='" + this.opts.element.attr("id") + "']")
+ .attr('for', this.focusser.attr('id'));
+
this.search.bind("keydown", this.bind(function (e) {
if (!this.enabled) return;
@@ -1662,6 +1693,16 @@ the specific language governing permissions and limitations under the Apache Lic
}
}));
+ this.search.bind("blur", this.bind(function(e) {
+ // a workaround for chrome to keep the search field focussed when the scroll bar is used to scroll the dropdown.
+ // without this the search field loses focus which is annoying
+ if (document.activeElement === this.body().get(0)) {
+ window.setTimeout(this.bind(function() {
+ this.search.focus();
+ }), 0);
+ }
+ }));
+
this.focusser.bind("keydown", this.bind(function (e) {
if (!this.enabled) return;
@@ -1747,15 +1788,19 @@ the specific language governing permissions and limitations under the Apache Lic
},
// single
- clear: function() {
+ clear: function(triggerChange) {
var data=this.selection.data("select2-data");
- this.opts.element.val("");
- this.selection.find("span").empty();
- this.selection.removeData("select2-data");
- this.setPlaceholder();
+ if (data) { // guard against queued quick consecutive clicks
+ this.opts.element.val("");
+ this.selection.find("span").empty();
+ this.selection.removeData("select2-data");
+ this.setPlaceholder();
- this.opts.element.trigger({ type: "removed", val: this.id(data), choice: data });
- this.triggerChange({removed:data});
+ if (triggerChange !== false){
+ this.opts.element.trigger({ type: "removed", val: this.id(data), choice: data });
+ this.triggerChange({removed:data});
+ }
+ }
},
/**
@@ -1795,13 +1840,18 @@ the specific language governing permissions and limitations under the Apache Lic
// install default initSelection when applied to hidden input and data is local
opts.initSelection = opts.initSelection || function (element, callback) {
var id = element.val();
- //search in data by id
+ //search in data by id, storing the actual matching item
+ var match = null;
opts.query({
matcher: function(term, text, el){
- return equal(id, opts.id(el));
+ var is_match = equal(id, opts.id(el));
+ if (is_match) {
+ match = el;
+ }
+ return is_match;
},
- callback: !$.isFunction(callback) ? $.noop : function(filtered) {
- callback(filtered.results.length ? filtered.results[0] : null);
+ callback: !$.isFunction(callback) ? $.noop : function() {
+ callback(match);
}
});
};
@@ -1840,7 +1890,7 @@ the specific language governing permissions and limitations under the Apache Lic
},
// single
- postprocessResults: function (data, initial) {
+ postprocessResults: function (data, initial, noHighlightUpdate) {
var selected = 0, self = this, showSearchInput = true;
// find the selected element in the result list
@@ -1853,8 +1903,9 @@ the specific language governing permissions and limitations under the Apache Lic
});
// and highlight it
-
- this.highlight(selected);
+ if (noHighlightUpdate !== false) {
+ this.highlight(selected);
+ }
// hide the search box if this is the first we got the results and there are a few of them
@@ -1930,7 +1981,7 @@ the specific language governing permissions and limitations under the Apache Lic
this.select
.val(val)
.find(":selected").each2(function (i, elm) {
- data = {id: elm.attr("value"), text: elm.text()};
+ data = {id: elm.attr("value"), text: elm.text(), element: elm.get(0)};
return false;
});
this.updateSelection(data);
@@ -1944,7 +1995,7 @@ the specific language governing permissions and limitations under the Apache Lic
}
// val is an id. !val is true for [undefined,null,'',0] - 0 is legal
if (!val && val !== 0) {
- this.clear();
+ this.clear(triggerChange);
if (triggerChange) {
this.triggerChange();
}
@@ -2028,15 +2079,20 @@ the specific language governing permissions and limitations under the Apache Lic
// install default initSelection when applied to hidden input and data is local
opts.initSelection = opts.initSelection || function (element, callback) {
var ids = splitVal(element.val(), opts.separator);
- //search in data by array of ids
+ //search in data by array of ids, storing matching items in a list
+ var matches = [];
opts.query({
matcher: function(term, text, el){
- return $.grep(ids, function(id) {
+ var is_match = $.grep(ids, function(id) {
return equal(id, opts.id(el));
}).length;
+ if (is_match) {
+ matches.push(el);
+ }
+ return is_match;
},
- callback: !$.isFunction(callback) ? $.noop : function(filtered) {
- callback(filtered.results);
+ callback: !$.isFunction(callback) ? $.noop : function() {
+ callback(matches);
}
});
};
@@ -2053,6 +2109,11 @@ the specific language governing permissions and limitations under the Apache Lic
this.searchContainer = this.container.find(".select2-search-field");
this.selection = selection = this.container.find(selector);
+ // rewrite labels from original element to focusser
+ this.search.attr("id", "s2id_autogen"+nextUid());
+ $("label[for='" + this.opts.element.attr("id") + "']")
+ .attr('for', this.search.attr('id'));
+
this.search.bind("input paste", this.bind(function() {
if (!this.enabled) return;
if (!this.opened()) {
@@ -2121,6 +2182,12 @@ the specific language governing permissions and limitations under the Apache Lic
// prevent the page from scrolling
killEvent(e);
}
+
+ if (e.which === KEY.ENTER) {
+ // prevent form from being submitted
+ killEvent(e);
+ }
+
}));
this.search.bind("keyup", this.bind(this.resizeSearch));
@@ -2204,7 +2271,8 @@ the specific language governing permissions and limitations under the Apache Lic
if (placeholder !== undefined && this.getVal().length === 0 && this.search.hasClass("select2-focused") === false) {
this.search.val(placeholder).addClass("select2-default");
// stretch the search box to full width of the container so as much of the placeholder is visible as possible
- this.resizeSearch();
+ // we could call this.resizeSearch(), but we do not because that requires a sizer and we do not want to create one so early because of a firefox bug, see #944
+ this.search.width(this.getMaxSearchWidth());
} else {
this.search.val("").width(10);
}
@@ -2219,10 +2287,11 @@ the specific language governing permissions and limitations under the Apache Lic
// multi
opening: function () {
+ this.clearPlaceholder(); // should be done before super so placeholder is not used to search
+ this.resizeSearch();
+
this.parent.opening.apply(this, arguments);
- this.clearPlaceholder();
- this.resizeSearch();
this.focusSearch();
this.opts.element.trigger($.Event("open"));
@@ -2238,7 +2307,7 @@ the specific language governing permissions and limitations under the Apache Lic
focus: function () {
this.close();
this.search.focus();
- this.opts.element.triggerHandler("focus");
+ //this.opts.element.triggerHandler("focus");
},
// multi
@@ -2266,6 +2335,7 @@ the specific language governing permissions and limitations under the Apache Lic
self.postprocessResults();
},
+ // multi
tokenize: function() {
var input = this.search.val();
input = this.opts.tokenizer(input, this.data(), this.bind(this.onSelect), this.opts);
@@ -2293,7 +2363,7 @@ the specific language governing permissions and limitations under the Apache Lic
if (this.countSelectableResults()>0) {
this.search.width(10);
this.resizeSearch();
- if (this.val().length >= this.getMaximumSelectionSize()) {
+ if (this.getMaximumSelectionSize() > 0 && this.val().length >= this.getMaximumSelectionSize()) {
// if we reached max selection size repaint the results so choices
// are replaced with the max selection reached message
this.updateResults(true);
@@ -2432,6 +2502,11 @@ the specific language governing permissions and limitations under the Apache Lic
},
// multi
+ getMaxSearchWidth: function() {
+ return this.selection.width() - getSideBorderPadding(this.search);
+ },
+
+ // multi
resizeSearch: function () {
var minimumWidth, left, maxWidth, containerLeft, searchWidth,
sideBorderPadding = getSideBorderPadding(this.search);
@@ -2656,7 +2731,7 @@ the specific language governing permissions and limitations under the Apache Lic
formatResultCssClass: function(data) {return undefined;},
formatNoMatches: function () { return "No matches found"; },
formatInputTooShort: function (input, min) { var n = min - input.length; return "Please enter " + n + " more character" + (n == 1? "" : "s"); },
- formatInputTooLong: function (input, max) { var n = input.length - max; return "Please enter " + n + " less character" + (n == 1? "" : "s"); },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "Please delete " + n + " character" + (n == 1? "" : "s"); },
formatSelectionTooBig: function (limit) { return "You can only select " + limit + " item" + (limit == 1 ? "" : "s"); },
formatLoadMore: function (pageNumber) { return "Loading more results..."; },
formatSearching: function () { return "Searching..."; },
@@ -2666,7 +2741,7 @@ the specific language governing permissions and limitations under the Apache Lic
maximumSelectionSize: 0,
id: function (e) { return e.id; },
matcher: function(term, text) {
- return text.toUpperCase().indexOf(term.toUpperCase()) >= 0;
+ return (''+text).toUpperCase().indexOf((''+term).toUpperCase()) >= 0;
},
separator: ",",
tokenSeparators: [],
@@ -2682,7 +2757,7 @@ the specific language governing permissions and limitations under the Apache Lic
"/": '&#47;'
};
- return String(markup).replace(/[&<>"'/\\]/g, function (match) {
+ return String(markup).replace(/[&<>"'\/\\]/g, function (match) {
return replace_map[match[0]];
});
},
diff --git a/module/web/static/js/views/abstract/modalView.js b/module/web/static/js/views/abstract/modalView.js
index 1e45e942b..170681f06 100644
--- a/module/web/static/js/views/abstract/modalView.js
+++ b/module/web/static/js/views/abstract/modalView.js
@@ -83,7 +83,7 @@ define(['jquery', 'backbone', 'underscore', 'omniwindow'], function($, Backbone,
},
renderContent: function() {
- return {content: $('<h1>Content!</h1>').html()};
+ return {};
},
show: function() {
diff --git a/module/web/static/js/views/dashboard/fileView.js b/module/web/static/js/views/dashboard/fileView.js
index c673041b5..5d687a111 100644
--- a/module/web/static/js/views/dashboard/fileView.js
+++ b/module/web/static/js/views/dashboard/fileView.js
@@ -77,7 +77,7 @@ define(['jquery', 'backbone', 'underscore', 'app', 'utils/apitypes', 'views/abst
},
progress_changed: function() {
- if(!this.model.isDownload())
+ if (!this.model.isDownload())
return;
if (this.model.get('download').status === Api.DownloadStatus.Downloading) {
@@ -89,6 +89,10 @@ define(['jquery', 'backbone', 'underscore', 'app', 'utils/apitypes', 'views/abst
bar.width(this.model.get('progress') + '%');
bar.html('&nbsp;&nbsp;' + formatTime(this.model.get('eta')));
+ } else if (this.model.get('download').status === Api.DownloadStatus.Waiting) {
+ this.$('.second').html(
+ "<i class='iconf-time'></i>&nbsp;" + formatTime(this.model.get('eta')));
+
} else // Every else state can be renderred normally
this.render();
diff --git a/module/web/static/js/views/configSectionView.js b/module/web/static/js/views/settings/configSectionView.js
index 949493731..79f314309 100644
--- a/module/web/static/js/views/configSectionView.js
+++ b/module/web/static/js/views/settings/configSectionView.js
@@ -1,4 +1,4 @@
-define(['jquery', 'underscore', 'backbone', 'app', './abstract/itemView', './input/inputLoader'],
+define(['jquery', 'underscore', 'backbone', 'app', '../abstract/itemView', '../input/inputLoader'],
function($, _, Backbone, App, itemView, load_input) {
// Renders settings over view page
diff --git a/module/web/static/js/views/settings/pluginChooserModal.js b/module/web/static/js/views/settings/pluginChooserModal.js
new file mode 100644
index 000000000..c7cdce244
--- /dev/null
+++ b/module/web/static/js/views/settings/pluginChooserModal.js
@@ -0,0 +1,66 @@
+define(['jquery', 'underscore', 'app', 'views/abstract/modalView', 'text!tpl/default/pluginChooserDialog.html', 'select2'],
+ function($, _, App, modalView, template) {
+ return modalView.extend({
+
+ events: {
+ 'click .btn-add': 'add'
+ },
+ template: _.compile(template),
+ plugins: null,
+ select: null,
+
+ initialize: function() {
+ // Inherit parent events
+ this.events = _.extend({}, modalView.prototype.events, this.events);
+ var self = this;
+ $.ajax(App.apiRequest('getAvailablePlugins', null, {success: function(data) {
+ self.plugins = data;
+ self.render();
+ }
+ }));
+ },
+
+ onRender: function() {
+ // TODO: could be a seperate input type if needed on multiple pages
+ if (this.plugins)
+ this.select = this.$('#pluginSelect').select2({
+ escapeMarkup: function(m) {
+ return m;
+ },
+ formatResult: this.format,
+ formatSelection: this.formatSelection,
+ data: {results: this.plugins, text: function(item) {
+ return item.label;
+ }},
+ id: function(item) {
+ return item.name;
+ }
+ });
+ },
+
+ onShow: function() {
+ },
+
+ onHide: function() {
+ },
+
+ format: function(data) {
+ var s = '<div class="plugin-select" style="background-image: url(icons/' + data.name + '">' + data.label;
+ s += "<br><span>" + data.description + "<span></div>";
+ return s;
+ },
+
+ formatSelection: function(data) {
+ return '<img class="logo-select" src="icons/' + data.name + '"> ' + data.label;
+ },
+
+ add: function(e) {
+ e.stopPropagation();
+ if (this.select) {
+ var plugin = this.select.val();
+ App.settingsView.openConfig(plugin);
+ this.hide();
+ }
+ }
+ });
+ }); \ No newline at end of file
diff --git a/module/web/static/js/views/settingsView.js b/module/web/static/js/views/settings/settingsView.js
index 3b8308f19..58507f51a 100644
--- a/module/web/static/js/views/settingsView.js
+++ b/module/web/static/js/views/settings/settingsView.js
@@ -4,18 +4,20 @@ define(['jquery', 'underscore', 'backbone', 'app', 'models/ConfigHolder', './con
// Renders settings over view page
return Backbone.View.extend({
- el: "#content",
+ el: "body",
templateMenu: _.compile($("#template-menu").html()),
events: {
- 'click .settings-menu li > a': 'change_section'
+ 'click .settings-menu li > a': 'change_section',
+ 'click .btn-add': 'choosePlugin'
},
menu: null,
content: null,
+ modal: null,
- core_config: null, // It seems models are not needed
- plugin_config: null,
+ coreConfig: null, // It seems collections are not needed
+ pluginConfig: null,
// currently open configHolder
config: null,
@@ -36,19 +38,19 @@ define(['jquery', 'underscore', 'backbone', 'app', 'models/ConfigHolder', './con
refresh: function() {
var self = this;
$.ajax(App.apiRequest("getCoreConfig", null, {success: function(data) {
- self.core_config = data;
+ self.coreConfig = data;
self.render();
}}));
$.ajax(App.apiRequest("getPluginConfig", null, {success: function(data) {
- self.plugin_config = data;
+ self.pluginConfig = data;
self.render();
}}));
},
render: function() {
this.menu.html(this.templateMenu({
- core: this.core_config,
- plugin: this.plugin_config
+ core: this.coreConfig,
+ plugin: this.pluginConfig
}));
},
@@ -113,6 +115,7 @@ define(['jquery', 'underscore', 'backbone', 'app', 'models/ConfigHolder', './con
change_section: function(e) {
// TODO check for changes
+ // TODO move this into render?
var el = $(e.target).parent();
var name = el.data("name");
@@ -121,6 +124,16 @@ define(['jquery', 'underscore', 'backbone', 'app', 'models/ConfigHolder', './con
this.menu.find("li.active").removeClass("active");
el.addClass("active");
e.preventDefault();
+ },
+
+ choosePlugin: function(e){
+ var self = this;
+ _.requireOnce(['views/settings/pluginChooserModal'], function(Modal) {
+ if (self.modal === null)
+ self.modal = new Modal();
+
+ self.modal.show();
+ });
}
});
diff --git a/module/web/templates/default/backbone/pluginChooserDialog.html b/module/web/templates/default/backbone/pluginChooserDialog.html
new file mode 100755
index 000000000..02284d0e6
--- /dev/null
+++ b/module/web/templates/default/backbone/pluginChooserDialog.html
@@ -0,0 +1,23 @@
+{% extends 'default/backbone/modal.html' %}
+{% block header %}
+ Choose a plugin
+{% endblock %}
+{% block content %}
+ <form class="form-horizontal" action="#" xmlns="http://www.w3.org/1999/html">
+ <legend>
+ Please choose a plugin, which you want to configure
+ </legend>
+ <div class="control-group">
+ <label class="control-label" for="pluginSelect">
+ Plugin
+ </label>
+ <div class="controls">
+ <input type="hidden" id="pluginSelect">
+ </div>
+ </div>
+ </form>
+{% endblock %}
+{% block buttons %}
+ <a href="#" class="btn btn-success btn-add">Add</a>
+ <a href="#" class="btn btn-close">Close</a>
+{% endblock %} \ No newline at end of file
diff --git a/module/web/templates/default/settings.html b/module/web/templates/default/settings.html
index ea570af0f..bee583dbf 100644
--- a/module/web/templates/default/settings.html
+++ b/module/web/templates/default/settings.html
@@ -58,9 +58,9 @@
{% endblock %}
{% block actionbar %}
- {# <ul class="actionbar nav nav-pills span9">#}
- {# <li>Add Plugin</li>#}
- {# </ul>#}
+ <span class="span9">
+ <button class="btn btn-small btn-blue btn-add">Add Plugin</button>
+ </span>
{% endblock %}
{% block content %}