@ -1,7 +1,40 @@ 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					/ * *   *   E n t i t y G r i d . v u e   -   U n i f i e d   e n t i t y   g r i d   l a y o u t   c o m p o n e n t   *   *   E x t r a c t e d   f r o m  
					 
					 
					/ * *  
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					GiftedDialog . vue  to  provide  a  reusable  grid  layout  *  for  displaying  people ,  
					 
					 
					 *  EntityGrid . vue  -  Unified  entity  grid  layout  component  
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					projects ,  and  special  entities  with  selection .  *  *  @ author  Matthew  Raymer  * /  
					 
					 
					 *   
				
			 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					 
					 
					 
					 
					 
					 *  Extracted  from  GiftedDialog . vue  to  provide  a  reusable  grid  layout  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					 *  for  displaying  people ,  projects ,  and  special  entities  with  selection .  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					 *   
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					 *  @ author  Matthew  Raymer  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					 * /  
				
			 
			
		
	
		
		
			
				
					 
					 
					< template >  
					 
					 
					< template >  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					  <!--  Quick  Search  -- >  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					  < div  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    id = "QuickSearch"  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    class = "mb-4 flex items-center text-sm"  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					  >  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    < input  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      v - model = "searchTerm"  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      type = "text"  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      placeholder = "Search…"  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      class = "block w-full rounded-l border border-r-0 border-slate-400 px-3 py-1.5 placeholder:italic placeholder:text-slate-400 focus:outline-none"  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      @ input = "handleSearchInput"  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      @ keydown . enter = "performSearch"  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    / >  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    < div   
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      v - show = "isSearching"  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      class = "border-y border-slate-400 ps-2 py-1.5 text-center text-slate-400"  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    >  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      < font -awesome  icon = "spinner"  class = "fa-spin-pulse leading-[1.1]" > < / f o n t - a w e s o m e >  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    < / div >  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    < button  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      : disabled = "!searchTerm"  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      class = "px-2 py-1.5 rounded-r bg-white border border-l-0 border-slate-400 text-slate-400 disabled:cursor-not-allowed"  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      @ click = "clearSearch"  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    >  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      < font -awesome  : icon = "searchTerm ? 'times' : 'magnifying-glass'"  class = "fa-fw" > < / f o n t - a w e s o m e >  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    < / button >  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					  < / div >  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					   
				
			 
			
		
	
		
		
			
				
					 
					 
					  < ul  class = "border-t border-slate-300 mb-4 max-h-[60vh] overflow-y-auto" >  
					 
					 
					  < ul  class = "border-t border-slate-300 mb-4 max-h-[60vh] overflow-y-auto" >  
				
			 
			
		
	
		
		
			
				
					 
					 
					    <!--  Special  entities  ( You ,  Unnamed )  for  people  grids  -- >  
					 
					 
					    <!--  Special  entities  ( You ,  Unnamed )  for  people  grids  -- >  
				
			 
			
		
	
		
		
			
				
					 
					 
					    < template  v-if ="entityType === 'people'" >  
					 
					 
					    < template  v-if ="entityType === 'people'" >  
				
			 
			
		
	
	
		
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
					@ -101,6 +134,12 @@ export default class EntityGrid extends Vue { 
				
			 
			
		
	
		
		
			
				
					 
					 
					  @ Prop ( {  required :  true  } )  
					 
					 
					  @ Prop ( {  required :  true  } )  
				
			 
			
		
	
		
		
			
				
					 
					 
					  entityType ! :  "people"  |  "projects" ;  
					 
					 
					  entityType ! :  "people"  |  "projects" ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					
 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					  / /   S e a r c h   s t a t e  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					  searchTerm  =  "" ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					  isSearching  =  false ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					  searchTimeout :  NodeJS . Timeout  |  null  =  null ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					  filteredEntities :  Contact [ ]  |  PlanData [ ]  =  [ ] ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					 
					 
					  /** Array of entities to display */  
					 
					 
					  /** Array of entities to display */  
				
			 
			
		
	
		
		
			
				
					 
					 
					  @ Prop ( {  required :  true  } )  
					 
					 
					  @ Prop ( {  required :  true  } )  
				
			 
			
		
	
		
		
			
				
					 
					 
					  entities ! :  Contact [ ]  |  PlanData [ ] ;  
					 
					 
					  entities ! :  Contact [ ]  |  PlanData [ ] ;  
				
			 
			
		
	
	
		
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
					@ -184,8 +223,15 @@ export default class EntityGrid extends Vue { 
				
			 
			
		
	
		
		
			
				
					 
					 
					
 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					 
					 
					  / * *  
					 
					 
					  / * *  
				
			 
			
		
	
		
		
			
				
					 
					 
					   *  Computed  entities  to  display  -  uses  function  prop  if  provided ,  otherwise  defaults  
					 
					 
					   *  Computed  entities  to  display  -  uses  function  prop  if  provided ,  otherwise  defaults  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					   *  When  searching ,  returns  filtered  results  instead  of  original  logic  
				
			 
			
		
	
		
		
			
				
					 
					 
					   * /  
					 
					 
					   * /  
				
			 
			
		
	
		
		
			
				
					 
					 
					  get  displayedEntities ( ) :  Contact [ ]  |  PlanData [ ]  {  
					 
					 
					  get  displayedEntities ( ) :  Contact [ ]  |  PlanData [ ]  {  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    / /   I f   s e a r c h i n g ,   r e t u r n   f i l t e r e d   r e s u l t s  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    if  ( this . searchTerm . trim ( ) )  {  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      return  this . filteredEntities ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    }  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    / /   O r i g i n a l   l o g i c   w h e n   n o t   s e a r c h i n g  
				
			 
			
		
	
		
		
			
				
					 
					 
					    if  ( this . displayEntitiesFunction )  {  
					 
					 
					    if  ( this . displayEntitiesFunction )  {  
				
			 
			
		
	
		
		
			
				
					 
					 
					      return  this . displayEntitiesFunction (  
					 
					 
					      return  this . displayEntitiesFunction (  
				
			 
			
		
	
		
		
			
				
					 
					 
					        this . entities ,  
					 
					 
					        this . entities ,  
				
			 
			
		
	
	
		
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
					@ -283,6 +329,74 @@ export default class EntityGrid extends Vue { 
				
			 
			
		
	
		
		
			
				
					 
					 
					    } ) ;  
					 
					 
					    } ) ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					  }  
					 
					 
					  }  
				
			 
			
		
	
		
		
			
				
					 
					 
					
 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					  / * *  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					   *  Handle  search  input  with  debouncing  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					   * /  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					  handleSearchInput ( ) :  void  {  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    / /   S h o w   s p i n n e r   i m m e d i a t e l y   w h e n   u s e r   t y p e s  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    this . isSearching  =  true ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					     
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    / /   C l e a r   e x i s t i n g   t i m e o u t  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    if  ( this . searchTimeout )  {  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      clearTimeout ( this . searchTimeout ) ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    }  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    / /   S e t   n e w   t i m e o u t   f o r   5 0 0 m s   d e l a y  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    this . searchTimeout  =  setTimeout ( ( )  =>  {  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      this . performSearch ( ) ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    } ,  500 ) ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					  }  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					  / * *  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					   *  Perform  the  actual  search  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					   * /  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					  async  performSearch ( ) :  Promise < void >  {  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    if  ( ! this . searchTerm . trim ( ) )  {  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      this . filteredEntities  =  [ ] ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      return ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    }  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    this . isSearching  =  true ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    try  {  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      / /   S i m u l a t e   a s y n c   s e a r c h   ( i n   c a s e   w e   n e e d   t o   a d d   A P I   c a l l s   l a t e r )  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      await  new  Promise ( resolve  =>  setTimeout ( resolve ,  100 ) ) ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      const  searchLower  =  this . searchTerm . toLowerCase ( ) . trim ( ) ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					       
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      if  ( this . entityType  ===  "people" )  {  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					        this . filteredEntities  =  ( this . entities  as  Contact [ ] ) . filter ( ( contact :  Contact )  =>  {  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					          const  name  =  contact . name ? . toLowerCase ( )  ||  "" ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					          const  did  =  contact . did . toLowerCase ( ) ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					          return  name . includes ( searchLower )  ||  did . includes ( searchLower ) ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					        } ) ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      }  else  {  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					        this . filteredEntities  =  ( this . entities  as  PlanData [ ] ) . filter ( ( project :  PlanData )  =>  {  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					          const  name  =  project . name ? . toLowerCase ( )  ||  "" ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					          const  handleId  =  project . handleId . toLowerCase ( ) ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					          return  name . includes ( searchLower )  ||  handleId . includes ( searchLower ) ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					        } ) ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      }  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    }  finally  {  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      this . isSearching  =  false ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    }  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					  }  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					  / * *  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					   *  Clear  the  search  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					   * /  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					  clearSearch ( ) :  void  {  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    this . searchTerm  =  "" ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    this . filteredEntities  =  [ ] ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    this . isSearching  =  false ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					     
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    / /   C l e a r   a n y   p e n d i n g   t i m e o u t  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    if  ( this . searchTimeout )  {  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      clearTimeout ( this . searchTimeout ) ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      this . searchTimeout  =  null ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    }  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					  }  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					 
					 
					  / /   E m i t   m e t h o d s   u s i n g   @ E m i t   d e c o r a t o r  
					 
					 
					  / /   E m i t   m e t h o d s   u s i n g   @ E m i t   d e c o r a t o r  
				
			 
			
		
	
		
		
			
				
					 
					 
					
 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					 
					 
					  @ Emit ( "entity-selected" )  
					 
					 
					  @ Emit ( "entity-selected" )  
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					@ -295,6 +409,15 @@ export default class EntityGrid extends Vue { 
				
			 
			
		
	
		
		
			
				
					 
					 
					  }  {  
					 
					 
					  }  {  
				
			 
			
		
	
		
		
			
				
					 
					 
					    return  data ;  
					 
					 
					    return  data ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					  }  
					 
					 
					  }  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					  / * *  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					   *  Cleanup  timeouts  when  component  is  destroyed  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					   * /  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					  beforeUnmount ( ) :  void  {  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    if  ( this . searchTimeout )  {  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					      clearTimeout ( this . searchTimeout ) ;  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					    }  
				
			 
			
		
	
		
		
			
				
					 
					 
					 
					 
					 
					  }  
				
			 
			
		
	
		
		
			
				
					 
					 
					}  
					 
					 
					}  
				
			 
			
		
	
		
		
			
				
					 
					 
					< / script >  
					 
					 
					< / script >