UNPKG

cipherguard-mad

Version:

Cipherguard javascript application library for the open source password manager for teams

318 lines (278 loc) 9.24 kB
/** * Cipherguard ~ Open source password manager for teams * Copyright (c) KhulnaSoft Ltd (https://www.khulnasoft.com) * * Licensed under GNU Affero General Public License version 3 of the or any later version. * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * * @copyright Copyright (c) KhulnaSoft Ltd (https://www.khulnasoft.com) * @license https://opensource.org/licenses/AGPL-3.0 AGPL License * @link https://www.khulnasoft.com KhulnaSoft(tm) */ import $ from 'jquery'; import DomData from 'can-dom-data'; import domEvents from 'can-dom-events'; import View from '../view'; import HtmlHelper from '../../helper/html'; /** * @inherits mad.View */ const Grid = View.extend('mad.view.component.Grid', /* @static */ {}, /** @prototype */ { /** * Flush the grid */ reset: function() { const tableElement = $('.tableview-content', this.element); const tableTbody = tableElement.find('tbody'); tableElement.scrollTop(0); tableTbody.empty(); this.markAsUnsorted(); }, /** * Hide a column * @param {string} columnName The column name to hide */ hideColumn: function(columnName) { $(`.js_grid_column_${columnName}`, this.element).hide(); }, /** * Show a column * @param {string} columnName The column name to show */ showColumn: function(columnName) { $(`.js_grid_column_${columnName}`, this.element).show(); }, /** * Select an item * @param {DefineMap} item The selected item instance or its id */ selectItem: function(item) { const $item = this.getItemElement(item); $item.addClass('selected'); }, /** * Unselect an item * @param {DefineMap} item The unselected item instance or its id */ unselectItem: function(item) { const $item = this.getItemElement(item); $item.removeClass('selected'); }, /** * Unselect all. */ unselectAll: function() { $('tr.selected', this.element).removeClass('selected'); }, /** * An item has been right selected * @param {DefineMap} item The selected item instance or its id */ // eslint-disable-next-line no-unused-vars rightSelectItem: function(item) { }, /** * An item has been hovered * @param {DefineMap} item The selected item instance or its id * @param {HTMLElement} el The element the event occurred on * @param {HTMLEvent} ev The event that occurred */ // eslint-disable-next-line no-unused-vars hoverItem: function(item, el, ev) { }, /** * Remove an item from the grid * @param {DefineMap} item The item to remove */ removeItem: function(item) { const $item = this.getItemElement(item); $item.remove(); }, /** * Hide an item. * @param {DefineMap} item The item to hide. */ hideItem: function(item) { const $item = this.getItemElement(item); $item.hide(); }, /** * Show an item. * @param {DefineMap} item The item to show. */ showItem: function(item) { const $item = this.getItemElement(item); $item.show(); }, /** * Render a row for a given item * @param {DefineMap} item * @param {object} options */ _renderRow: function(item, options) { const control = this.getController(); const columnModels = control.getColumnModel(); const mappedItem = control.mappedItems[item.id]; // Render the row with the row data. return View.render(control.options.itemTemplate, { item: item, id: control.options.prefixItemId + mappedItem.id, columnModels: columnModels, mappedItem: mappedItem, cellTemplate: control.options.cellTemplate, options: options }); }, /** * Get the HtmlElement that has been drawn for an item. * @param {DefineMap} item The item to get the element for. * @return {jQuery} */ getItemElement: function(item) { return $(`#${this.getController().options.prefixItemId}${item.id}`, this.element); }, /** * Insert an item into the grid * @param {DefineMap} item The item to insert in the grid * @param {DefineMap} refItem (optional) The reference item to use to position the new item. * By default the item will be inserted as last element of the grid. * @param {string} position (optional) If the reference item has been defined. The position * of the item to insert, regarding the reference item. * @param {object} options */ insertItem: function(item, refItem, position, options) { // By default position the new element inside as final element position = position || 'last'; let $item = null; let $refElement = null; let row = ''; const control = this.getController(); /* * Adapt the insertion strategy regarding the reference element and the desired position. * By default the new item will be inserted as last elemement of the grid. */ switch (position) { case 'before': case 'after': // Get the HTML Element which represents the reference element. $refElement = this.getItemElement(refItem); if (!$refElement.length) { throw new mad.Exception('No HTMLElement found for the given item.'); } break; default: case 'first': case 'last': // By default retrieve the content HTML element of the grid as reference element. $refElement = $('tbody', this.element); break; } // Render the row. row = this._renderRow(item, options); // Insert the row html fragment in the grid. $item = HtmlHelper.create($refElement, position, row); // Associate to the item to the just created node DomData.set($item[0], control.getItemClass().shortName, item); return $item; }, /** * Refresh an item. * @param {DefineMap} item The item to refresh * @param {object} options */ refreshItem: function(item, options) { const $current = this.getItemElement(item); const row = this._renderRow(item, options); const $item = HtmlHelper.create($current, 'replace_with', row); DomData.set($item[0], this.getController().getItemClass().shortName, item); }, /** * Move an item to another position in the grid. * @param {DefineMap} item The item to move * @param {string} position The position to move the item to */ moveItem: function(item, position) { const $el = this.getItemElement(item); const $detachedEl = $el.detach(); const $refEl = $('tbody tr', this.element).eq(position); if ($refEl.length) { $refEl.before($detachedEl); } else { $('tbody', this.element).append($detachedEl); } }, /** * Mark the column as sorted * @param {Column} columnModel * @param {boolean} sortAsc */ markColumnAsSorted: function(columnModel, sortAsc) { let cssClasses = 'sorted '; cssClasses += sortAsc ? 'sort-asc' : 'sort-desc'; this.markAsUnsorted(); $(`.js_grid_column_${columnModel.name}`, this.element).addClass(cssClasses); }, /** * Mark the grid as unsorted. */ markAsUnsorted: function() { $('.sortable.sorted', this.element).removeClass('sorted sort-asc sort-desc'); }, /* ************************************************************** */ /* LISTEN TO THE VIEW EVENTS */ /* ************************************************************** */ /** * A sort is requested on a column * @param {HTMLElement} el The element the event occurred on * @param {HTMLEvent} ev The event that occurred */ '{element} thead th.sortable click': function(el, ev) { const control = this.getController(); let sortAsc = true; const columnModel = DomData.get(el, control.getColumnModelClass().shortName); // If the column is already sorted. if ($(el).hasClass('sorted')) { if ($(el).hasClass('sort-desc')) { sortAsc = true; } else { sortAsc = false; } } domEvents.dispatch(this.element, {type: 'column_sort', data: {columnModel: columnModel, sortAsc: sortAsc, srcEv: ev}}); }, /** * An item has been selected * @param {HTMLElement} el The element the event occurred on * @param {HTMLEvent} ev The event that occurred */ '{element} tbody tr click': function(el, ev) { let data; const control = this.getController(); const itemClass = control.getItemClass(); if (itemClass) { data = DomData.get(el, itemClass.shortName); } else { data = el.id.replace(control.options.prefixItemId, ''); } domEvents.dispatch(this.element, {type: 'item_selected', data: {item: data, srcEv: ev}}); }, /** * An item has been hovered * * @param {HTMLElement} el The element the event occurred on * @param {HTMLEvent} ev The event that occurred */ '{element} tbody tr hover': function(el, ev) { let data; const control = this.getController(); const itemClass = control.getItemClass(); if (itemClass) { data = DomData.get(el, itemClass.shortName); } else { data = el.id.replace(control.options.prefixItemId, ''); } domEvents.dispatch(this.element, {type: 'item_hovered', data: {item: data, srcEv: ev}}); } }); export default Grid;