From 7dac2623ad78a2f89fbfe15879316a1175cb1a8b Mon Sep 17 00:00:00 2001 From: Robert Axelsen Date: Fri, 15 Sep 2017 12:59:22 +0200 Subject: [PATCH] TT#21502 Fix store undefined issue CallForward: Fix race condition problem with destinations being populated before sourceset specific store has been created Change-Id: I37e86e21102bce433235ac7050e8a27103a66779 --- .../callforward/CallForwardController.js | 139 ++++++++++-------- .../pages/callforward/CallForwardModel.js | 4 +- 2 files changed, 82 insertions(+), 61 deletions(-) diff --git a/classic/src/view/pages/callforward/CallForwardController.js b/classic/src/view/pages/callforward/CallForwardController.js index d563daec..5932dd57 100644 --- a/classic/src/view/pages/callforward/CallForwardController.js +++ b/classic/src/view/pages/callforward/CallForwardController.js @@ -165,53 +165,61 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', { return mapping.length !== 0; }, - buildArrayOfModels: function (cfMappings, cfType, routeTimeset, cfdestinationsets, cftRingTimeout, arrayOfModels) { + hasOwnPhone: function(destinations) { + // TODO Destinations array has "own phone", but does not + // return true regardless. Fix, or create new task to tackle this + return destinations.some(function(destination) { + return "own phone" == destination.destination; + }); + }, + + // NOTE Commit message update + // - the task + // DONE - solve issue with cfu destinations only showin in first sourceset tab + // TODO - own phone not rendering for successive sourceset tabs + // TODO - solve problem with duplicate own phone within same destinationset + // TODO - if more than 1 cfu mapping exists, any mappings that is not the first + // are currently ignored. fix + buildArrayOfModels: function (cfMappings, cfType, routeTimeset, cfdestinationsets, cftRingTimeout, arrayOfModels, hasCftAndCfuMappings) { var $cf = this; Ext.each(cfMappings, function(mapping, j) { - var cfmappings = {}; - if (cfType === 'cfu' && j === 1) { return false; }; - cfmappings.destinationsetName = mapping.destinationset; - cfmappings.sourcesetName = mapping.sourceset; - cfmappings.timesetName = mapping.timeset; - if (cfmappings.timesetName == routeTimeset) { - // A destinationset can be used as mapping for mutiple call forwarding types, so - // we can not break out of this loop better than we already are. _modelCreated - // is already in place to make sure we don't go deeper in the loops if the current - // cftype already has that destinationset added as model + var currentMapping = {}; + currentMapping.destinationsetName = mapping.destinationset; + currentMapping.sourcesetName = mapping.sourceset; + currentMapping.timesetName = mapping.timeset; + if (currentMapping.timesetName == routeTimeset) { Ext.each(cfdestinationsets, function(cfdestinationset) { - if (cfType !== 'cft' || !hasCftAndCfuMappings && cfType === 'cft') { - if (cfdestinationset.name == cfmappings.destinationsetName && !cfmappings._modelCreated) { + if (cfType.match(/(cfb|cfna)/) || cfType === 'cfu' && cfMappings[0].destinationset === mapping.destinationset || !hasCftAndCfuMappings && cfType === 'cft') { + // _modelCreated check in place to make sure we don't add the destinationset more + // than one time if the cftype already has that destinationset added as model + if (cfdestinationset.name == currentMapping.destinationsetName && !currentMapping._modelCreated) { + var ownPhoneAdded = false; cfdestinationset.destinations = $cf.sortDestinationsetByPriority(cfdestinationset.destinations); - if (cfType === 'cft' && cfMappings[0].destinationset === mapping.destinationset) { + // TODO Do not add 'own phone' if it already exists in cfdestinationset.destinations + // if (cfType === 'cft' && cfMappings[0].destinationset === mapping.destinationset && !$cf.hasOwnPhone(cfdestinationset.destinations)) { + if (cfType === 'cft' && !$cf.hasOwnPhone(cfdestinationset.destinations)) { $cf.addCftOwnPhone(cfdestinationset.destinations, cftRingTimeout); + ownPhoneAdded = true; }; - // We can not break out of this one, as we need all destinations of the given - // destinationset added to the store for (item in cfdestinationset.destinations) { var destinationToDisplayInGrid = $cf.getDestinationFromSipId(cfdestinationset.destinations[item].destination); - var destinationAnnouncementId = cfdestinationset.announcement_id; - var destination = cfdestinationset.destinations[item].destination; - var priority = cfdestinationset.destinations[item].priority; - var timeout = cfdestinationset.destinations[item].timeout; - var destinationId = cfdestinationset.id; - var destinationName = cfdestinationset.name; // Removes timeout if destination is not a number var ringFor = !Ext.isNumber(parseInt(destinationToDisplayInGrid)) ? '' : cfdestinationset.destinations[item].timeout; var cbModel = Ext.create('NgcpCsc.model.CallForwardDestination', { type: cfType, destination_displayed: destinationToDisplayInGrid, - destination: destination, - destination_announcement_id: destinationAnnouncementId, - priority: priority, + destination: cfdestinationset.destinations[item].destination, + destination_announcement_id: cfdestinationset.announcement_id, + priority: cfdestinationset.destinations[item].priority, timeout_displayed: ringFor, - timeout: timeout, - sourceset: cfmappings.sourcesetName, - timeset: cfmappings.timesetName, - destinationset_id: destinationId, - destinationset_name: destinationName + timeout: cfdestinationset.destinations[item].timeout, + sourceset: currentMapping.sourcesetName, + timeset: currentMapping.timesetName, + destinationset_id: cfdestinationset.id, + destinationset_name: cfdestinationset.name }); arrayOfModels.push(cbModel); - cfmappings._modelCreated = true; + currentMapping._modelCreated = true; } } }; @@ -228,11 +236,15 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', { var cfbMappings = data.get('cfb'); var cfnaMappings = data.get('cfna'); var cftRingTimeout = data.get('cft_ringtimeout'); + // TODO Need to create an new function to also take into account the fact that if one + // online grid has cft and cfu mappings together, online grids under other sourcesets + // that does not have this combination should still render. Right now they don't var hasCftAndCfuMappings = $cf.hasMappings(cfuMappings) && $cf.hasMappings(cftMappings); var timeset = store._type; var arrayOfModels = []; var currentRoute = window.location.hash; var routeTimeset = this.getTimesetFromRoute(currentRoute); + $vm.set('destStoresPopulated', false); $vm.set('cft_ringtimeout', cftRingTimeout); store.removeAll(); Ext.Ajax.request({ @@ -243,11 +255,12 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', { var cfdestinationsets = decodedResponse._embedded['ngcp:cfdestinationsets']; $cf.buildArrayOfModels(cfbMappings, 'cfb', routeTimeset, cfdestinationsets, cftRingTimeout, arrayOfModels); $cf.buildArrayOfModels(cfuMappings, 'cfu', routeTimeset, cfdestinationsets, cftRingTimeout, arrayOfModels); - $cf.buildArrayOfModels(cftMappings, 'cft', routeTimeset, cfdestinationsets, cftRingTimeout, arrayOfModels); + $cf.buildArrayOfModels(cftMappings, 'cft', routeTimeset, cfdestinationsets, cftRingTimeout, arrayOfModels, hasCftAndCfuMappings); $cf.buildArrayOfModels(cfnaMappings, 'cfna', routeTimeset, cfdestinationsets, cftRingTimeout, arrayOfModels); $cf.addOwnPhoneToEmptyOnline(); if (arrayOfModels.length > 0) { - $cf.populateDestinationStores(arrayOfModels); + $vm.set('arrayOfDestModels', arrayOfModels); + $cf.populateDestinationStores(); }; }; }, @@ -259,7 +272,7 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', { }, - destinationIdExistsInArray: function(arr, id) { + hasDestinationWithId: function(arr, id) { return arr.some(function(arrObj) { return id == arrObj.id; }); @@ -275,7 +288,7 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', { Ext.each(store.getRange(), function(record) { var data = record.getData(); if (data.destination !== 'own phone') { - switch (recordsToSend.length === 0 || !me.destinationIdExistsInArray(recordsToSend, data.destinationset_id)) { + switch (recordsToSend.length === 0 || !me.hasDestinationWithId(recordsToSend, data.destinationset_id)) { case true: // if recordsToSend array is empty or recordsToSend does not already contain current destinationset already if (data.timeout) { @@ -622,31 +635,36 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', { }); }, - populateDestinationStores: function(models) { + populateDestinationStores: function() { var $cf = this; + var $vm = $cf.getViewModel(); var store; var stores = []; - Ext.each(models, function(model) { - var sourcename = $cf.getSourceNameFromSourceSet(model.get('sourceset')); - var timename = $cf.getTimeNameFromTimeSet(model.get('timeset')); - var type = $cf.getGridCategoryFromType(model.get('type')); - var storeName = sourcename + timename + type; - store = Ext.getStore(storeName); - if(!store._emptied){ - store.removeAll(); - store._emptied = true; - } - if (store) { - store.add(model); - stores.push(store); - } - }); - if (store) { - Ext.each(stores, function(store) { - store.commitChanges(); - $cf.setLabelTerminationType(store); - store._emptied = false; + var models = $vm.get('arrayOfDestModels'); + if (models && !$vm.get('destStoresPopulated')) { + Ext.each(models, function(model) { + var sourcename = $cf.getSourceNameFromSourceSet(model.get('sourceset')); + var timename = $cf.getTimeNameFromTimeSet(model.get('timeset')); + var type = $cf.getGridCategoryFromType(model.get('type')); + var storeName = sourcename + timename + type; + store = Ext.getStore(storeName); + if (store) { + if (!store._emptied) { + store.removeAll(); + store._emptied = true; + } + store.add(model); + stores.push(store); + } }); + if (store) { + Ext.each(stores, function(store) { + store.commitChanges(); + $cf.setLabelTerminationType(store); + store._emptied = false; + }); + }; + $vm.set('destStoresPopulated', true); }; }, @@ -717,6 +735,7 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', { return; } }); + $cf.populateDestinationStores(); } else { var models = []; Ext.Ajax.request({ @@ -969,7 +988,7 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', { if ($cf.recordHasStoreAndOwnPhone(record)) { store = $cf.setCfuAsType(store, record.get('destinationset_id')); Ext.Ajax.request({ - url: '/api/cfmappings/' + localStorage.getItem('subscriber_id'), + url: '/api/currentMapping/' + localStorage.getItem('subscriber_id'), method: 'GET', jsonData: {}, success: function(response) { @@ -989,7 +1008,7 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', { cftMappings = []; }; Ext.Ajax.request({ - url: '/api/cfmappings/' + subscriberId, + url: '/api/currentMapping/' + subscriberId, method: 'PATCH', headers: { 'Content-Type': 'application/json-patch+json' @@ -1196,7 +1215,7 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', { createNewMapping: function(subscriberId, newType, newDestinationsetName, newSourceset, newTimeset) { Ext.Ajax.request({ - url: '/api/cfmappings/' + localStorage.getItem('subscriber_id'), + url: '/api/currentMapping/' + localStorage.getItem('subscriber_id'), method: 'GET', jsonData: {}, success: function(response) { @@ -1208,7 +1227,7 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', { "timeset": newTimeset }); Ext.Ajax.request({ - url: '/api/cfmappings/' + subscriberId, + url: '/api/currentMapping/' + subscriberId, method: 'PATCH', headers: { 'Content-Type': 'application/json-patch+json' diff --git a/classic/src/view/pages/callforward/CallForwardModel.js b/classic/src/view/pages/callforward/CallForwardModel.js index 85e9cee0..f35dd465 100644 --- a/classic/src/view/pages/callforward/CallForwardModel.js +++ b/classic/src/view/pages/callforward/CallForwardModel.js @@ -35,7 +35,9 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardModel', { after_hours_exists_in_api: false, company_hours_exists_in_api: false, last_store_synced: '', - cft_ringtimeout: '15' + cft_ringtimeout: '15', + arrayOfDestModels: null, + destStoresPopulated: false }, formulas: {