@@ -423,24 +423,93 @@ export class CommandBox {
423423 button . disabled = false ;
424424 }
425425
426- static getSelectedMinionList ( ) {
426+ static _getNodegroupsSelection ( ) {
427+ const allNodeGroups = Utils . getStorageItemObject ( "session" , "nodegroups" ) ;
428+ const allNodeGroupsKeys = Object . keys ( allNodeGroups ) ;
429+
430+ let ret = "" ;
431+ const lst_nodegroups = Utils . getStorageItem ( "session" , "select_nodegroups" , null ) ;
432+ if ( lst_nodegroups ) {
433+ for ( const nodegroup of lst_nodegroups . split ( "," ) ) {
434+ if ( nodegroup === "null" ) {
435+ // the spaces around '(' and before ')' are mandatory
436+ // salt-api returns 500-InternalServerError when missing
437+ // see also https://docs.saltproject.io/en/latest/topics/targeting/compound.html#precedence-matching
438+ ret += " or not ( "
439+ let grplst = "" ;
440+ for ( const grp of allNodeGroupsKeys ) {
441+ grplst += " or N@" + grp ;
442+ }
443+ // strip the prefix " or "
444+ ret += grplst . substring ( 4 ) + " )" ;
445+ } else if ( nodegroup ) {
446+ ret += " or N@" + nodegroup ;
447+ }
448+ }
449+ }
450+ return ret ;
451+ }
452+
453+ static _getMinionSelection ( ) {
454+ let ret = "" ;
455+ const lst_minions = Utils . getStorageItem ( "session" , "select_minions" , null ) ;
456+ if ( lst_minions ) {
457+ let minionlist = "" ;
458+ for ( const minion of lst_minions . split ( "," ) ) {
459+ if ( minion ) {
460+ minionlist += "," + minion ;
461+ }
462+ }
463+ if ( minionlist ) {
464+ // substring removes the extra ","
465+ ret += " or L@" + minionlist . substring ( 1 ) ;
466+ }
467+ }
468+ return ret ;
469+ }
470+
471+ static getSelectedItemList ( pSessionKeys ) {
427472 const selectVisible = Utils . getStorageItemBoolean ( "session" , "select_visible" , false ) ;
428473 if ( ! selectVisible ) {
429474 return null ;
430475 }
431476
432- // only when the selection is visible
433- const selectMinions = Utils . getStorageItem ( "session" , "select_minions" , "" ) ;
434- const lst = selectMinions . split ( "," ) . sort ( ) ;
435- while ( lst . length > 0 && lst [ 0 ] === "" ) {
436- lst . shift ( ) ;
477+ let target = "" ;
478+
479+ if ( pSessionKeys . includes ( "select_nodegroups" ) ) {
480+ target += CommandBox . _getNodegroupsSelection ( ) ;
437481 }
438- // and only when there is a selection
439- if ( lst . length == 0 ) {
482+
483+ if ( pSessionKeys . includes ( "select_minions" ) ) {
484+ target += CommandBox . _getMinionSelection ( ) ;
485+ }
486+
487+ if ( pSessionKeys . includes ( "select_keys" ) ) {
488+ const lst_keys = Utils . getStorageItem ( "session" , "select_keys" , null ) ;
489+ if ( lst_keys ) {
490+ let keylist = "" ;
491+ for ( const key of lst_keys . split ( "," ) ) {
492+ if ( key ) {
493+ keylist += "," + key ;
494+ }
495+ }
496+ // substring removes the extra ","
497+ target += " or " + keylist . substring ( 1 ) ;
498+ }
499+ }
500+
501+ // remove the extra " or "
502+ target = target . substring ( 4 ) ;
503+ if ( target . startsWith ( "L@" ) ) {
504+ // simplify when we only have the list of minions
505+ target = target . substring ( 2 ) ;
506+ }
507+
508+ if ( target === "" ) {
440509 return null ;
441510 }
442511
443- return lst . join ( "," ) ;
512+ return target ;
444513 }
445514
446515 static showManualRun ( pApi ) {
@@ -498,7 +567,26 @@ export class CommandBox {
498567 CommandBox . _populateTemplateTmplMenu ( ) ;
499568 CommandBox . _populateTestProviders ( pApi ) ;
500569
501- const lst = CommandBox . getSelectedMinionList ( )
570+ let lst = null ;
571+ // different pages have different selection-types
572+ // but run-command is available from every page
573+ switch ( window . location . hash ) {
574+ case "#minions" :
575+ case "#grains" :
576+ case "#schedules" :
577+ case "#pillars" :
578+ case "#beacons" :
579+ case "#highstate" :
580+ lst = CommandBox . getSelectedItemList ( [ "select_minions" ] ) ;
581+ break ;
582+ case "#keys" :
583+ lst = CommandBox . getSelectedItemList ( [ "select_keys" ] ) ;
584+ break ;
585+ case "#nodegroups" :
586+ lst = CommandBox . getSelectedItemList ( [ "select_minions" , "select_nodegroups" ] ) ;
587+ break ;
588+ }
589+
502590 if ( lst ) {
503591 const targetField = document . getElementById ( "target" ) ;
504592 targetField . value = lst ;
@@ -547,6 +635,7 @@ export class CommandBox {
547635
548636 // The leading # was used to indicate a nodegroup
549637 if ( pTargetType === "nodegroup" && pTarget . startsWith ( "#" ) ) {
638+ // remove the leading "#" as that is not part of the syntax for nodegroups
550639 pTarget = pTarget . substring ( 1 ) ;
551640 }
552641
0 commit comments