TT#17654 Csc destination grid reordering changes

What has been done
 1. Handle read and write rendering of all non-number destination
    types, parsing sip-uri values from API to human readable types
 2. Implement ability to add new destinations, also non-number types
 3. Move "first ring" section to grid
 4. Implement persistent reordering of destinations in grid, handling
    both changes in termination status, priority order and
    destinationset
 5. Implement color indication of what destinations are terminated
    (inactive/active) and not
 6. Implement logic for handling Ajax PATCH request based on
    destinationset
 7. Some cleanup/refactoring, including change names for CallForward
    store and models, clean up models, defaultValue added where needed
 8. Render combinations of destination types and timeouts correctly
 9. Implement cft/cfu rules. Currently you can't reposition it
 10. Implement dynamic handling of labels in grid

Change-Id: I9f9252412d5ae921b8a4160a51b0acec8e8ea179
changes/12/14312/17
Robert Axelsen 8 years ago
parent 6482aad4c3
commit deeebaff79

@ -1,42 +0,0 @@
Ext.define('NgcpCsc.model.CallForward', {
extend: 'Ext.data.Model',
fields: [{
name: 'id',
type: 'string'
}, {
name: 'type',
type: 'auto'
}, {
name: 'destination_cleaned',
type: 'auto'
}, {
name: 'destination_announcement_id',
type: 'auto'
}, {
name: 'destination',
type: 'auto'
}, {
name: 'priority',
type: 'auto'
}, {
name: 'simple_destination',
type: 'auto'
}, {
name: 'ring_for',
type: 'auto'
}, {
name: 'sourceset',
type: 'auto'
}, {
name: 'timeset',
type: 'auto'
}, {
name: 'destinationset_id',
type: 'auto'
}, {
name: 'destinationset_name',
type: 'auto'
}]
});

@ -0,0 +1,53 @@
Ext.define('NgcpCsc.model.CallForwardDestination', {
extend: 'Ext.data.Model',
fields: [{
name: 'id',
type: 'string'
},
{
name: 'type'
},
{
name: 'destination_displayed'
},
{
name: 'destination'
},
{
name: 'after_termination',
defaultValue: false
},
{
name: 'destination_announcement_id',
defaultValue: null
},
{
name: 'priority',
defaultValue: '1'
},
{
name: 'timeout_displayed'
},
{
name: 'timeout'
},
{
name: 'sourceset'
},
{
name: 'timeset'
},
{
name: 'destinationset_id'
},
{
name: 'destinationset_name'
},
{
name: 'label',
defaultValue: ''
}
]
});

@ -5,14 +5,11 @@ Ext.define('NgcpCsc.model.CallForwardSourceset', {
name: 'id', name: 'id',
type: 'string' type: 'string'
}, { }, {
name: 'sourceset_name', name: 'sourceset_name'
type: 'auto'
}, { }, {
name: 'sourceset_id', name: 'sourceset_id'
type: 'auto'
}, { }, {
name: 'source', name: 'source'
type: 'auto'
}, { }, {
name: 'edit', name: 'edit',
type: 'boolean' type: 'boolean'

@ -5,23 +5,17 @@ Ext.define('NgcpCsc.model.CallForwardTimeset', {
name: 'id', name: 'id',
type: 'string' type: 'string'
}, { }, {
name: 'timeset_name', name: 'timeset_name'
type: 'auto'
}, { }, {
name: 'timeset_id', name: 'timeset_id'
type: 'auto'
}, { }, {
name: 'time_from', name: 'time_from'
type: 'auto'
}, { }, {
name: 'time_to', name: 'time_to'
type: 'auto'
}, { }, {
name: 'day', name: 'day'
type: 'auto'
}, { }, {
name: 'closed', name: 'closed'
type: 'auto'
}] }]
}); });

@ -1,9 +1,9 @@
Ext.define('NgcpCsc.store.CallForward', { Ext.define('NgcpCsc.store.CallForwardDestinations', {
extend: 'Ext.data.Store', extend: 'Ext.data.Store',
storeId: 'CallForward', storeId: 'CallForwardDestinations',
model: 'NgcpCsc.model.CallForward', model: 'NgcpCsc.model.CallForwardDestination',
proxy: { proxy: {
type: 'ngcp-api', type: 'ngcp-api',

@ -92,3 +92,12 @@
} }
} }
} }
.below-termination {
background: #FFB0C4;
color: grey;
}
.above-termination {
background: #B0FFC5;
color: black;
}

@ -50,20 +50,6 @@ Ext.define('NgcpCsc.view.login.LoginController', {
} }
}, },
loadSubscriberDomain: function () {
Ext.Ajax.request({
url: window.location.origin + '/api/subscribers/' + localStorage.getItem('subscriber_id'),
success: function(response, opts) {
var decodedResponse = Ext.decode(response.responseText);
var domain = decodedResponse.domain;
localStorage.setItem('domain', domain);
},
failure: function(response, opts) {
console.log('server-side failure with status code ' + response.status);
}
});
},
unsuccessLogin: function(response) { unsuccessLogin: function(response) {
localStorage.removeItem('jwt'); localStorage.removeItem('jwt');
Ext.Msg.alert('Error', 'Username or Password not valid!'); Ext.Msg.alert('Error', 'Username or Password not valid!');

@ -21,12 +21,23 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', {
} }
}, },
destinationDropped: function (node, data, overModel, dropPosition, eOpts) { destinationDropped: function(node, data, overModel, dropPosition, eOpts) {
// TODO: Leaving uncommented code here for upcoming task #17654 var dropRec = data.records[0];
// var store = Ext.getStore('everybody-always-CallForwardBusy'); var store = overModel.store;
// Ext.each(store.getRange(), function(record) { var recIndex = store.indexOf(dropRec);
// console.log(record.get('destination_cleaned')); var adjacentRec = dropPosition === 'before' ? store.getAt(recIndex+1) : store.getAt(recIndex-1);
// }) var destinationsetId = adjacentRec.get('destinationset_id') === dropRec.get('destinationset_id') ? dropRec.get('destinationset_id') : adjacentRec.get('destinationset_id');
var destinationsetName = adjacentRec.get('destinationset_name') === dropRec.get('destinationset_name') ? dropRec.get('destinationset_name') : adjacentRec.get('destinationset_name');
var afterTermination = adjacentRec.get('after_termination') === dropRec.get('after_termination') ? dropRec.get('after_termination') : adjacentRec.get('after_termination');
var priority = adjacentRec.get('priority') === dropRec.get('priority') ? dropRec.get('priority') : adjacentRec.get('priority');
var type = adjacentRec.get('type') === dropRec.get('type') ? dropRec.get('type') : adjacentRec.get('type');
dropRec.set('destinationset_id', destinationsetId);
dropRec.set('destinationset_name', destinationsetName);
dropRec.set('after_termination', afterTermination);
dropRec.set('priority', priority);
dropRec.set('type', type);
this.setLabelTerminationType(store);
store.sync();
}, },
cfTimesetStoreLoaded: function(store, data) { cfTimesetStoreLoaded: function(store, data) {
@ -46,7 +57,7 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', {
if (/(After|Company)\s(Hours)/.test(timesetName)) { if (/(After|Company)\s(Hours)/.test(timesetName)) {
var times = me.getModelValuesFromTimesData(timeset.times[0]); var times = me.getModelValuesFromTimesData(timeset.times[0]);
Ext.each(times.days, function (weekday) { Ext.each(times.days, function (weekday) {
var cfModel = Ext.create('NgcpCsc.model.CallForward', { var cfModel = Ext.create('NgcpCsc.model.CallForwardDestination', {
id: Ext.id(), id: Ext.id(),
timeset_name: timesetName, timeset_name: timesetName,
timeset_id: timesetId, timeset_id: timesetId,
@ -95,7 +106,7 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', {
var sourcesetId = sourceset.id; var sourcesetId = sourceset.id;
me.setVmToTrue(sourcesetName); me.setVmToTrue(sourcesetName);
Ext.each(sourceset.sources, function (sourceEntry) { Ext.each(sourceset.sources, function (sourceEntry) {
var cfModel = Ext.create('NgcpCsc.model.CallForward', { var cfModel = Ext.create('NgcpCsc.model.CallForwardDestination', {
id: Ext.id(), id: Ext.id(),
sourceset_name: sourcesetName, sourceset_name: sourcesetName,
sourceset_id: sourcesetId, sourceset_id: sourcesetId,
@ -125,6 +136,24 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', {
}; };
}, },
sortDestinationsetByPriority: function (destinations) {
var sorted = destinations.sort(function(a, b) {
return parseFloat(a.priority) - parseFloat(b.priority);
});
return sorted;
},
addCftOwnPhone: function (destinations) {
if (destinations.length > 0) {
destinations.unshift({
"announcement_id": null,
"destination": "own phone",
"priority": 1,
"timeout": 15
})
}
},
cfStoreLoaded: function(store, data) { cfStoreLoaded: function(store, data) {
var me = this; var me = this;
var cfTypeArrayOfObjects = [data.get('cfu'), data.get('cft'), data.get('cfb'), data.get('cfna')]; var cfTypeArrayOfObjects = [data.get('cfu'), data.get('cft'), data.get('cfb'), data.get('cfna')];
@ -143,9 +172,11 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', {
var decodedResponse = Ext.decode(response.responseText); var decodedResponse = Ext.decode(response.responseText);
if (decodedResponse._embedded) { if (decodedResponse._embedded) {
var destinationsets = decodedResponse._embedded['ngcp:cfdestinationsets']; var destinationsets = decodedResponse._embedded['ngcp:cfdestinationsets'];
destinationsets[0].destinations = me.sortDestinationsetByPriority(destinationsets[0].destinations);
me.getView()._preventReLoad = true; // assumes there is no need to reload the store me.getView()._preventReLoad = true; // assumes there is no need to reload the store
Ext.each(cfTypeArrayOfObjects, function (cfTypeObjects, index) { Ext.each(cfTypeArrayOfObjects, function (cfTypeObjects, index) {
var cfType = cfTypes[index]; var cfType = cfTypes[index];
cfType !== 'cft' && me.addCftOwnPhone(destinationsets[0].destinations); // if 'cft' we invoke addCftOwnPhone()
Ext.each(cfTypeObjects, function(cfTypeObject) { Ext.each(cfTypeObjects, function(cfTypeObject) {
var destinationsetName = cfTypeObject.destinationset; var destinationsetName = cfTypeObject.destinationset;
var sourcesetName = cfTypeObject.sourceset; var sourcesetName = cfTypeObject.sourceset;
@ -154,22 +185,23 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', {
Ext.each(destinationsets, function(destinationset) { Ext.each(destinationsets, function(destinationset) {
if (destinationset.name == destinationsetName) { if (destinationset.name == destinationsetName) {
for (item in destinationset.destinations) { for (item in destinationset.destinations) {
var destinationToUse = me.getDestinationFromSipId(destinationset.destinations[item].destination); var destinationToDisplayInGrid = me.getDestinationFromSipId(destinationset.destinations[item].destination);
var destinationAnnouncementId = destinationset.announcement_id; var destinationAnnouncementId = destinationset.announcement_id;
var destination = destinationset.destinations[item].destination; var destination = destinationset.destinations[item].destination;
var priority = destinationset.destinations[item].priority; var priority = destinationset.destinations[item].priority;
var simpleDestination = destinationset.destinations[item].simple_destination; var timeout = destinationset.destinations[item].timeout;
var destinationId = destinationset.id; var destinationId = destinationset.id;
var destinationName = destinationset.name; var destinationName = destinationset.name;
var ringFor = destinationToUse == 'Voicemail' ? '' : destinationset.destinations[item].timeout; // Removes timeout if destination is not a number
var cbModel = Ext.create('NgcpCsc.model.CallForward', { var ringFor = !Ext.isNumber(parseInt(destinationToDisplayInGrid)) ? '' : destinationset.destinations[item].timeout;
var cbModel = Ext.create('NgcpCsc.model.CallForwardDestination', {
type: cfType, type: cfType,
destination_cleaned: destinationToUse, destination_displayed: destinationToDisplayInGrid,
destination_announcement_id: destinationAnnouncementId,
destination: destination, destination: destination,
destination_announcement_id: destinationAnnouncementId,
priority: priority, priority: priority,
simple_destination: simpleDestination, timeout_displayed: ringFor,
ring_for: ringFor, timeout: timeout,
sourceset: sourcesetName, sourceset: sourcesetName,
timeset: timesetName, timeset: timesetName,
destinationset_id: destinationId, destinationset_id: destinationId,
@ -202,24 +234,34 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', {
}, },
cfStoreBeforeSync: function(store, options) { cfStoreBeforeSync: function(store, options) {
// TODO: #17654 Ensure we also have ability to display and write all
// required destination types, like voicemail, fax, conference, etc
var me = this; var me = this;
var recordsToSend = []; var recordsToSend = [];
delete options['destroy']; delete options['destroy'];
delete options['create']; delete options['create'];
delete options['update'];
Ext.each(store.getRange(), function(record) { Ext.each(store.getRange(), function(record) {
var data = record.getData(); var data = record.getData();
switch (recordsToSend.length === 0 || !me.destinationIdExistsInArray(recordsToSend, data.destinationset_id)) { if (data.destination !== 'own phone') {
case true: switch (recordsToSend.length === 0 || !me.destinationIdExistsInArray(recordsToSend, data.destinationset_id)) {
recordsToSend.push({id: data.destinationset_id, records: [{ "announcement_id": null, "destination": data.simple_destination, "priority": data.priority, "timeout": data.ring_for }]}); case true:
break; recordsToSend.push({id: data.destinationset_id, records: [{
case false: "announcement_id": null,
recordsToSend.forEach(function (obj, index) { "destination": data.destination,
if (obj.id == data.destinationset_id) { "priority": data.priority,
recordsToSend[index].records.push({ "announcement_id": null, "destination": data.simple_destination, "priority": data.priority, "timeout": data.ring_for }); "timeout": data.timeout }]});
} break;
}) case false:
recordsToSend.forEach(function (obj, index) {
if (obj.id == data.destinationset_id) {
recordsToSend[index].records.push({
"announcement_id": null,
"destination": data.destination,
"priority": data.priority,
"timeout": data.timeout });
};
});
break;
};
}; };
}); });
Ext.each(recordsToSend, function (obj) { Ext.each(recordsToSend, function (obj) {
@ -274,54 +316,36 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', {
return false; return false;
}, },
timesBasedOnRecords: function (store) {
// TODO: Started this, but then discovered the issue leading to creation
// of #18401. Leaving the code in place for upcoming task #18401
var recordsToSend = [];
Ext.each(store.getRange(), function(record) {
var data = record.getData();
// console.log(data.time_from);
// console.log(data.time_to);
// For fields of data that have been changed in the grid, data is in
// this format:
// Tue Jan 01 2008 13:00:00 GMT+0100 (CET)
});
return recordsToSend;
},
cfTimesetBeforeSync: function (store, options) { cfTimesetBeforeSync: function (store, options) {
delete options['destroy']; delete options['destroy'];
delete options['create']; delete options['create'];
delete options['update']; delete options['update'];
var timesetId = store.last().get('timeset_id');
// var recordsToSend = this.timesBasedOnRecords(store);
// TODO: Example ajax request for #18401
// Ext.Ajax.request({
// url: '/api/cftimesets/' + timesetId,
// method: 'PATCH',
// headers: { 'Content-Type': 'application/json-patch+json' },
// jsonData: [{
// "op": "add",
// "path": "/times",
// "value": recordsToSend
// }],
// success: function(response, opts) {
// console.log('server-side success with status code ' + response.status);
// },
// failure: function(response, opts) {
// console.log('server-side failure with status code ' + response.status);
// }
// });
return false; return false;
}, },
getDestinationFromSipId: function (destination) { getDestinationFromSipId: function (destination) {
var splitDestination = destination.split(/(:|@)/); var splitDestination = destination === 'own phone' ? [null, null, 'own phone', null, null] : destination.split(/(:|@)/);
if (splitDestination[4] == 'voicebox.local') { switch (splitDestination[4]) {
return 'Voicemail'; case 'voicebox.local':
} else { return 'Voicemail';
return splitDestination[2]; break;
} case 'conference.local':
return 'Conference';
break;
case 'fax2mail.local':
return 'Fax2Mail';
break;
default:
// Returns parsed destination URI/Number types to make them
// human readable in grid, as well as for any app.local types
// that might exist (callingcard, callthrough, autoattendant,
// officehours, customhours, localuser)
if (!Ext.isNumber(parseInt(splitDestination[2]))) {
return Ext.util.Format.capitalize(splitDestination[2]);
} else {
return splitDestination[2];
};
};
}, },
getGridCategoryFromType: function (type) { getGridCategoryFromType: function (type) {
@ -336,7 +360,7 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', {
case 'cfna': case 'cfna':
return 'CallForwardOffline'; return 'CallForwardOffline';
break; break;
} };
}, },
getTypeFromTypeName: function (type) { getTypeFromTypeName: function (type) {
@ -350,7 +374,7 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', {
case 'Offline': case 'Offline':
return 'cfna'; return 'cfna';
break; break;
} };
}, },
getSourceNameFromSourceSet: function (sourceset) { getSourceNameFromSourceSet: function (sourceset) {
@ -364,7 +388,7 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', {
case null: case null:
return 'everybody-'; return 'everybody-';
break; break;
} };
}, },
getSourceSetFromSourceName: function (sourceset) { getSourceSetFromSourceName: function (sourceset) {
@ -378,7 +402,7 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', {
case null: case null:
return null; return null;
break; break;
} };
}, },
getTimeNameFromTimeSet: function (timeset) { getTimeNameFromTimeSet: function (timeset) {
@ -465,12 +489,60 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', {
}; };
}, },
setLabelTerminationType: function (store) {
var terminationPositionRecord = store.findRecord('destination_displayed', /(Voicemail|Fax2Mail|Conference|Custom-hours|Office-hours|Auto-attendant|Callthrough|Callingcard)/);
var storeCount = store.getCount();
// Sets after_termination value for all records after first non-number
if (terminationPositionRecord && terminationPositionRecord.get('destination_displayed')) {
var terminationPositionIndex = store.indexOf(terminationPositionRecord);
var terminationTrueIndexRange = [];
var terminationFalseIndexRange = [];
for (i = terminationPositionIndex+1; i < storeCount; i++) {
terminationTrueIndexRange.push(i);
};
for (i = terminationPositionIndex; i >= 0; i--) {
terminationFalseIndexRange.push(i);
};
terminationTrueIndexRange.map(function (index) {
store.getAt(index).set('after_termination', true);
});
terminationFalseIndexRange.map(function (index) {
store.getAt(index).set('after_termination', false);
});
};
// Set all cft records to after_termination true if cfu records exist
if (store.findRecord('type', 'cfu') && store.findRecord('type', 'cft')) {
Ext.each(store.getRange(), function(record) {
if (!record.get('after_termination') && record.get('type') === 'cft') {
record.set('after_termination', true);
};
});
};
// Sorts "own phone" to top plus prevents it from being reordered
Ext.each(store.getRange(), function(record) {
if (record.get('destination') === 'own phone') {
record.set('label', 'first ring');
record.set('after_termination', false);
store.remove(record);
store.insert(0, record);
};
});
// Sets "first ring", "then forward to ..." and "" (empty) labels
Ext.each(store.getRange(), function(record, index) {
if (index === 0) {
record.set('label', 'first ring');
} else if (index === 1) {
record.set('label', 'then forward to ...');
} else {
record.set('label', '');
}
});
},
populateDestinationStores: function (models) { populateDestinationStores: function (models) {
var me = this; var me = this;
var gridName = this.getGridCategoryFromType(models[0].get('type'));
var store; var store;
// TODO: #17654 New grid logic and styling with conditions for cft/cfu, var stores = [];
// and remove first ring section
Ext.each(models, function (model) { Ext.each(models, function (model) {
var sourcename = me.getSourceNameFromSourceSet(model.get('sourceset')); var sourcename = me.getSourceNameFromSourceSet(model.get('sourceset'));
var timename = me.getTimeNameFromTimeSet(model.get('timeset')); var timename = me.getTimeNameFromTimeSet(model.get('timeset'));
@ -479,10 +551,14 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', {
store = Ext.getStore(storeName); store = Ext.getStore(storeName);
if (store) { if (store) {
store.add(model); store.add(model);
stores.push(store);
} }
}); });
if (store) { if (store) {
store.commitChanges(); Ext.each(stores, function (store) {
store.commitChanges();
me.setLabelTerminationType(store);
});
} }
}, },
@ -661,7 +737,7 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', {
}, },
success: function(response, opts) { success: function(response, opts) {
var sourcesetId = response.getResponseHeader('Location').split('/')[3]; var sourcesetId = response.getResponseHeader('Location').split('/')[3];
var cfSourcesetModel = Ext.create('NgcpCsc.model.CallForward', { var cfSourcesetModel = Ext.create('NgcpCsc.model.CallForwardSourceset', {
id: Ext.id(), id: Ext.id(),
source: " ", source: " ",
sourceset_name: sourcesetName, sourceset_name: sourcesetName,
@ -720,11 +796,13 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', {
}, },
confirmCFRemoval: function(record) { confirmCFRemoval: function(record) {
var me = this;
var store = record.store; var store = record.store;
if(store){ if(store){
store.remove(record); store.remove(record);
store.sync(); store.sync();
} me.setLabelTerminationType(store);
};
}, },
getStoresArrayFromRoute: function(currentRoute, currentSourceset) { getStoresArrayFromRoute: function(currentRoute, currentSourceset) {
@ -779,12 +857,14 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', {
}, },
renderDestinationColumn: function(value, metaData, record) { renderDestinationColumn: function(value, metaData, record) {
if (record.get('ring_for') === '' && !Ext.isNumber(parseInt(value))) { if (record.get('timeout_displayed') === '' && !Ext.isNumber(parseInt(value))) {
return Ext.String.format('{0}', value); return Ext.String.format('{0}', value);
} else if (record.get('destination') === 'own phone') {
return Ext.String.format('own phone and ring for {0} secs', record.get('timeout_displayed'));
} else if (Ext.isNumber(parseInt(value))) { } else if (Ext.isNumber(parseInt(value))) {
return Ext.String.format('+{0} and ring for {1} secs', value, record.get('ring_for')); return Ext.String.format('+{0} and ring for {1} secs', value, record.get('timeout_displayed'));
} else { } else {
return Ext.String.format('{0} and ring for {1} secs', value, record.get('ring_for')); return Ext.String.format('{0} and ring for {1} secs', value, record.get('timeout_displayed'));
}; };
}, },
@ -942,8 +1022,8 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', {
var simpleDestination = destination; var simpleDestination = destination;
var priority = 1; var priority = 1;
var storeCount = store.getCount(); var storeCount = store.getCount();
var ringFor = destination == 'Voicemail' ? '' : timeout; // Removes timeout if destination is not a number
var destinationCleaned = destination; var ringFor = !Ext.isNumber(parseInt(destination)) ? '' : timeout;
var storeIdSplit = store.storeId.split('-'); var storeIdSplit = store.storeId.split('-');
var newSourcesetName = storeIdSplit[0] == 'everybody' ? null : storeIdSplit[0]; var newSourcesetName = storeIdSplit[0] == 'everybody' ? null : storeIdSplit[0];
var newTimesetName = storeIdSplit[1] == 'always' ? null : storeIdSplit[1]; var newTimesetName = storeIdSplit[1] == 'always' ? null : storeIdSplit[1];
@ -951,39 +1031,36 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', {
var newSourceset = this.getSourceSetFromSourceName(newSourcesetName); var newSourceset = this.getSourceSetFromSourceName(newSourcesetName);
var newTimeset = this.getTimeSetFromTimeSource(newTimesetName); var newTimeset = this.getTimeSetFromTimeSource(newTimesetName);
var newType = this.getTypeFromTypeName(newTypeName); var newType = this.getTypeFromTypeName(newTypeName);
var newDomain = localStorage.getItem('domain'); var newDestination = destination === 'Voicemail' ? 'voicebox' : destination.toLowerCase();
// TODO: #17654 Consider the fact that one destinationset can be in // TODO: Sets default timeout to 10 for non-number types, as can not be
// several grids, so if you write one, update all other grids with // set to null. Not sure if this has any implication, so needs to be
// that same destinationset id // checked with Andreas
var newTimeout = !timeout ? '10' : timeout;
if (!store.last()) { // if store empty we need to create new destset if (!store.last()) { // if store empty we need to create new destset
var newDestinationsetName = 'csc_defined_' + newType; var newDestinationsetName = 'csc_defined_' + newType;
var subscriberId = localStorage.getItem('subscriber_id'); var subscriberId = localStorage.getItem('subscriber_id');
Ext.Ajax.request({ Ext.Ajax.request({
url: '/api/cfdestinationsets/', url: '/api/cfdestinationsets/',
method: 'POST', method: 'POST',
defaultHeaders: 'Prefer: return=representation',
jsonData: { jsonData: {
name: newDestinationsetName, name: newDestinationsetName,
subscriber_id: subscriberId subscriber_id: subscriberId
}, },
success: function(response, opts) { success: function(response, opts) {
var destinationsetId = response.getResponseHeader('Location').split('/')[3]; var destinationsetId = response.getResponseHeader('Location').split('/')[3];
var cfModel = Ext.create('NgcpCsc.model.CallForward', { var cfModel = Ext.create('NgcpCsc.model.CallForwardDestination', {
type: newType, type: newType,
destination_cleaned: destinationCleaned, destination_displayed: destination,
destination_announcement_id: null, destination: newDestination,
destination: 'sip:' + destination + '@' + newDomain, timeout_displayed: ringFor,
// Keeping priority 1 as default for now, as we'll handle priotity timeout: newTimeout,
// with grid "drag-and-drop" widget plugin in upcoming task
priority: 1,
simple_destination: destination,
ring_for: ringFor,
sourceset: newSourceset, sourceset: newSourceset,
timeset: newTimeset, timeset: newTimeset,
destinationset_id: destinationsetId, destinationset_id: destinationsetId,
destinationset_name: newDestinationsetName destinationset_name: newDestinationsetName
}); });
store.add(cfModel); store.add(cfModel);
me.setLabelTerminationType(store);
store.sync(); store.sync();
// Creates new sourceset/timeset if variable is not set to null // Creates new sourceset/timeset if variable is not set to null
newSourceset && me.createNewStandardSet('/api/cfsourcesets/', newSourceset, subscriberId); newSourceset && me.createNewStandardSet('/api/cfsourcesets/', newSourceset, subscriberId);
@ -996,20 +1073,30 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', {
}); });
} else { } else {
var lastRecordInStore = store.last(); var lastRecordInStore = store.last();
var cfModel = Ext.create('NgcpCsc.model.CallForward', { var afterTermination = false;
switch (true) {
case (!lastRecordInStore.get('after_termination') && !Ext.isNumber(parseInt(lastRecordInStore.get('destination_displayed')))):
afterTermination = true;
break;
case (lastRecordInStore.get('after_termination')):
afterTermination = true;
break;
};
var cfModel = Ext.create('NgcpCsc.model.CallForwardDestination', {
type: lastRecordInStore.get('type'), type: lastRecordInStore.get('type'),
destination_cleaned: destinationCleaned, destination_displayed: destination,
destination_announcement_id: null, destination: newDestination,
destination: 'sip:' + destination + '@' + newDomain, after_termination: afterTermination,
priority: 1, priority: lastRecordInStore.get('priority'),
simple_destination: destination, timeout_displayed: ringFor,
ring_for: ringFor, timeout: newTimeout,
sourceset: lastRecordInStore.get('sourceset'), sourceset: lastRecordInStore.get('sourceset'),
timeset: lastRecordInStore.get('timeset'), timeset: lastRecordInStore.get('timeset'),
destinationset_id: lastRecordInStore.get('destinationset_id'), destinationset_id: lastRecordInStore.get('destinationset_id'),
destinationset_name: lastRecordInStore.get('destinationset_name') destinationset_name: lastRecordInStore.get('destinationset_name')
}); });
store.add(cfModel); store.add(cfModel);
me.setLabelTerminationType(store);
store.sync(); store.sync();
} }
}, },
@ -1040,9 +1127,4 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardController', {
store.sync(); store.sync();
} }
// TODO #18401, maybe use a blur or change listener on editors in grid
// editingTimeDone: function () {
//
// }
}); });

@ -37,17 +37,20 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardMainForm', {
store: storeListB store: storeListB
}); });
var busyGrid = Ext.create('NgcpCsc.view.pages.callforward.CallForwardMainGrid', { var busyGrid = Ext.create('NgcpCsc.view.pages.callforward.CallForwardMainGrid', {
store: Ext.create('NgcpCsc.store.CallForward', { id: this._firstprefix + this._secondprefix + 'CallForwardBusy',
store: Ext.create('NgcpCsc.store.CallForwardDestinations', {
storeId: this._firstprefix + this._secondprefix + 'CallForwardBusy' storeId: this._firstprefix + this._secondprefix + 'CallForwardBusy'
}) })
}); });
var onlineGrid = Ext.create('NgcpCsc.view.pages.callforward.CallForwardMainGrid', { var onlineGrid = Ext.create('NgcpCsc.view.pages.callforward.CallForwardMainGrid', {
store: Ext.create('NgcpCsc.store.CallForward', { id: this._firstprefix + this._secondprefix + 'CallForwardOnline',
store: Ext.create('NgcpCsc.store.CallForwardDestinations', {
storeId: this._firstprefix + this._secondprefix + 'CallForwardOnline' storeId: this._firstprefix + this._secondprefix + 'CallForwardOnline'
}) })
}); });
var offlineGrid = Ext.create('NgcpCsc.view.pages.callforward.CallForwardMainGrid', { var offlineGrid = Ext.create('NgcpCsc.view.pages.callforward.CallForwardMainGrid', {
store: Ext.create('NgcpCsc.store.CallForward', { id: this._firstprefix + this._secondprefix + 'CallForwardOffline',
store: Ext.create('NgcpCsc.store.CallForwardDestinations', {
storeId: this._firstprefix + this._secondprefix + 'CallForwardOffline' storeId: this._firstprefix + this._secondprefix + 'CallForwardOffline'
}) })
}); });
@ -94,20 +97,11 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardMainForm', {
layout: 'hbox', layout: 'hbox',
margin: '15 0 0 0', margin: '15 0 0 0',
items: [ items: [
// NOTE: Commenting out this now, and will tackle it as part of #17651
// {
// xtype: 'button',
// html: Ngcp.csc.locales.callforward.change_title[localStorage.getItem('languageSelected')],
// id: this._firstprefix + this._secondprefix + 'lista_titleField-showButton',
// margin: '0 0 0 500',
// handler: 'toggleChangeTitle'
// },
{ {
xtype: 'button', xtype: 'button',
text: Ngcp.csc.locales.callforward.add_new_source[localStorage.getItem('languageSelected')], text: Ngcp.csc.locales.callforward.add_new_source[localStorage.getItem('languageSelected')],
id: this._firstprefix + this._secondprefix + 'addListAButton', id: this._firstprefix + this._secondprefix + 'addListAButton',
margin: '0 0 0 620', margin: '0 0 0 620',
// margin: '0 0 0 10',
width: 135, width: 135,
listeners: { listeners: {
click: 'addEmptySourcesetRow' click: 'addEmptySourcesetRow'
@ -158,21 +152,12 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardMainForm', {
hidden: '{list_b}' hidden: '{list_b}'
}, },
items: [ items: [
// NOTE: Commenting out this now, and will tackle it as part of #17651
// {
// xtype: 'button',
// html: Ngcp.csc.locales.callforward.change_title[localStorage.getItem('languageSelected')],
// id: this._firstprefix + this._secondprefix + 'listb_titleField-showButton',
// margin: '0 0 0 500',
// handler: 'toggleChangeTitle'
// },
{ {
xtype: 'button', xtype: 'button',
text: Ngcp.csc.locales.callforward.add_new_source[localStorage.getItem('languageSelected')], text: Ngcp.csc.locales.callforward.add_new_source[localStorage.getItem('languageSelected')],
id: this._firstprefix + this._secondprefix + 'addListBButton', id: this._firstprefix + this._secondprefix + 'addListBButton',
width: 135, width: 135,
margin: '0 0 0 620', margin: '0 0 0 620',
// margin: '0 0 0 10',
listeners: { listeners: {
click: 'addEmptySourcesetRow' click: 'addEmptySourcesetRow'
} }
@ -182,60 +167,11 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardMainForm', {
xtype: 'container', xtype: 'container',
userCls: 'cf-text cf-subheader', userCls: 'cf-text cf-subheader',
html: Ngcp.csc.locales.callforward.when_phone_online[localStorage.getItem('languageSelected')] html: Ngcp.csc.locales.callforward.when_phone_online[localStorage.getItem('languageSelected')]
}, {
xtype: 'panel',
layout: 'hbox',
id: this._firstprefix + this._secondprefix + 'onlineFirstRingFields',
padding: '0 11 0 0',
width: 500,
margin: '0 0 0 50',
items: [{
xtype: 'combo',
store: 'FirstRingActions',
valueField: 'name',
displayField: 'name',
id: this._firstprefix + this._secondprefix + 'onlineFirstDest',
fieldLabel: Ngcp.csc.locales.callforward.first_ring[localStorage.getItem('languageSelected')],
value: 'Own phone',
allowBlank: false,
editable: false,
listeners: {
change: 'selectRing'
},
flex: 5
}, {
xtype: 'numberfield',
step: 10,
minValue:0,
maxValue: 300,
value: '10',
id: this._firstprefix + this._secondprefix + 'onlineFirstTimeout',
allowBlank: false,
editable: true,
flex: 4,
margin: '0 0 0 10',
bind: {
hidden: '{online_first_timeout_hidden}'
},
fieldLabel: Ngcp.csc.locales.callforward.and_ring_for[localStorage.getItem('languageSelected')]
}, {
xtype: 'container',
html: Ngcp.csc.locales.callforward.secs[localStorage.getItem('languageSelected')],
padding: '7 0 0 20',
flex: 1,
bind: {
hidden: '{online_first_timeout_hidden}'
}
}]
}, { }, {
xtype: 'container', xtype: 'container',
layout: 'hbox', layout: 'hbox',
margin: '10 0 0 50', margin: '10 0 0 50',
items: [{ items: [
xtype: 'container',
html: Ngcp.csc.locales.callforward.then_forward_to[localStorage.getItem('languageSelected')],
userCls: 'cf-thentext'
},
onlineGrid onlineGrid
] ]
}, { }, {
@ -337,11 +273,7 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardMainForm', {
xtype: 'container', xtype: 'container',
layout: 'hbox', layout: 'hbox',
margin: '10 0 0 50', margin: '10 0 0 50',
items: [{ items: [
xtype: 'container',
html: Ngcp.csc.locales.callforward.forward_to[localStorage.getItem('languageSelected')],
userCls: 'cf-thentext'
},
busyGrid busyGrid
] ]
}, { }, {
@ -443,11 +375,7 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardMainForm', {
xtype: 'container', xtype: 'container',
layout: 'hbox', layout: 'hbox',
margin: '10 0 0 50', margin: '10 0 0 50',
items: [{ items: [
xtype: 'container',
html: Ngcp.csc.locales.callforward.forward_to[localStorage.getItem('languageSelected')],
userCls: 'cf-thentext'
},
offlineGrid offlineGrid
] ]
}, { }, {

@ -14,30 +14,22 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardMainGrid', {
dragText: Ngcp.csc.locales.callforward.drag_text[localStorage.getItem('languageSelected')] dragText: Ngcp.csc.locales.callforward.drag_text[localStorage.getItem('languageSelected')]
}, },
markDirty: false, markDirty: false,
emptyText: Ngcp.csc.locales.callforward.nowhere[localStorage.getItem('languageSelected')], emptyText: Ngcp.csc.locales.callforward.forward_to[localStorage.getItem('languageSelected')] + '<span style="padding-left: 40px;">' + Ngcp.csc.locales.callforward.nowhere[localStorage.getItem('languageSelected')] + '</span>',
deferEmptyText: false, deferEmptyText: false,
stripeRows: false, stripeRows: false,
listeners: { listeners: {
drop: 'destinationDropped' drop: 'destinationDropped'
},
getRowClass: function(record, index) {
var afterTermination = record.get('after_termination');
if (afterTermination) {
return 'below-termination';
} else {
return 'above-termination';
}
} }
}, },
// TODO: Leaving this for PUT/PATCH task, as it might make sense to use
// with unmask triggered in controller
// listeners: {
// render: function(grid) {
// grid.body.mask('Loading...');
// var store = grid.getStore();
// Ext.defer(function() {
// store.load;
// }, 100);
// Ext.defer(function() {
// grid.body.unmask();
// }, 600);
// },
// delay: 200
// },
plugins: { plugins: {
ptype: 'cellediting', ptype: 'cellediting',
clicksToEdit: 1 clicksToEdit: 1
@ -47,7 +39,10 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardMainGrid', {
var me = this; var me = this;
me.columns = [{ me.columns = [{
dataIndex: 'destination_cleaned', // Renderer also uses ring_for value dataIndex: 'label',
width: 135
}, {
dataIndex: 'destination_displayed', // Renderer also uses ring_for value
width: 285, width: 285,
renderer: 'renderDestinationColumn' renderer: 'renderDestinationColumn'
}, { }, {

@ -7,11 +7,6 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardTimesetGrid', {
markDirty: false markDirty: false
}, },
// TODO: #18401
// listeners: {
// edit: 'editingTimeDone'
// },
initComponent: function() { initComponent: function() {
this.columns = { this.columns = {
defaults: { defaults: {
@ -25,7 +20,7 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardTimesetGrid', {
flex: 1 flex: 1
}, { }, {
text: Ngcp.csc.locales.common.from[localStorage.getItem('languageSelected')], text: Ngcp.csc.locales.common.from[localStorage.getItem('languageSelected')],
dataIndex: 'time_from', // TODO: #18401 Add listener dataIndex: 'time_from',
xtype: 'widgetcolumn', xtype: 'widgetcolumn',
editable: false, editable: false,
flex: 1, flex: 1,
@ -39,7 +34,7 @@ Ext.define('NgcpCsc.view.pages.callforward.CallForwardTimesetGrid', {
} }
}, { }, {
text: Ngcp.csc.locales.common.to[localStorage.getItem('languageSelected')], text: Ngcp.csc.locales.common.to[localStorage.getItem('languageSelected')],
dataIndex: 'time_to', // TODO: #18401 Add listener dataIndex: 'time_to',
xtype: 'widgetcolumn', xtype: 'widgetcolumn',
editable: false, editable: false,
flex: 1, flex: 1,

@ -6,7 +6,7 @@ Ext.define('NgcpCsc.view.pages.callforward.afterhours.Afterhours', {
ui: 'cf-mainform', ui: 'cf-mainform',
initComponent: function() { initComponent: function() {
var cfInitialStore = Ext.create('NgcpCsc.store.CallForward', { var cfInitialStore = Ext.create('NgcpCsc.store.CallForwardDestinations', {
storeId: 'CallForwardAfterHours', storeId: 'CallForwardAfterHours',
_type: 'afterHours', _type: 'afterHours',
autoLoad: true, autoLoad: true,

@ -8,7 +8,7 @@ Ext.define('NgcpCsc.view.pages.callforward.always.Always', {
viewModel: 'callforward', viewModel: 'callforward',
initComponent: function() { initComponent: function() {
var cfInitialStore = Ext.create('NgcpCsc.store.CallForward',{ var cfInitialStore = Ext.create('NgcpCsc.store.CallForwardDestinations',{
storeId: 'CallForwardAlways', storeId: 'CallForwardAlways',
_type: 'always', _type: 'always',
autoLoad: true, autoLoad: true,

@ -6,7 +6,7 @@ Ext.define('NgcpCsc.view.pages.callforward.companyhours.Companyhours', {
ui: 'cf-mainform', ui: 'cf-mainform',
initComponent: function() { initComponent: function() {
var cfInitialStore = Ext.create('NgcpCsc.store.CallForward', { var cfInitialStore = Ext.create('NgcpCsc.store.CallForwardDestinations', {
storeId: 'CallForwardCompanyHours', storeId: 'CallForwardCompanyHours',
_type: 'companyHours', _type: 'companyHours',
autoLoad: true, autoLoad: true,

Loading…
Cancel
Save