From bfc59c9007447dae108bbef2b04b04040eac38a7 Mon Sep 17 00:00:00 2001 From: alekseybobkov Date: Sun, 27 Jul 2014 11:11:16 +1100 Subject: [PATCH] Updating the Settings pages --- modules/backend/ServiceProvider.php | 3 +- modules/backend/assets/css/october.css | 1 + .../backend/assets/js/october.sidenav-tree.js | 248 ++++++++++++++++++ .../backend/assets/js/vendor/jquery.cookie.js | 117 +++++++++ .../assets/less/controls/sidenav-tree.less | 1 + modules/backend/lang/en/lang.php | 2 + modules/backend/layouts/_head.htm | 4 +- modules/system/ServiceProvider.php | 45 ++-- modules/system/classes/SettingsManager.php | 1 + modules/system/controllers/settings/index.htm | 6 +- modules/system/lang/en/lang.php | 1 + .../system/partials/_settings_menu_items.htm | 15 +- .../partials/_settings_menu_toolbar.htm | 4 +- modules/system/partials/_system_sidebar.htm | 2 +- 14 files changed, 417 insertions(+), 33 deletions(-) create mode 100644 modules/backend/assets/js/october.sidenav-tree.js create mode 100755 modules/backend/assets/js/vendor/jquery.cookie.js diff --git a/modules/backend/ServiceProvider.php b/modules/backend/ServiceProvider.php index 34aea94e1..9f3dd231d 100644 --- a/modules/backend/ServiceProvider.php +++ b/modules/backend/ServiceProvider.php @@ -101,7 +101,8 @@ class ServiceProvider extends ModuleServiceProvider 'icon' => 'icon-user', 'url' => Backend::URL('backend/users/myaccount'), 'order' => 400, - 'context' => 'mysettings' + 'context' => 'mysettings', + 'keywords' => 'backend::lang.myaccount.menu_keywords', ], ]); }); diff --git a/modules/backend/assets/css/october.css b/modules/backend/assets/css/october.css index 6b49d86d2..5b7d56b26 100644 --- a/modules/backend/assets/css/october.css +++ b/modules/backend/assets/css/october.css @@ -12893,6 +12893,7 @@ div[data-control="balloon-selector"]:not(.control-disabled) ul li:hover { padding: 15px 15px 15px 33px; margin: 0; position: relative; + cursor: pointer; } .sidenav-tree ul.top-level > li > div.group h3:before { width: 10px; diff --git a/modules/backend/assets/js/october.sidenav-tree.js b/modules/backend/assets/js/october.sidenav-tree.js new file mode 100644 index 000000000..55d8ef192 --- /dev/null +++ b/modules/backend/assets/js/october.sidenav-tree.js @@ -0,0 +1,248 @@ +/* + * Side navigation tree + * + * Data attributes: + * - data-control="sidenav-tree" - enables the plugin + * - data-tree-name - unique name of the tree control. The name is used for storing user configuration in the browser cookies. + * + * JavaScript API: + * $('#tree').sidenavTree() + * + * Dependences: + * - Null + */ + ++function ($) { "use strict"; + + // SIDENAVTREE CLASS DEFINITION + // ============================ + + var SidenavTree = function(element, options) { + this.options = options + this.$el = $(element) + + this.init(); + } + + SidenavTree.DEFAULTS = { + treeName: 'sidenav_tree' + } + + SidenavTree.prototype.init = function (){ + var self = this + + this.statusCookieName = this.options.treeName + 'groupStatus' + this.searchCookieName = this.options.treeName + 'search' + this.$searchInput = $(this.options.searchInput) + + this.$el.on('click', 'li > div.group', function() { + self.toggleGroup($(this).closest('li')) + + return false; + }); + + this.$searchInput.on('keyup', function(){ + self.handleSearchChange() + }) + + var searchTerm = $.cookie(this.searchCookieName) + if (searchTerm !== undefined && searchTerm.length > 0) { + this.$searchInput.val(searchTerm) + this.applySearch() + } + } + + SidenavTree.prototype.toggleGroup = function(group) { + var $group = $(group), + status = $group.attr('data-status') + + status === undefined || status == 'expanded' ? + this.collapseGroup($group) : + this.expandGroup($group) + } + + SidenavTree.prototype.collapseGroup = function(group) { + var + $list = $('> ul', group), + self = this; + + $list.css('overflow', 'hidden') + $list.animate({'height': 0}, { duration: 100, queue: false, complete: function() { + $list.css({ + 'overflow': 'visible', + 'display': 'none' + }) + $(group).attr('data-status', 'collapsed') + $(window).trigger('oc.updateUi') + self.saveGroupStatus($(group).data('group-code'), true) + } }) + } + + SidenavTree.prototype.expandGroup = function(group, duration) { + var + $list = $('> ul', group), + self = this + + duration = duration === undefined ? 100 : duration + + $list.css({ + 'overflow': 'hidden', + 'display': 'block', + 'height': 0 + }) + $list.animate({'height': $list[0].scrollHeight}, { duration: duration, queue: false, complete: function() { + $list.css({ + 'overflow': 'visible', + 'height': 'auto' + }) + $(group).attr('data-status', 'expanded') + $(window).trigger('oc.updateUi') + self.saveGroupStatus($(group).data('group-code'), false) + } }) + } + + SidenavTree.prototype.saveGroupStatus = function(groupCode, collapsed) { + var collapsedGroups = $.cookie(this.statusCookieName), + updatedGroups = [] + + if (collapsedGroups === undefined) + collapsedGroups = '' + + collapsedGroups = collapsedGroups.split('|') + $.each(collapsedGroups, function() { + if (groupCode != this) + updatedGroups.push(this) + }) + + if (collapsed) + updatedGroups.push(groupCode) + + $.cookie(this.statusCookieName, updatedGroups.join('|'), { expires: 30, path: '/' }) + } + + SidenavTree.prototype.handleSearchChange = function() { + var lastValue = this.$searchInput.data('oc.lastvalue'); + + if (lastValue !== undefined && lastValue == this.$searchInput.val()) + return + + this.$searchInput.data('oc.lastvalue', this.$searchInput.val()) + + if (this.dataTrackInputTimer !== undefined) + window.clearTimeout(this.dataTrackInputTimer); + + var self = this + this.dataTrackInputTimer = window.setTimeout(function(){ + self.applySearch() + }, 300); + + $.cookie(this.searchCookieName, $.trim(this.$searchInput.val()), { expires: 30, path: '/' }) + } + + SidenavTree.prototype.applySearch = function() { + var query = $.trim(this.$searchInput.val()), + words = query.toLowerCase().split(' '), + visibleGroups = [], + visibleItems = [], + self = this + + if (query.length == 0) { + $('li', this.$el).removeClass('hidden') + + return + } + + // Find visible groups and items + // + $('ul.top-level > li', this.$el).each(function() { + var $li = $(this) + + if (self.textContainsWords($('div.group h3', $li).text(), words)) { + visibleGroups.push($li.get(0)) + + $('ul li', $li).each(function(){ + visibleItems.push(this) + }) + } else { + $('ul li', $li).each(function(){ + if (self.textContainsWords($(this).text(), words) || self.textContainsWords($(this).data('keywords'), words)) { + visibleGroups.push($li.get(0)) + visibleItems.push(this) + } + }) + } + }) + + // Hide invisible groups and items + // + $('ul.top-level > li', this.$el).each(function() { + var $li = $(this), + groupIsVisible = $.inArray(this, visibleGroups) !== -1 + + $li.toggleClass('hidden', !groupIsVisible) + if (groupIsVisible) + self.expandGroup($li, 0) + + $('ul li', $li).each(function(){ + var $itemLi = $(this) + + $itemLi.toggleClass('hidden', $.inArray(this, visibleItems) == -1) + }) + }) + + return false + } + + SidenavTree.prototype.textContainsWords = function(text, words) { + text = text.toLowerCase() + + for (var i = 0; i < words.length; i++) { + if (text.indexOf(words[i]) === -1) + return false + } + + return true + } + + // SIDENAVTREE PLUGIN DEFINITION + // ============================ + + var old = $.fn.sidenavTree + + $.fn.sidenavTree = function (option) { + var args = arguments; + + return this.each(function () { + var $this = $(this) + var data = $this.data('oc.sidenavTree') + var options = $.extend({}, SidenavTree.DEFAULTS, $this.data(), typeof option == 'object' && option) + + if (!data) $this.data('oc.sidenavTree', (data = new SidenavTree(this, options))) + if (typeof option == 'string') { + var methodArgs = []; + for (var i=1; i 1 && !$.isFunction(value)) { + options = $.extend({}, config.defaults, options); + + if (typeof options.expires === 'number') { + var days = options.expires, t = options.expires = new Date(); + t.setTime(+t + days * 864e+5); + } + + return (document.cookie = [ + encode(key), '=', stringifyCookieValue(value), + options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE + options.path ? '; path=' + options.path : '', + options.domain ? '; domain=' + options.domain : '', + options.secure ? '; secure' : '' + ].join('')); + } + + // Read + + var result = key ? undefined : {}; + + // To prevent the for loop in the first place assign an empty array + // in case there are no cookies at all. Also prevents odd result when + // calling $.cookie(). + var cookies = document.cookie ? document.cookie.split('; ') : []; + + for (var i = 0, l = cookies.length; i < l; i++) { + var parts = cookies[i].split('='); + var name = decode(parts.shift()); + var cookie = parts.join('='); + + if (key && key === name) { + // If second argument (value) is a function it's a converter... + result = read(cookie, value); + break; + } + + // Prevent storing a cookie that we couldn't decode. + if (!key && (cookie = read(cookie)) !== undefined) { + result[name] = cookie; + } + } + + return result; + }; + + config.defaults = {}; + + $.removeCookie = function (key, options) { + if ($.cookie(key) === undefined) { + return false; + } + + // Must not alter options, thus extending a fresh object... + $.cookie(key, '', $.extend({}, options, { expires: -1 })); + return !$.cookie(key); + }; + +})); diff --git a/modules/backend/assets/less/controls/sidenav-tree.less b/modules/backend/assets/less/controls/sidenav-tree.less index b149a2df8..72eb5b3df 100644 --- a/modules/backend/assets/less/controls/sidenav-tree.less +++ b/modules/backend/assets/less/controls/sidenav-tree.less @@ -40,6 +40,7 @@ padding: 15px 15px 15px 33px; margin: 0; position: relative; + cursor: pointer; &:before { width: 10px; diff --git a/modules/backend/lang/en/lang.php b/modules/backend/lang/en/lang.php index 28f721349..13ec1161b 100644 --- a/modules/backend/lang/en/lang.php +++ b/modules/backend/lang/en/lang.php @@ -49,6 +49,7 @@ return [ 'user' => [ 'name' => 'Administrator', 'menu_label' => 'Administrators', + 'menu_description' => 'Manage back-end administrator users, groups and permissions.', 'list_title' => 'Manage Administrators', 'new' => 'New Administrator', 'login' => "Login", @@ -178,6 +179,7 @@ return [ 'myaccount' => [ 'menu_label' => 'My Account', 'menu_description' => 'Update your account details such as name, email address and password.', + 'menu_keywords' => 'security login' ], 'backend_preferences' => [ 'menu_label' => 'Backend Preferences', diff --git a/modules/backend/layouts/_head.htm b/modules/backend/layouts/_head.htm index 8dceb3af1..fc61b28d6 100644 --- a/modules/backend/layouts/_head.htm +++ b/modules/backend/layouts/_head.htm @@ -18,6 +18,8 @@ + + @@ -69,7 +71,7 @@ - +