diff options
Diffstat (limited to 'module')
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 Binary files differnew file mode 100755 index 000000000..5b33f7e54 --- /dev/null +++ b/module/web/static/img/select2-spinner.gif diff --git a/module/web/static/img/select2.png b/module/web/static/img/select2.png Binary files differnew file mode 100755 index 000000000..1d804ffb9 --- /dev/null +++ b/module/web/static/img/select2.png diff --git a/module/web/static/img/select2x2.png b/module/web/static/img/select2x2.png Binary files differnew file mode 100755 index 000000000..4bdd5c961 --- /dev/null +++ b/module/web/static/img/select2x2.png 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 "/": '/' }; - 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(' ' + formatTime(this.model.get('eta'))); + } else if (this.model.get('download').status === Api.DownloadStatus.Waiting) { + this.$('.second').html( + "<i class='iconf-time'></i> " + 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 %}
|