espiceland: branch 2.0 r5120 - in /branches/2.0/config: ./ js/

SVN commits to the Asterisk-GUI project asterisk-gui-commits at lists.digium.com
Fri Nov 19 14:32:25 CST 2010


Author: espiceland
Date: Fri Nov 19 14:32:19 2010
New Revision: 5120

URL: http://svnview.digium.com/svn/asterisk-gui?view=rev&rev=5120
Log:
Expose channel groups in the GUI. The GUI will still use groups internally
but will maintain a dedicated group for each trunk, and users can now create
additional groups and add multiple trunks to each.

Modified:
    branches/2.0/config/js/astman.js
    branches/2.0/config/js/callingrules.js
    branches/2.0/config/js/meetme.js
    branches/2.0/config/js/menus.js
    branches/2.0/config/js/pbx.js
    branches/2.0/config/js/pbx2.js
    branches/2.0/config/js/tooltip.js
    branches/2.0/config/js/trunks_analog.js
    branches/2.0/config/trunks_analog.html

Modified: branches/2.0/config/js/astman.js
URL: http://svnview.digium.com/svn/asterisk-gui/branches/2.0/config/js/astman.js?view=diff&rev=5120&r1=5119&r2=5120
==============================================================================
--- branches/2.0/config/js/astman.js (original)
+++ branches/2.0/config/js/astman.js Fri Nov 19 14:32:19 2010
@@ -62,7 +62,10 @@
 	
 	/* This cannot be used if you need to return from the calling
 	function early. The return statement will return from this 
-	anonymous function instead. */
+	anonymous function instead. 
+	
+	This method can also introduce race conditions if you use the array
+	right after calling it. */
 	Array.prototype.each = function(iterator) {
 		for(var i=0 , j = this.length; i < j ; i++ ){
 			iterator(this[i] , i);
@@ -78,16 +81,19 @@
 	
 	Array.prototype.firstAvailable = function(start) {
 		start = (!start)? 1 : Number( start );
-		if(!this.length)
+		if(!this.length){
 			return start;
-		for( var y=0, x=[], z=this.length ; y < z ; y++ ){
+		}
+		var x = [];
+		for( var y=0 ; y < this.length ; y++ ){
 			var NT = Number(this[y]) ;
 			if( NT < start )
 				continue;
 			x.push(NT);
 		}
-		if( !x.length )
+		if( !x.length ){
 			return start;
+		}
 		while(true){
 			if( x.contains(start) ){
 				start++;
@@ -1108,7 +1114,15 @@
 			case 'select-one':
 				return el.value ; //.trim()
 				break;
-
+			case 'select-multiple':
+				var res = [];
+				for (var i = 0 ; i < el.options.length; i++){
+					if (el.options[i].selected){
+						res.push(el.options[i].value)
+					}
+				}
+				return res;
+				break;
 			case 'text':
 			case 'textarea':
 			case 'password':
@@ -2198,7 +2212,7 @@
 			} 
 		},
 
-		append: function(el,txt, val){ // ASTGUI.selectbox.append(el,txt,val);
+		append: function(el, txt, val){ // ASTGUI.selectbox.append(el,txt,val);
 			if ( typeof el == 'string'){ el = _$(el) ; }
 			el.options[el.options.length] = new Option (txt,val);
 		},
@@ -2231,6 +2245,16 @@
 			for (var x=0; x < el.options.length; x++) {
 				if (el.options[x].value == opt){
 					el.selectedIndex = x;
+				}
+			}
+		},
+
+		selectOptionMultiple: function(el, opt){ // ASTGUI.selectbox.selectOption(el,opt)
+			if ( typeof el == 'string'){ el = _$(el) ; }
+			for (var x=0; x < el.options.length; x++) {
+				if (el.options[x].value == opt){
+					//el.selectedIndex = x;
+					el.options[x].selected = true;
 				}
 			}
 		},
@@ -2568,6 +2592,10 @@
 				ASTGUI.selectbox.selectOption(el, val);
 				if( tmp_dfalt && !val ) ASTGUI.selectbox.selectOption(el, tmp_dfalt);
 				break;
+			case 'select-multiple':
+				ASTGUI.selectbox.selectOptionMultiple(el, val);
+				if( tmp_dfalt && !val ) ASTGUI.selectbox.selectOption(el, tmp_dfalt);
+				break;
 			default:
 				break;
 		}

Modified: branches/2.0/config/js/callingrules.js
URL: http://svnview.digium.com/svn/asterisk-gui/branches/2.0/config/js/callingrules.js?view=diff&rev=5120&r1=5119&r2=5120
==============================================================================
--- branches/2.0/config/js/callingrules.js (original)
+++ branches/2.0/config/js/callingrules.js Fri Nov 19 14:32:19 2010
@@ -55,6 +55,9 @@
 	EDIT_CR_RULE = b;
 	var tmp_cr = ASTGUI.parseContextLine.obCallingRule(b) ;
 
+	DOM_new_crl_trunk.selectedIndex = -1;
+	DOM_new_crl_fotrunk.selectedIndex = -1;
+ 
 	DOM_new_crl_name.value = EDIT_CR.withOut(ASTGUI.contexts.CallingRulePrefix) ;
 	DOM_new_crl_name.disabled = true;
 	DOM_new_crl_pattern.value = tmp_cr.pattern ;
@@ -65,14 +68,37 @@
 		_$('toLocalDest').checked = true;
 	}else{
 		_$('toLocalDest').checked = false;
-		ASTGUI.selectbox.selectOption(DOM_new_crl_trunk, tmp_cr.firstTrunk );
+ 		/* if the trunk is not analog, we can use this value as is. If it is,
+ 		we need to figure out if it has been converted to a group_X name */
+ 		if(!parent.pbx.trunks.isAnalog(tmp_cr.firstTrunk)){
+ 			ASTGUI.updateFieldToValue(DOM_new_crl_trunk, tmp_cr.firstTrunk);
+ 		}else if(tmp_cr.firstTrunk.indexOf('group_') > -1){
+ 			ASTGUI.updateFieldToValue(DOM_new_crl_trunk, tmp_cr.firstTrunk);
+ 		}else{
+ 			var trunk1_name = parent.pbx.trunks.getName(tmp_cr.firstTrunk);
+ 			var ded_group = parent.pbx.trunks.getDedicatedGroup(trunk1_name);
+ 			// if ded_group is null, the trunk is misconfigured; this should never happen
+ 			ded_group = "group_" + (ded_group ? ded_group : "0");
+ 			ASTGUI.updateFieldToValue(DOM_new_crl_trunk, ded_group);
+ 		}
 
 		DOM_new_crl_tr_stripx.value = tmp_cr.stripdigits_firstTrunk  ;
 		DOM_new_crl_tr_prepend.value = tmp_cr.firstPrepend ;
 		DOM_new_crl_tr_filter.value = tmp_cr.firstFilter;
 		if(tmp_cr.secondTrunk){
 			DOM_new_crl_foChkbx.checked = true 
-			ASTGUI.selectbox.selectOption(DOM_new_crl_fotrunk, tmp_cr.secondTrunk );
+ 			if(!parent.pbx.trunks.isAnalog(tmp_cr.secondTrunk)){
+ 				//ASTGUI.selectbox.selectOption(DOM_new_crl_fotrunk, tmp_cr.secondTrunk);
+ 				ASTGUI.updateFieldToValue(DOM_new_crl_fotrunk, tmp_cr.secondTrunk);
+ 			}else if(tmp_cr.secondTrunk.indexOf('group_') > -1){
+ 				ASTGUI.updateFieldToValue(DOM_new_crl_fotrunk, tmp_cr.secondTrunk);
+ 			}else{
+ 				var trunk2_name = parent.pbx.trunks.getName(tmp_cr.secondTrunk);
+ 				var ded_group = parent.pbx.trunks.getDedicatedGroup(trunk2_name);
+ 				// if ded_group is null, the trunk is misconfigured; this should never happen
+ 				ded_group = "group_" + (ded_group ? ded_group : "0");
+ 				ASTGUI.updateFieldToValue(DOM_new_crl_fotrunk, ded_group);
+ 			}
 			DOM_new_crl_fotr_stripx.value = tmp_cr.stripdigits_secondTrunk ;
 			DOM_new_crl_fotr_prepend.value = tmp_cr.secondPrepend ;
 			DOM_new_crl_fotr_filter.value = tmp_cr.secondFilter;
@@ -120,7 +146,8 @@
 		ASTGUI.events.add( DOM_new_crl_foChkbx, 'change' , en_db_fofields);
 		ASTGUI.events.add( DOM_new_cr_button , 'click' ,  newCallingRule_form);
 
-		var t = parent.pbx.trunks.list();
+ 		// list non-analog trunks by trunk.
+ 		var t = parent.pbx.trunks.list({iax: true, providers: true, sip: true});
 		var TMP_FORSORT = [];
 		t.each(function(item){
 			TMP_FORSORT.push( parent.pbx.trunks.getName(item) + ':::::::' +  item);
@@ -132,6 +159,13 @@
 			ASTGUI.selectbox.append( DOM_new_crl_fotrunk , a[0], a[1] );
 		});
 
+ 		// list analog trunks by group.
+ 		var g = parent.pbx.trunks.listAllGroups();
+ 		g.each( function(group){
+ 			ASTGUI.selectbox.append( DOM_new_crl_trunk, parent.pbx.trunks.getGroupDescription(group), 'group_' + group);
+ 			ASTGUI.selectbox.append( DOM_new_crl_fotrunk , parent.pbx.trunks.getGroupDescription(group), 'group_' + group);
+ 		});
+ 
 		var modules_show = ASTGUI.cliCommand('module show');
 		if( modules_show.contains('res_skypeforasterisk') && modules_show.contains('chan_skype') ){
 			ASTGUI.selectbox.append( DOM_new_crl_trunk , 'Skype', 'Skype');
@@ -200,8 +234,8 @@
 				addCell( newRow , { html: tmp_cr.pattern });
 
 				if( tmp_cr.hasOwnProperty('firstTrunk') ){
-					addCell( newRow , { html: tmp_cr.firstTrunk ? ( parent.pbx.trunks.getName(tmp_cr.firstTrunk) || '<i><font color=red>Invalid Trunk</font></i>' ) : '<i><font color=red>None Assigned</font></i>' });
-					addCell( newRow , { html: tmp_cr.secondTrunk ? ( parent.pbx.trunks.getName(tmp_cr.secondTrunk) || '<i><font color=red>Invalid Trunk</font></i>' ): '<i>None Selected</i>' });
+ 					addCell( newRow , { html: trunkHtml(tmp_cr.firstTrunk) });
+ 					addCell( newRow , { html: trunkHtml(tmp_cr.secondTrunk) });
 				}else{
 					addCell( newRow , { html:  '<i><font color=blue>Local Destination : ' + ASTGUI.parseContextLine.showAs(tmp_cr.destination) + '</font></i>', align: 'left', colspan : 2 });
 				}
@@ -223,6 +257,21 @@
 	})();
 };
 
+var trunkHtml = function(trunk){
+	if(!trunk){ return '<i><font color=red>None Assigned</font></i>'; }
+	var trunk_name = parent.pbx.trunks.getName(trunk);
+	if(trunk_name) { return trunk_name; }
+ 	if(trunk.indexOf('group_' > -1)){ // it's a new-style analog trunk
+		var group = trunk.replace('group_',"");
+		var tr = parent.pbx.trunks.getTrunkNamesByGroup(group);
+		var trstr = tr.join(", ");
+		if (trstr.length > 30){
+			trstr = trstr.substr(30) + '...';
+		}
+		return "Group " + group + "(" + trstr + ")";
+	}
+	return '<i><font color=red>Invalid Trunk\"' + trunk + '\"</font></i>';
+};
 
 var localajaxinit = function() {
 	top.document.title = "Edit Calling Rules";
@@ -255,27 +304,27 @@
 	var x = new listOfActions('extensions.conf');
 	x.new_action('delcat', 'CallingRule_Longdistance', '', '');
 	x.new_action('newcat', 'CallingRule_Longdistance', '', '');
-	x.new_action('append', 'CallingRule_Longdistance', 'exten', '_91XXXXXXXXXX!,1,Macro(' + ASTGUI.contexts.dialtrunks + ',${}/${FILTER(0-9,${EXTEN:1})}, , , )' );
+	x.new_action('append', 'CallingRule_Longdistance', 'exten', '_91XXXXXXXXXX!,1,Macro(' + ASTGUI.contexts.dialtrunks + ',${}/${FILTER(0123456789,${EXTEN:1})}, , , )' );
 
 	x.new_action('delcat', 'CallingRule_IAXTEL', '', '');
 	x.new_action('newcat', 'CallingRule_IAXTEL', '', '');
-	x.new_action('append', 'CallingRule_IAXTEL', 'exten', '_91700XXXXXXX!,1,Macro(' + ASTGUI.contexts.dialtrunks + ',${}/${FILTER(0-9,${EXTEN:1})}, , , )' );
+	x.new_action('append', 'CallingRule_IAXTEL', 'exten', '_91700XXXXXXX!,1,Macro(' + ASTGUI.contexts.dialtrunks + ',${}/${FILTER(0123456789,${EXTEN:1})}, , , )' );
 	
 	x.new_action('delcat', 'CallingRule_Local_AreaCode', '', '');
 	x.new_action('newcat', 'CallingRule_Local_AreaCode', '', '');
-	x.new_action('append', 'CallingRule_Local_AreaCode', 'exten', '_9256XXXXXXX!,1,Macro(' + ASTGUI.contexts.dialtrunks + ',${}/${FILTER(0-9,${EXTEN:4})}, , , )' );
+	x.new_action('append', 'CallingRule_Local_AreaCode', 'exten', '_9256XXXXXXX!,1,Macro(' + ASTGUI.contexts.dialtrunks + ',${}/${FILTER(0123456789,${EXTEN:4})}, , , )' );
 
 	x.new_action('delcat', 'CallingRule_International', '', '');
 	x.new_action('newcat', 'CallingRule_International', '', '');
-	x.new_action('append', 'CallingRule_International', 'exten', '_9011XXXXX.,1,Macro(' + ASTGUI.contexts.dialtrunks + ',${}/${FILTER(0-9,${EXTEN:1})}, , , )' );
+	x.new_action('append', 'CallingRule_International', 'exten', '_9011XXXXX.,1,Macro(' + ASTGUI.contexts.dialtrunks + ',${}/${FILTER(0123456789,${EXTEN:1})}, , , )' );
 
 	x.new_action('delcat', 'CallingRule_Local_7_digits', '', '');
 	x.new_action('newcat', 'CallingRule_Local_7_digits', '', '');
-	x.new_action('append', 'CallingRule_Local_7_digits', 'exten', '_9XXXXXXX!,1,Macro(' + ASTGUI.contexts.dialtrunks + ',${}/${FILTER(0-9,${EXTEN:1})}, , , )' );
+	x.new_action('append', 'CallingRule_Local_7_digits', 'exten', '_9XXXXXXX!,1,Macro(' + ASTGUI.contexts.dialtrunks + ',${}/${FILTER(0123456789,${EXTEN:1})}, , , )' );
 
 	x.new_action('delcat', 'CallingRule_Emergency', '', '');
 	x.new_action('newcat', 'CallingRule_Emergency', '', '');
-	x.new_action('append', 'CallingRule_Emergency', 'exten', '_911!,1,Macro(' + ASTGUI.contexts.dialtrunks + ',${}/${FILTER(0-9,${EXTEN:1})}, , , )' );
+	x.new_action('append', 'CallingRule_Emergency', 'exten', '_911!,1,Macro(' + ASTGUI.contexts.dialtrunks + ',${}/${FILTER(0123456789,${EXTEN:1})}, , , )' );
 
 
 	x.callActions(function(){
@@ -344,6 +393,15 @@
 			return ;
 		}
 
+		var g1cid = '';
+		var g2cid = '';
+		if(t1.indexOf("group_") > -1){
+			g1cid = parent.pbx.trunks.getTrunkIdByName(t1);
+		}
+		if(t2.indexOf("group_") > -1){
+			g2cid = parent.pbx.trunks.getTrunkIdByName(t2);
+		}
+
 		var tmp_stripx = DOM_new_crl_tr_stripx.value || '0' ;
 		var tmp_fotr_stripx = DOM_new_crl_fotr_stripx.value || '0' ;
 		var tmp_checkThis = ( DOM_new_crl_pattern.value.beginsWith('_') ) ?  DOM_new_crl_pattern.value.length -1 :  DOM_new_crl_pattern.value.length ;
@@ -378,8 +436,8 @@
 		}
 		foTrunk_Build_str = ',' + foTrunk_Build_str;
 
-		var t1_cidarg = ( t1 == 'Skype') ? ',' : ',' + t1 ;
-		var t2_cidarg = ( t2 == 'Skype') ? ',' : ',' + t2 ;
+		var t1_cidarg = ( t1 == 'Skype') ? ',' : ',' + (g1cid ? g1cid : t1);
+		var t2_cidarg = ( t2 == 'Skype') ? ',' : ',' + (g2cid ? g2cid : t2);
 		var as = DOM_new_crl_pattern.value + ',1,Macro(' + ASTGUI.contexts.dialtrunks + Trunk_Build_str + foTrunk_Build_str + t1_cidarg + t2_cidarg + caller_id + ')' ;
 	}
 

Modified: branches/2.0/config/js/meetme.js
URL: http://svnview.digium.com/svn/asterisk-gui/branches/2.0/config/js/meetme.js?view=diff&rev=5120&r1=5119&r2=5120
==============================================================================
--- branches/2.0/config/js/meetme.js (original)
+++ branches/2.0/config/js/meetme.js Fri Nov 19 14:32:19 2010
@@ -59,7 +59,9 @@
 		meetme_rooms.sortNumbers();
 		meetme_rooms.each( function(this_room){
 			var this_MEETME = ASTGUI.cloneObject(parent.sessionData.pbxinfo.conferences[this_room]) ;
-			var room_options = this_MEETME['configOptions'].split("${EXTEN}")[1].betweenXY(',',')') ;
+			var a = this_MEETME['configOptions'].split("${EXTEN}");
+			if(a.length <= 1){ return; }
+			var room_options = a[1].betweenXY(',',')') ;
 
 			var newRow = DOM_table_mml.insertRow(-1);
 			newRow.className = ((DOM_table_mml.rows.length)%2==1)?'odd':'even';

Modified: branches/2.0/config/js/menus.js
URL: http://svnview.digium.com/svn/asterisk-gui/branches/2.0/config/js/menus.js?view=diff&rev=5120&r1=5119&r2=5120
==============================================================================
--- branches/2.0/config/js/menus.js (original)
+++ branches/2.0/config/js/menus.js Fri Nov 19 14:32:19 2010
@@ -3,7 +3,7 @@
  *
  * menus.html functions
  *
- * Copyright (C) 2006-2008, Digium, Inc.
+ * Copyright (C) 2006-2010, Digium, Inc.
  *
  * Pari Nannapaneni <pari at digium.com>
  *
@@ -450,7 +450,8 @@
 				if (!parent.ASTGUI.validateFields([_$('newstep_dial_ThisNumber')])) {
 					return;
 				}
-				newstep =  'Macro('+ ASTGUI.contexts.dialtrunks + ',${' + tmp_trunkName + '}/'+ tmp_extern_num +',,'+ tmp_trunkName + ',)' ;
+				var tname = parent.pbx.trunks.getTrunkIdByName(tmp_trunkName);
+				newstep =  'Macro('+ ASTGUI.contexts.dialtrunks + ',${' + tmp_trunkName + '}/'+ tmp_extern_num +',,'+ (tname ? tname : tmp_trunkName) + ',)' ;
 				break;
 			case 'UserEvent':
 				var tmp_EventName = ASTGUI.getFieldValue('newstep_UserEvent_eventname');
@@ -787,7 +788,8 @@
 	})();
 
 	(function(){
-		var t = ASTGUI.cloneObject( parent.pbx.trunks.list() ) ;
+		// list non-analog trunks by trunk.
+		var t = ASTGUI.cloneObject(parent.pbx.trunks.list({iax: true, providers: true, sip: true}));
 		var TMP_FORSORT = [];
 		t.each(function(item){
 			TMP_FORSORT.push( parent.pbx.trunks.getName(item) + ':::::::' +  item);
@@ -798,6 +800,19 @@
 			var a = this_str.split(':::::::');
 			ASTGUI.selectbox.append( trunks_selectbox, 'via Trunk ' + a[0], a[1] );
 		});
+
+		// list analog trunks by group.
+		var g = parent.pbx.trunks.listAllGroups();
+		g.each( function(group){
+			var tr = parent.pbx.trunks.getTrunkNamesByGroup(group);
+			var trstr = tr.join(", ");
+			if (trstr.length > 30){
+				trstr = trstr.substr(30) + '...';
+			}
+			ASTGUI.selectbox.append( trunks_selectbox, 'via ' + parent.pbx.trunks.getGroupDescription(group), "group_" + group);
+		});
+
+
 	})();
 
 	(function(){

Modified: branches/2.0/config/js/pbx.js
URL: http://svnview.digium.com/svn/asterisk-gui/branches/2.0/config/js/pbx.js?view=diff&rev=5120&r1=5119&r2=5120
==============================================================================
--- branches/2.0/config/js/pbx.js (original)
+++ branches/2.0/config/js/pbx.js Fri Nov 19 14:32:19 2010
@@ -93,10 +93,6 @@
 					check_For_Contexts[ASTGUI.contexts.guitools][4] = 'exten=record_vmenu,n,Record(${var1},0,500,k)';
 				}
 		
-				check_For_Contexts[ 'macro-' + ASTGUI.contexts.localcrcid ] = [
-					'exten=s,1,Set(CALLERID(all)=${IF($[${LEN(${ARG4})} > 2]?${ARG4}:)})',
-					'exten=s,n,Goto(${ARG1},${ARG2},${ARG3})'
-				];
 				check_For_Contexts[ 'macro-' + ASTGUI.contexts.dialtrunks ] = [
 					// "; Macro by =  Brandon Kruse, Matthew O'Gorman, & Erin Spiceland <espiceland at digium.com>",
 					'exten=s,1,GotoIf($[${LEN(${FMCIDNUM})} > 6]?1-fmsetcid,1)',
@@ -939,7 +935,7 @@
 	},
 
 	addAnalogTrunk: function(tr, cbf){ // creates a new analog trunk with the details metioned in tr object, cbf is callback function
-		// usage:: astgui_managetrunks.addAnalogTrunk({ 'zapchan':'2,3,4' , (optional) trunkname:'Ports 2,3,4'} , cbf) ;
+		// usage:: astgui_managetrunks.addAnalogTrunk({ 'zapchan':'2,3,4' , (optional) trunkname:'Ports 2,3,4', (optional) group: '1,2,3'} , cbf) ;
 
 		if( !tr.hasOwnProperty('zapchan') &&  !tr.hasOwnProperty('dahdichan') ){return false;} // zapchan is a required parameter. 
 
@@ -951,9 +947,18 @@
 			var TMP_CHANNELS = tr.dahdichan ;
 			delete tr.dahdichan ;
 		}
-
+		
 		var trunk = astgui_managetrunks.misc.nextAvailableTrunk_x();
-		var group = astgui_managetrunks.misc.nextAvailableGroup();
+		var newgroup = astgui_managetrunks.misc.nextAvailableGroup();
+		var group = '';
+		if( tr.hasOwnProperty('group') ){
+			group = tr.group;
+			if(group.indexOf("New") > -1){
+				group.replace(/New/, newgroup);
+			}
+		}else{
+			group = newgroup;
+		}
 		var ct = ASTGUI.contexts.TrunkDIDPrefix + trunk;
 		// there are no incoming rules for analog trunks - there is only one catch all rule
 		// we only add the fallback extension "exten=s,3,..."  in incoming rules  Ex: 'exten = s,3,Goto(default|6000|1)' 

Modified: branches/2.0/config/js/pbx2.js
URL: http://svnview.digium.com/svn/asterisk-gui/branches/2.0/config/js/pbx2.js?view=diff&rev=5120&r1=5119&r2=5120
==============================================================================
--- branches/2.0/config/js/pbx2.js (original)
+++ branches/2.0/config/js/pbx2.js Fri Nov 19 14:32:19 2010
@@ -3,7 +3,7 @@
  *
  * Core objects and utilities for their configs
  *
- * Copyright (C) 2006-2008, Digium, Inc.
+ * Copyright (C) 2006-2010, Digium, Inc.
  *
  * Ryan Brindley <ryan at digium.com>
  *
@@ -1324,6 +1324,115 @@
 	tech: {analog: 'DAHDI', bri: 'DAHDI', iax: 'IAX2', pri:'DAHDI', sip: 'SIP'}
 };
 
+pbx.trunks.getTrunkIdByName = function(name) {
+	if(name.indexOf('group_' > -1)){
+		var group = name.replace("group_","");
+		var g = this.getTrunkNamesByGroup(group);
+		name = g[0] ? g[0] : name;
+	}
+	var t = this.list();
+	var res = '';
+	t.each(function(item){
+		var type = pbx.trunks.getType(item);
+		if(parent.sessionData.pbxinfo.trunks[type][item]['trunkname'] == name || item == name){
+			res = item;
+		}
+	});
+	return res;
+};
+
+pbx.trunks.getTrunkNamesByGroup = function(group) {
+	var t = this.list({analog: true, bri: true, pri: true});
+	var a = [];
+	t.each(function(item){
+		var type = parent.pbx.trunks.getType(item);
+		var g = parent.sessionData.pbxinfo.trunks[type][item]['group'].toString().split(',');
+		g.each(function(h){
+			if(h == group){
+				var name = parent.sessionData.pbxinfo.trunks[type][item]['trunkname'];
+				if(!a.contains(name)){
+					a.push(parent.sessionData.pbxinfo.trunks[type][item]['trunkname']);
+				}
+			}
+		});
+	});
+	return a.sort();
+};
+
+pbx.trunks.getGroupDescription = function(group){
+	var tr = parent.pbx.trunks.getTrunkNamesByGroup(group);
+	var trstr = tr.join(", ");
+	if (trstr.length > 30){
+		trstr = trstr.substr(30) + '...';
+	}
+	return "Group " + group + " (" + trstr + ")";
+};
+
+pbx.trunks.getDedicatedGroup = function(trunk) {
+	var g = this.listAllGroups();
+	var cur = [];
+	var ded_group = '';
+	g.each(function(group){
+		if(ded_group) { return ded_group; }
+		var t = parent.pbx.trunks.getTrunkNamesByGroup(group);
+		var abort = false;
+		t.each(function(eachtrunk){
+			if(!abort){
+				if(trunk == eachtrunk){
+					ded_group = group;
+					g.push(group);
+				}else{
+					if(ded_group == group){
+						ded_group = '';
+					}
+					abort = true;
+				}
+			}
+		});
+	});
+	return ded_group;
+}
+
+pbx.trunks.makeDedicatedGroup = function() {
+	var newgroup = this.nextAvailGroup();
+	var ext_conf = new listOfSynActions('extensions.conf');
+	ext_conf.new_action('update', 'globals', 'group_' + newgroup, 'DAHDI/g' + newgroup);
+	ext_conf.callActions();
+	return newgroup;
+};
+
+pbx.trunks.listAllGroups = function() {
+	var t = this.list({analog: true, bri: true, pri: true});
+	var a = [];
+	t.each(function(item){
+		var type = parent.pbx.trunks.getType(item);
+		var g = parent.sessionData.pbxinfo.trunks[type][item]['group'].toString().split(',');
+		g.each(function(h){
+			if(!a.contains(h)){
+				a.push(h);
+			}
+		});
+	});
+	return a.sort();
+};
+
+pbx.trunks.formatGroupString = function(group) {
+	var newgroup = this.nextAvailGroup();
+	var oldgroups = group.split(",");
+	// when creating a new group and a dedicated group at the same time,
+	// use the same group for both and don't duplicate it.
+	for(var i = 0; i < oldgroups.length; i++){
+		if (oldgroups[i] == newgroup){ return group; }
+	}
+	if(group.indexOf('New') > -1){
+		var ext_conf = new listOfSynActions('extensions.conf');
+		ext_conf.new_action('update', 'globals', 'group_' + newgroup, 'DAHDI/g' + newgroup);
+		ext_conf.callActions();
+		group = group.replace('New', newgroup);
+	}
+	return group ? group : newgroup;
+};
+
 /**
  * Add a trunk.
  * @param type type of trunk.
@@ -1353,7 +1462,9 @@
 		delete trunk.dahdichan;
 
 		name = this.nextAvailTrunk();
-		group = this.nextAvailGroup();
+		if (trunk.hasOwnProperty('group')) {
+			group = trunk.group;
+		}
 
 		delete trunk.signalling;
 		delete trunk.channel;
@@ -1435,6 +1546,12 @@
 			users_conf.new_action('append', name, 'signalling', sg);
 			users_conf.new_action('append', name, 'channel', ch);
 		});
+		if(!group || group.toString().indexOf(',') > 0){
+			group = this.getDedicatedGroup(name);
+			if(!group){
+				group = this.makeDedicatedGroup();
+			}
+		}
 	}
 
 	/* TODO: get listOfActions to return a response so we know everythings ok! */
@@ -1447,9 +1564,12 @@
 	ext_conf.new_action('newcat', ct, '', '');
 	ext_conf.new_action('delcat', ct + ASTGUI.contexts.TrunkDefaultSuffix, '' ,'');
 	ext_conf.new_action('newcat', ct + ASTGUI.contexts.TrunkDefaultSuffix, '', '');
+	ext_conf.callActions();
+	ext_conf.clearActions();
 	ext_conf.new_action('append', ct, 'include', ct + ASTGUI.contexts.TrunkDefaultSuffix);
 	/* not going to work for analog vv */
 	ext_conf.new_action('update', 'globals', name, tech + '/' + ((type === 'analog') ? 'g' + group : name));
+
 
 	resp = '';
 	resp = ext_conf.callActions();
@@ -1472,6 +1592,16 @@
 	return true;
 };
 
+pbx.trunks.isAnalog = function(trunk) {
+	if(trunk.indexOf("group_" == -1)){
+		var type = this.getType(trunk);
+		if(type == 'analog' || type == 'bri' || type == 'pri'){
+			return true;
+		}
+	}
+	return false;
+};
+
 /**
  * Get Trunk Details.
  * @param trunk
@@ -1517,6 +1647,19 @@
 pbx.trunks.getName = function(trunk) {
 	if (trunk === 'Skype') {
 		return trunk;
+	}
+
+	/* if we got passed a group somehow, see if it's a dedicated group. 
+	If it is, we can get that trunk's name. */
+	if (trunk.indexOf("group_") > -1){
+		trunk = trunk.replace("group_","");
+		var tr = this.getTrunkNamesByGroup(trunk);
+		if(tr.length == 1){
+			return tr[0];
+		}else{
+			top.log.error("group_" + trunk + "describes multiple trunks. I don't know which one's name you want!");
+			return null;
+		}
 	}
 
 	for (var i=0; i < this.trunk_types.length; i++) {
@@ -1528,8 +1671,8 @@
 		}
 	}
 
-	top.log.warn('pbx.trunks.getType: No trunk name found.');
-	top.log.warn('pbx.trunks.getType: Trunk, ' + trunk + ', most like doesn\'t exist');
+	top.log.warn('pbx.trunks.getName: No trunk name found.');
+	top.log.warn('pbx.trunks.getName: Trunk, ' + trunk + ', most likely doesn\'t exist');
 	return null;
 };
 
@@ -1562,6 +1705,9 @@
  * @return type of trunk.
  */
 pbx.trunks.getType = function(trunk) {
+	if(trunk.indexOf("group_") > -1){
+		return "group";
+	}
 	for (var i=0; i < this.trunk_types.length; i++) {
 		if (sessionData.pbxinfo.trunks[this.trunk_types[i]][trunk]) {
 			return this.trunk_types[i];
@@ -1630,19 +1776,22 @@
  */
 pbx.trunks.nextAvailGroup = function() {
 	var nums = [];
-	var trunks = this.list({analog: true, pri: true});
-	var type = 'analog';
+	var trunks = this.list({analog: true, bri: true, pri: true});
 
 	if (!trunks.length) {
 		top.log.warn('pbx.trunks.nextAvailGroup: no trunks');
 	}
 
-	trunks.each(function(trunk) {
-		type = (sessionData.pbxinfo.trunks['analog'].hasOwnProperty(trunk)) ? 'analog' : 'pri';
-		nums.push(sessionData.pbxinfo.trunks[type][trunk]['group']);
-	});
-
-	return nums.firstAvailable();
+	//trunks.each(function(trunk) {
+	for (var i = 0; i < trunks.length; i++){
+		trunk = trunks[i];
+		type = parent.pbx.trunks.getType(trunk);
+		var g = sessionData.pbxinfo.trunks[type][trunk]['group'].toString().split(',');
+		for(var j = 0; j < g.length; j++){
+			nums.push(g[j]);
+		}
+	}
+	return nums.sort().firstAvailable();
 };
 
 /**
@@ -1675,6 +1824,7 @@
 	var exts = config2json({filename: 'extensions.conf', usf:0});
 	var actions = new listOfSynActions('extensions.conf');
 	actions.new_action('delete', 'globals', trunk, '');
+	actions.new_action('delete', 'globals', "CID_" + trunk, '');
 
 	for (var ext in exts) {
 		if (!exts.hasOwnProperty(ext) || !ext.contains(ASTGUI.contexts.TrunkDIDPrefix + trunk)) {
@@ -2340,10 +2490,11 @@
  * @return boolean of success.
  */
 pbx.voice_menus.remove = function(name) {
+	if(!name){ return false; }
 	var acts = new listOfSynActions('extensions.conf');
 	acts.new_action('delcat', name, '', '');
 
-	if (sessionData.pbxinfo.voicemenus[name]['alias_exten'] != '') {
+	if (sessionData.pbxinfo.voicemenus[name] && sessionData.pbxinfo.voicemenus[name]['alias_exten'] != '') {
 		var aext = sessionData.pbxinfo.voicemenus[name]['alias_exten'].lChop('exten=');
 		acts.new_action('delete', ASTGUI.contexts.VoiceMenuExtensions, 'exten', '', aext);
 		acts.new_action('delete', 'default', 'exten', '', aext); /* backward compatibility with gui 1.x */

Modified: branches/2.0/config/js/tooltip.js
URL: http://svnview.digium.com/svn/asterisk-gui/branches/2.0/config/js/tooltip.js?view=diff&rev=5120&r1=5119&r2=5120
==============================================================================
--- branches/2.0/config/js/tooltip.js (original)
+++ branches/2.0/config/js/tooltip.js Fri Nov 19 14:32:19 2010
@@ -445,6 +445,7 @@
 	tooltips['trunks'].en[33] = "<B>CID Signalling :</B> This option defines the type of Caller ID signalling to use: bell (bell202 as used in the United States), v23 (as used in the UK), v23_jp (as used in Japan), or dtmf (as used in Denmark, Sweden, and Holland).";
 	tooltips['trunks'].en[34] = "Flash Time defines the time, in milliseconds, that is generated for a flash operation.";
 	tooltips['trunks'].en[35] = "Receiver Flash Time defines the time, in milliseconds, that is required for the receiver to recognize a flash operation.";
+	tooltips['trunks'].en[43] = "<B>Groups:</B> This GUI uses groups in the backend and creates a group for every trunk to use by itself.  You can also create new groups and add multiple trunks to each one to use in calling rules so that Asterisk will be able to choose one of several available trunks when handling calls.  To create a new group, you must add a trunk to it by selecting \"New\" while adding or editing a trunk. To delete a group, simply remove all trunks from it.";
 	// end of 'advanced options for analog trunks'
 	
 	// BEGIN trunks_voip.html

Modified: branches/2.0/config/js/trunks_analog.js
URL: http://svnview.digium.com/svn/asterisk-gui/branches/2.0/config/js/trunks_analog.js?view=diff&rev=5120&r1=5119&r2=5120
==============================================================================
--- branches/2.0/config/js/trunks_analog.js (original)
+++ branches/2.0/config/js/trunks_analog.js Fri Nov 19 14:32:19 2010
@@ -39,6 +39,17 @@
 	ASTGUI.domActions.checkSelected(ch_chkbxClass, channels) ;
 };
 
+var populateGroupsSelect = function(){
+	parent.pbx.trunks.listAllGroups().each(function(h){
+		var tr = parent.pbx.trunks.getTrunkNamesByGroup(h);
+		var trstr = tr.join(", ");
+		if (trstr.length > 30){
+			trstr = trstr.substr(30) + '...';
+		}
+		ASTGUI.selectbox.append( _$('edit_groups'), parent.pbx.trunks.getGroupDescription(h), h);
+	});
+};
+
 var disable_usedChannels = function(trunk){ // trunk is (optional, used while editing a trunk, for new trunk leave blank)
 	// FXOS -- list of all Analog channels
 	var used = [];
@@ -65,6 +76,7 @@
 	$(DOM_new_ATRNK_DIV).showWithBg();
 	ASTGUI.updateFieldToValue( 'edit_trunkName', '' );
 	ASTGUI.resetTheseFields( Electrical_Fields );
+	DOM_edit_groups_select.selectedIndex = -1;
 };
 
 
@@ -88,6 +100,10 @@
 		ASTGUI.updateFieldToValue( _$(fld) ,  fld_value );
 	} );
 
+	DOM_edit_groups_select.selectedIndex = -1;
+	var g = parent.sessionData.pbxinfo['trunks']['analog'][EDIT_TRUNK]['group'].toString().split(',');
+	g.each(function(group){ ASTGUI.updateFieldToValue(DOM_edit_groups_select, group); });
+
 	ASTGUI.updateFieldToValue(_$('dummy_customCid'), '');
 	ASTGUI.updateFieldToValue( _$('dummy_callerid'), 'asreceived');
 	if (parent.sessionData.pbxinfo['trunks']['analog'][EDIT_TRUNK]['callerid'] && parent.sessionData.pbxinfo['trunks']['analog'][EDIT_TRUNK]['callerid'] != 'asreceived') {
@@ -120,6 +136,7 @@
 	DOM_div_electrical = _$('div_electrical');
 	DOM_div_audioLevels = _$('div_audioLevels');
 	VOLUMES_TBL = _$('TABLE_PORTS_VOLUME');
+	DOM_edit_groups_select = _$('edit_groups');
 
 	FXOS.each(function(item){
 		var lbl = document.createElement( 'label' ) ;
@@ -146,6 +163,9 @@
 		top.cookies.set( 'require_restart' , 'yes' );
 	}
 
+	var groupstr = ASTGUI.getFieldValue(DOM_edit_groups_select) ? ASTGUI.getFieldValue(DOM_edit_groups_select).join(',') : 'New';
+	groupstr = parent.pbx.trunks.formatGroupString(groupstr);
+	
 	if( ASTGUI.getFieldValue('edit_trunkName') ){
 		var trunk_name = ASTGUI.getFieldValue('edit_trunkName');
 	}else{
@@ -158,7 +178,7 @@
 			window.location.reload();
 		};
 
-		var tmp_object = {'zapchan':scs , 'trunkname': trunk_name } ;
+		var tmp_object = {'zapchan':scs , 'trunkname': trunk_name , 'group': groupstr} ;
 		Electrical_Fields.each(function(fld){
 			tmp_object[fld] = ASTGUI.getFieldValue( _$(fld) );
 		});
@@ -171,15 +191,62 @@
 
 		parent.pbx.trunks.add('analog', tmp_object , cbf ) ;
 		return;
-	}
+	}else{
+		var new_groups = groupstr.split(",");
+
+		var ded_group = parent.pbx.trunks.getDedicatedGroup(parent.pbx.trunks.getName(EDIT_TRUNK));
+		if(!new_groups.contains(ded_group)){
+			/* See if there is another dedicated group */
+			var save_old_groups = parent.sessionData.pbxinfo.trunks['analog'][EDIT_TRUNK]['group'].toString().split(',');
+			parent.sessionData.pbxinfo.trunks['analog'][EDIT_TRUNK]['group'] = new_groups.join(',');
+			if(!parent.pbx.trunks.getDedicatedGroup(parent.pbx.trunks.getName(EDIT_TRUNK))){
+				top.log.debug("Can't remove a trunk from its dedicated group.");
+				new_groups.push(ded_group);
+				parent.sessionData.pbxinfo.trunks['analog'][EDIT_TRUNK]['group'] = new_groups.join(',');
+			}
+		}
+	}
+
+	/* If the user just put a trunk into another trunk's dedicated group, we will allow it
+	   but create a new dedicated group for the other trunk. */
+	var ana_trunks = parent.pbx.trunks.list({analog: true});
+	ana_trunks.each(function(item){
+		var ded_group = parent.pbx.trunks.getDedicatedGroup(parent.pbx.trunks.getName(item));
+		/* make sure the user isn't trying to remove the trunk from its dedicated group */
+		if(!ded_group || new_groups.contains(ded_group)){ /* We've just used another trunk's ded_group */
+			/* should never happen. */
+			var new_ded_group = parent.pbx.trunks.makeDedicatedGroup();
+			var g = parent.sessionData.pbxinfo.trunks['analog'][item]['group'].toString().split(',');
+			g.push(new_ded_group);
+			parent.sessionData.pbxinfo.trunks['analog'][item]['group'] = g.join(',');
+			var x = new listOfSynActions('users.conf');
+			x.new_action('update', item, 'group', parent.sessionData.pbxinfo.trunks['analog'][item]['group']);
+			x.callActions();
+		}
+	});
+	var final_groups = [];
+	for( var i = 0 ; i < new_groups.length; i++){
+		if(new_groups[i]){
+			final_groups.push(new_groups[i]);
+		}
+	}
+	delete new_groups;
+	groupstr = final_groups.join(",");
+	parent.sessionData.pbxinfo.trunks['analog'][EDIT_TRUNK]['group'] = groupstr;
+	var x = new listOfSynActions('extensions.conf');
+	x.new_action('update', 'globals', EDIT_TRUNK, "DAHDI/g" + parent.pbx.trunks.getDedicatedGroup(parent.pbx.trunks.getName(EDIT_TRUNK)));
+	x.callActions();
 
 	// just update the selected channels
 	(function(){
 		var x = new listOfSynActions('users.conf');
 			x.new_action('update', EDIT_TRUNK , DAHDICHANNELSTRING, scs );
+			x.new_action('update', EDIT_TRUNK , 'group', groupstr);
 			x.new_action('delete', EDIT_TRUNK , 'gui_volume', '' );
 			x.new_action('delete', EDIT_TRUNK , 'gui_fxooffset', '' );
 			x.new_action('delete', EDIT_TRUNK , 'rxgain', '' );
+			x.callActions();
+			x.clearActions();
 			x.new_action('delete', EDIT_TRUNK , 'txgain', '' );
 			x.new_action('delete', EDIT_TRUNK , 'signalling', '' );
 			x.new_action('delete', EDIT_TRUNK , 'channel', '' );
@@ -188,6 +255,7 @@
 
 		x.new_action('update', EDIT_TRUNK , 'trunkname', trunk_name.guiMetaData() );
 		parent.sessionData.pbxinfo['trunks']['analog'][EDIT_TRUNK]['trunkname'] = trunk_name ;
+		parent.sessionData.pbxinfo['trunks']['analog'][EDIT_TRUNK]['group'] = groupstr;
 
 		var zap_channels = ASTGUI.miscFunctions.chanStringToArray(scs);
 
@@ -259,7 +327,7 @@
 	EDIT_TRUNK = a;
 
 	var trunk_name = getProperty(parent.sessionData.pbxinfo['trunks']['analog'][EDIT_TRUNK], 'trunkname') || EDIT_TRUNK ;
-	if(!confirm("Delete trunk '"+ trunk_name + "' ?")) { return true; }
+	if(!confirm("Delete trunk '"+ trunk_name + "' ?  If you intend to reconfigure this trunk later, you will have to update any calling rules or voice menu Dial actions which use this trunk.")) { return true; }
 	if( parent.pbx.trunks.remove(EDIT_TRUNK) ){ 
 		ASTGUI.feedback({msg:'Deleted Analog trunk ' + "'" + trunk_name + "'" , showfor: 3 , color: '#5D7CBA', bgcolor: '#FFFFFF'}) ;
 		window.location.reload();
@@ -294,6 +362,7 @@
 			}
 		});
 	})();
+	populateGroupsSelect();
 	loadDOMelements();
 	update_AnalogTrunksTable();
 };

Modified: branches/2.0/config/trunks_analog.html
URL: http://svnview.digium.com/svn/asterisk-gui/branches/2.0/config/trunks_analog.html?view=diff&rev=5120&r1=5119&r2=5120
==============================================================================
--- branches/2.0/config/trunks_analog.html (original)
+++ branches/2.0/config/trunks_analog.html Fri Nov 19 14:32:19 2010
@@ -62,6 +62,12 @@
 		<TABLE	align=center cellpadding=2 cellspacing=2 border=0>
 		<TR>	<TD align="right">Channels:</TD>
 			<TD><span id='new_ATRNK_cls_container'></span></TD>
+ 		<TD rowspan=2>
+ 			<b>Groups <img src="images/tooltip_info.gif" tip="en,trunks,43" class='tooltipinfo'> : </b><br> 
+ 			<select id='edit_groups' size=5 multiple='multiple'>
+ 				<option value='New'>New</option>
+ 			</select>
+ 		</TD>
 		</TR>
 		<TR>	<TD align="right" valign=top> <b>Trunk Name <img src="images/tooltip_info.gif" tip="en,trunks,38" class='tooltipinfo'> :</b></TD>
 			<TD align="left"> <input id='edit_trunkName' size=20> </TD>
@@ -73,7 +79,7 @@
 			</TD>
 		</TR>
 		<tr id='HIDE_OnNEW_1'>
-			<td class="field_text" colspan=2 align="center">
+			<td class="field_text" colspan=3 align="center">
 				<div><B>Audio Tuning</B></div>
 				The analog ports that you have chosen should be calibrated for optimum performance. Please ensure that your analog lines are plugged in and proceed with calibration.
 				<div style='margin:10px;'>
@@ -84,7 +90,7 @@
 		</tr>
 
 		<tr id='HIDE_OnNEW_2'>
-			<td class="field_text" colspan=2 align="center">
+			<td class="field_text" colspan=3 align="center">
 				<table align=center width="100%">
 					<tr>	<td class="field_text" align="center" valign=top>
 							Normally you should not have to adjust your analog ports beyond the initial calibration. 
@@ -99,7 +105,7 @@
 		</tr>
 
 		<tr id='HIDE_OnNEW_3'>
-			<td class="field_text" colspan=2 align="center">
+			<td class="field_text" colspan=3 align="center">
 					<div><B>Advanced Options</B></div>
 					<table align=center cellpadding=8 cellspacing=0>
 					<tr>	<td align=right>
@@ -217,7 +223,7 @@
 					</TABLE>
 			</td>
 		</tr>
-		<TR>	<TD colspan=2 align=center valign=middle>
+		<TR>	<TD colspan=3 align=center valign=middle>
 				<span class='guiButtonCancel' onclick='ASTGUI.hideDrag(event);'>Cancel</span>
 				<span class='guiButtonEdit' onclick='new_ATRNK_save_go();' id='new_ATRNK_addUpdateButton'>Update</span>
 			</TD>




More information about the asterisk-gui-commits mailing list