UNPKG

@coon-js/extjs-comp-navport

Version:

NPM package providing enhanced viewport template for rapid, modular, package agnostic Sencha ExtJS application building.

354 lines (293 loc) 10.9 kB
/** * coon.js * extjs-comp-navport * Copyright (C) 2017-2021 Thorsten Suckow-Homberg https://github.com/coon-js/extjs-comp-navport * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ /** * An {@link Ext.app.ViewController} to provide functionality for adding/managing * permanent navigation- and id-associated navigation-items in a toolbar. * * * @see coon.navport.view.NavigationToolbar */ Ext.define("coon.navport.view.controller.NavigationToolbarViewController", { extend: "Ext.app.ViewController", alias: "controller.cn_navport-navigationtoolbarviewcontroller", /** * An object keyed with node ids. The values are the itemId's of the * associated toolbar items which should be shown when requested. * @type {Object} nodeNavItemIds * @private * @see #activateNavigationForNode */ nodeNavItemIds: null, /** * The currently active id for which toolbar items are shown. * @type {String} activeNodeId * @private */ activeNodeId: null, /** * The insert position of the toolbar, where node navigation items should be * added by calling toolbar.insert() * @type {String} nodeNavInsertPosition * @private */ nodeNavInsertPosition: 2, /** * The initial insert position of permanent navigation (perma nav) items * * @type {Number} * @private */ permaNavIndex: 3, /** * Creates and adds toolbar items which are handled as permanent navigation * items. * * @param {Array|Object} items An array with items to add, or an object with * the properties "index" for the desired insert-position, and "items" with * the items to add. If "index" is not specified, items will get added to the end * of the item-list. * * @returns {Array} an array with the itemIds of the added items * * @throws bubbles exceptions from #buildToolbarItems * * @see #buildToolbarItems */ buildPermaNavItems: function (items) { const me = this, view = me.getView(); let passItems = items, index = false; if (items.items) { passItems = items.items; index = items.index ? items.index : false; } let maxIndex = index; if (index === false) { maxIndex = 0; view.items.items.forEach( item => maxIndex = item.cn_index > maxIndex ? item.cn_index + 1 : maxIndex ); } const createdItems = me.buildToolbarItems(passItems, false), itemIds = []; createdItems.map(item => item.cn_index = maxIndex++); for (var i = 0, len = createdItems.length; i < len; i++) { itemIds.push( view.insert( view.items.findInsertionIndex(createdItems[i], (item, itemNext) => { if (item.cn_index < itemNext.cn_index) { return -1; } if (item.cn_index > itemNext.cn_index) { return 1; } return 0; }), createdItems[i] ).getItemId() ); } return itemIds; }, /** * Creates and adds toolbar items which are handled as navigation items * belonging to a specific id. Belonging items can be set active by calling * #activateNavigationForNode. * * @param {Array} items * * @returns {Array} an array with the itemIds of the added items * * @throws bubbles exceptions from #buildToolbarItems * * @see #buildToolbarItems * @see #activateNavigationForNode */ buildNodeNavItems: function (items, id) { var me = this, createdItems = me.buildToolbarItems(items, true), view = me.getView(), itemIds = []; for (var i = createdItems.length - 1; i > -1; i--) { itemIds.push( view.insert(me.nodeNavInsertPosition, createdItems[i]).getItemId() ); me.permaNavIndex++; } if (!me.nodeNavItemIds) { me.nodeNavItemIds = {}; } me.nodeNavItemIds[id] = itemIds; return itemIds.reverse(); }, /** * Makes sure that items associated with the specified id are switched to * hidden=false. If the property cn_hidden is found in an item, and it's * value is set to true, it is assumed that this controller should not * manage the visibility state of this item, and leave it be. * Items associated with an existing activeNodeId will be set to be hidden. * activeNodeId will be set to the new id. * The nodeId does not necessarily have to hold a navigation. If that is not the case, * previous navigation will simply be set to hidden. * * @param {String} nodeId the id for which the associated items should be set * to be visible. * * @return {String} nodeId or null if there are no registered nodeNavItemIds * in this class * * @see switchItemVisibility */ activateNavigationForNode: function (nodeId) { var me = this, activeId = me.activeNodeId, itemIds, i, len; // no node navigation - exit if (!me.nodeNavItemIds) { return null; } // do nothing if nothing changes in nav if (nodeId === activeId) { return nodeId; } // set to new nodeId - its okay if not existing me.activeNodeId = nodeId; // set old hidden if (me.nodeNavItemIds[activeId]) { itemIds = me.nodeNavItemIds[activeId]; for (i = 0, len = itemIds.length; i < len; i++) { me.switchItemVisibility(itemIds[i], false); } } // no node-navigation to show? Exit. if (!me.nodeNavItemIds[nodeId]) { return null; } // set new visible if (me.nodeNavItemIds[nodeId]) { itemIds = me.nodeNavItemIds[nodeId]; for (i = 0, len = itemIds.length; i < len; i++) { me.switchItemVisibility(itemIds[i], true); } } return nodeId; }, /** * Returns true if a node navigation for the specific id exists, * otherwise false. * * @param {String} id * * @returns {Boolean} */ hasNodeNavigation: function (id) { return this.nodeNavItemIds && !!this.nodeNavItemIds[id]; }, /** * Adds new items this controller's toolbar. This method will check the entries * in items for validity, and also apply itemId's if not already specified * in the items' entries. Additionally, a flag "cn_hidden" will be set * with the original state of "hidden" when this method was called * with initalHide=true. This is so a further call to activation of this items * (treated as id-associated navigation) does not accidentally set them to * visible if they where initially set to be hidden. * * @param {Array} items * @param {Boolean} initialHide Whether the item should be initially set * to be hidden. This should be "true" for calls from #buildNodeNavItems. * The cn_hidden flag will be automatically applied to the item entries with * the original value. * * @protected * * @throws if items is not an array or entries of the array where misconfigured. */ buildToolbarItems: function (items, initialHide) { var itemsToAdd = [], item, start, end; if (!Ext.isArray(items)) { Ext.raise({ sourceClass: Ext.getClassName(this), items: items, msg: Ext.getClassName(this) + "#buildToolbarItems needs items to be an array" }); } start = -1; end = items.length - 1; while (start++ < end) { item = items[start]; if (!Ext.isObject(item) || (!Ext.isString(item.xtype) && !Ext.isString(item.xclass))) { Ext.raise({ sourceClass: Ext.getClassName(this), item: item, msg: Ext.getClassName(this) + "#buildToolbarItems found an invalid configuration for an item" }); } if (!item.itemId) { item.itemId = Ext.id(); } if (initialHide) { item.cn_hidden = item.hidden; item.hidden = true; } itemsToAdd.push(item); } return itemsToAdd; }, /** * Switches the visibility of the item specified with the itemId to either * true or false. Makes sure the cn_hidden property of the item is considered * when switching the items visibility to "visible". * * @param {String} itemId * @param {Boolean} show * * @return {Boolean} true if the item was set to visible, otherwise false * @private */ switchItemVisibility: function (itemId, show) { var me = this, view = me.getView(), item = view.down("#" + itemId); if (show) { if (!item.cn_hidden) { item.suspendEvents(); item.setHidden(false); item.resumeEvents(); return true; } } else { item.cn_hidden = item.isHidden(); item.suspendEvents(); item.setHidden(true); item.resumeEvents(); } return false; } });