UNPKG

generator-addin

Version:

MyGeotab/Geotab Drive add-in generator

202 lines (174 loc) 7.41 kB
const _GroupHelper = require('./_GroupHelper.js'); /** * Handles most of the HTML modification and Api calls for tasks relating to the * group filter functionality. Will make first call to the api to gather groups when * the user first clicks on the groups dropdown to save on requests to the database * when making small changes to the addins. * * Relies on the _GroupHelper class to do most of the html generation/sorting. */ class Groups { constructor(api, state, label, target, searchbar, removeBtn, activeGroupsid, parent){ this.api = api; this.state = state; this.label = label; this.baseNode; this.groupsDictionary; this.root = document.getElementById(target); this.activeLabel = document.getElementById(activeGroupsid); this.deleteAllBtn = document.getElementById(removeBtn); this.searchbar = searchbar this.parent = parent this.previousGroupStack = []; this.activeGroups = []; this.previousSearchTerm; } /** * Once the initial call for groups has been made, we want to re-reference the already * collected groups and use this method to just re-generate the base html. */ generateRootHtml(){ let html = _GroupHelper.generateNodeHtml(this.label, this.groupsDictionary, this.baseNode, this.parent); this.root.innerHTML = html; } /** * Creates a request to the database the user is currently logged in to, and grabs all * the registered groups from there. * * @param {int} resultsLimit how many results to limit the response to. * @returns {Promise} Once the call completes, the call resolves. */ getAllGroupsInDatabase(resultsLimit = 2000){ let callPromise = new Promise( (resolve, reject) => { this.api.call('Get', { 'typeName': 'Group', 'resultsLimit': resultsLimit }, (result) => this._groupSuccessCallback(result, resolve), (error) => this._groupErrorCallback(error, reject)); }); return callPromise; } /** * Removes all group names from the 'Active Groups' header. * Removes all groups from the state. * Unselects any previously selected groups in the groupsDictionary. * Resets the HTML to remove any checked attributes. */ resetActiveGroups(){ this.state._activeGroups.forEach( group => { this.groupsDictionary[group.id].selected = false; }); this.state._activeGroups = []; this.writeActiveGroups(); let html = _GroupHelper.generateNodeHtml(this.label, this.groupsDictionary, this.baseNode, this.parent); this.root.innerHTML = html; geotab.addin.<%= root%>.focus(this.api, this.state); } /** * Toggles the status of the selected node to be 'active'. Updates this on the groupsDictionary * to maintain the highlighting style when the HTML is reloaded (folder change, search, etc.) * * @param {string} id id of the node that is to be added to the 'Active Groups' filter */ toggleGroupFilter(id){ let idIndex; for (let i = 0; i < this.state._activeGroups.length; i++) { if(this.state._activeGroups[i].id === id){ idIndex = i; } } if(idIndex !== undefined){ this.state._activeGroups.splice(idIndex, 1); this.groupsDictionary[id].selected = false; } else { this.groupsDictionary[id].selected = true; this.state._activeGroups.push({id}); } this.writeActiveGroups(); geotab.addin.<%= root%>.focus(this.api, global.state); } /** * Writes the currently selected group's to the top bar, and injects 'OR' if there are multiple * filters selected. */ writeActiveGroups(){ let text = `Active Groups:`; let stateLength = this.state._activeGroups.length; if(stateLength > 0){ text += _GroupHelper.generateActiveHeaderText(this.state, stateLength, this.groupsDictionary, this.state.operator); this.deleteAllBtn.style.display = 'inline'; } else { text += ` All`; this.deleteAllBtn.style.display = 'none'; } this.activeLabel.innerHTML = text; } /** * Creates regex out of a provided search term and re-generates the group list html based on * the inclusion of the keyword. Should be run whenever the query input changes. * * @param {string} query keyword for searching the groups */ groupSearch(query){ let regex = this._createRegex(query.toLowerCase()); let html = _GroupHelper.generateSearchHtml(this.label, this.groupsDictionary, `${this.parent}-ul`, regex); this.root.innerHTML = html; } _createRegex(input){ let regex = new RegExp(`.*${input}.*`); return regex; } /** * Handles navigation into a subfolder. Stores information about where the user is going * and where the user is coming from to allow us to go 'one level up' from the new group list. * * @param {string} previous the id of the folder/level that the user is leaving. * @param {string} current the id of the folder/level the user is navigating into. */ changeFocus(previous, current){ this.previousGroupStack.push(previous); let html = _GroupHelper.generateNodeHtml(this.label, this.groupsDictionary, current, this.parent, this.baseNode); this.root.innerHTML = html; } /** * Returns to the previous folder that was in view for the user when selecting 'Go up one level' * option. */ goToPreviousFolder(){ let previousFolder = this.previousGroupStack.pop(); let html = _GroupHelper.generateNodeHtml(this.label, this.groupsDictionary, previousFolder, this.parent, this.baseNode); this.root.innerHTML = html; } /** * Callback used for collecting the group list from the authenticated database. * * @param {object} result Response from the server - should contain a list of all the groups on the DB. */ _groupSuccessCallback(result, resolve){ let groupInput = document.getElementById(this.searchbar); this.baseNode = result[0].id; this.groupsDictionary = _GroupHelper.convertGroupsListToDictionary(result); let html = _GroupHelper.generateNodeHtml(this.label, this.groupsDictionary, this.baseNode, this.parent); this.root.innerHTML = html; // If we had any errors, we want to reset the placeholder text. groupInput.placeholder = 'Search for Groups'; resolve(); } /** * Notifies the user that there has been an error in creating the group list. Will retry * every 60 seconds. * * @param {string} error Error message from failed api call/Group object instantiation. */ _groupErrorCallback(error){ let groupInput = document.getElementById(this.searchbar); groupInput.placeholder = "Unable to retrieve Groups"; console.log(error); setTimeout(() => { groupInput.placeholder = "Retrying..."; this.getAllGroupsInDatabase(); }, 60000); } } module.exports = Groups;