The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Yote Admin Page (YAP)</title>
    <script src="/yote/js/jquery-latest.js"></script>
    <script src="/yote/js/jquery.cookie.js"></script>
    <script src="/yote/js/jquery.base64.min.js"></script>
    <script src="/yote/js/json2.js"></script>

    <script src="/templates/templates.js"></script>

    <script src="/yote/js/yote.js"></script>
    <script src="/yote/js/yote.util.js"></script>
    <link href="/yote.css" rel="stylesheet" type="text/css" media="all" />
    <link href="/css/main.css" rel="stylesheet" type="text/css" media="all" />

    <META NAME="Author" CONTENT="Eric Wolf, coyocanid@gmail.com">

    <STYLE>
      .mainpanel { top:0px; width:900px; display:inline-block; }
      .tabs {
	  position: relative;
	  min-height: 300px; /* This part sucks */
	  clear: both;
	  margin: 25px 0;
      }
      .tab {
	  float: left;
      }
      .tab label {
	  background: #eee;
	  padding: 10px;
	  border: 1px solid #ccc;
	  margin-left: -1px;
	  position: relative;
	  left: 1px;
      }
      .tab [type=radio] {
	  display: none;
      }
      .content {
	  position: absolute;
	  top: 28px;
	  left: 0;
	  background: white;
	  right: 0;
	  bottom: 0;
	  padding: 20px;
	  border: 1px solid #ccc;
      }
      [type=radio]:checked ~ label {
	  background: white;
	  border-bottom: 1px solid white;
	  z-index: 2;
      }
      [type=radio]:checked ~ label ~ .content {
	  z-index: 1;
      }
      .apppanel { margin-left: 150px; }
      .sidenav { float: left; text-align: center; }
      button.sidenav {     background:none!important; cursor:pointer;
     border:none;
     padding:0!important;
    /*border is optional*/
     border-bottom:1px solid #444; ; }
      ._ct_row { vertical-align: top }
      ._ct_cell { border: 6px rgb(120,226,165) groove }


      tr { vertical-align: top }
    </STYLE>

<!--
there is a beauty that we experience as kids that only leaves tiny hints of itself when we are older.
it hides in smells and in the whispered wind.
if we are our experiences then we are both sides of them.

-->

    <script>
      var root;
	  function msg( args, message ) {
	      $( '#' + args[ 'controls' ][ 'messages' ] ).empty().append( message );
	  }

      $().ready(function(){
	  $.yote.include_templates( '/templates/templates.html' );
	  $.yote.util.register_functions( base_templates );

	  $( '#mainpanel' ).hide();
	  $.yote.debug = true;
	  $.yote.init();
	  $.yote.debug = false;
	  root = $.yote.fetch_root();
	  $.yote.app = root;
	  $.yote.util.register_item( 'root', root );
	  $( 'button.sidenav' ).each( function( idx, domEl ) {
	      $(this).click(function(){
		  $( '.apppanel' ).hide();
		  $( '#' + $(this).attr('id') + '_div' ).show();
	      });
	  } );

	  // -------------------------------------

	  $.yote.util.register_functions( {
	      ref : function( args ) {
		  return args[ 'default_var' ][ 'class' ];
	      },
	      remove_attached : function( args ) {
		  $.yote.debug = true;
		  var dh = args[ 'vars' ][ 'fieldname' ];
		  args[ 'default_parent' ].set( dh, null );
		  args[ 'default_parent' ].delete_key( { name : '_attached_objects', key : dh } );
		  $.yote.debug = false;
		  refresh_all();
	      },
	      setup_attached : function( args ) {
		  $.yote.util.button_actions( 
		      {
			  button : '#' + args[ 'controls' ][ 'add_attached_b' ],
			  texts  : [ '#' + args[ 'controls' ][ 'field' ] ],
			  action : function() {
			      var k  = $( '#' + args[ 'controls' ][ 'field' ] ).val();
			      var ot = $( '#' + args[ 'controls' ][ 'objtype' ] ).val();
			      var o = ot == 1 ? $.yote.fetch_root().new_obj() :
				  ot == 2 ? $.yote.fetch_root().new_user_obj() :
				  ot == 3 ? $.yote.fetch_root().new_root_obj() : null;
			      if( o ) {
				  args[ 'default_var' ].set( k, o );
				  args[ 'default_var' ].hash( {  name  : '_attached_objects',
								 key   : k,
								 value : o } );
				  refresh_all();
			      }
			  } //action
		      } );
	      }, //setup_attached
	      PurgedApps : function( args ) {
		  var pc = args[ 'default_var' ].count( '_purged_apps' );
		  if( pc > 0 ) {
		      return pc + ' apps thate have been purged <$$$ var ac ' + pc
			  + ' $$$> <$ button purge_apps Flush all Purged Apps $>';
		  } 
		  return '';
	      }, //PurgedApps
	      purge_apps : function( args ) {
		  if( confirm( 'Really purge ' + args[ 'vars' ][ 'ac' ] + ' removed apps?' ) ) {
		      args[ 'default_var' ].flush_purged_apps(undefined,function(){ msg( args, 'flushed purged apps' ) },function(err){ msg( args, err ) } );
		  }
	      },
	      reset_app : function( args ) {
		  $.yote.debug = true;
		  root.purge_app( args[ 'default_var' ] );
		  $.yote.debug = false;
		  refresh_all();
	      },
	      init_create_app : function( args ) {
		  (function( arg ) {
		      $.yote.util.button_actions( {
			  button :   '#' + arg[ 'controls' ][ 'new_app_b' ],
			  texts  : [ '#' + arg[ 'controls' ][ 'name' ] ],
			  action : function() {
			      var newapp = arg[ 'default_var' ].register_app(
				  { name    : $( '#' + arg[ 'controls' ][ 'name' ] ).val(),
				    'class' : $( '#' + arg[ 'controls' ][ 'class' ] ).val() },
				  function() { $.yote.util.refresh_ui() },
				  function(err) { msg( arg, err ); }
			      );
			  }
		      } );
		  } )( args );
	      },
	      cron_entry_next_time : function( args ) {
		  var entry = args[ 'default_var' ];
		  return entry.get( 'next_time' ) > 0 ? '<nobr>' +  $.yote.util.format_date( new Date( 60 * 1000 * entry.get( 'next_time' ) ), "h:m Y-M-D" ) + '</nobr>' : 'Not Scheduled';
	      },
	      app_user_count : function( args ) {
		  return args[ 'default_var' ].count('_account_roots');
	      },
	      make_root : function( is_checked, user ) {
		  if( is_checked ) return root.make_root( user );
		  root.remove_root( user, function(){},function(err){ alert(err)} );
	      },
	      root_status : function( args ) {
		  var login = args[ 'default_var' ];
		  return login.is_master_root() ? 'master root' : '<$ switch make_root ' + (1*login.is_root() != 0 ? '1' : '') + '$>';
	      },
	      is_validated : function( args ) {
		  return args[ 'default_var' ].is_validated() ? "Yes" : "No";
	      },
	      new_schedule:function( args ) {
		  var id = '#' + args[ 'controls' ][ 'new_schedule_time' ];
		  alert( $(id).val() );
	      },
	      refresh_all: refresh_all
	  } );

	  function refresh_all() {
	      if( $.yote.is_root() ) {
		  $( '#errpanel' ).hide();
		  $( '#mainpanel' ).show();
	      }
	      else {
		  $( '#errpanel' ).show();
		  $( '#mainpanel' ).hide();
		  $.yote.util.refresh_ui();
		  return;
 	      }
	      $.yote.util.register_template_variable( 'cron', root.cron() );
	      $.yote.util.register_template_variable( 'root', root );

	      $.yote.util.refresh_ui();
	  }//refresh_all

	  $.yote.util.register_function( 'refresh_all', refresh_all );

	  refresh_all();
      });
    </script>

<script type="text/template" class="yote_template_definition" template_name="Cron_Row">
  <tr> <td> <$ edit _ name $> </td>  <td> <$ checkbox _ enabled $> </td>  <td> <$ edit _ notes $> </td>
    <td> <$ edit _ script $> </td>  <td> <? cron_entry_next_time ?> </td>  <td> <$$ Entry_Repeat $$> </td>
    <td> <$$ Entry_Schedule $$> </td>  <td> <$ button Delete_Cron_Entry Delete $> </td>
  </tr>
</script>

<script type="text/template" class="yote_template_definition" template_name="Log_in_box_admin">
  <$$$ var default_login_message This page requires a root login. $$$>
  <$$ Log_in_box $$>
</script>

<script type="text/template" class="yote_template_definition" template_name="Empty">
   None Found
</script>

<script type="text/template" class="yote_template_definition" template_name="Cron">
 <A NAME="Cron">
 <H3>Crons</H3>
 <$@ Cron_Table Empty cron entries @$>
 <$ newbutton cron entries Add Cron $>
</script>

<script type="text/template" class="yote_template_definition" template_name="Cron_Table">

  <table border=1><tr>  <th>Name</th>     <th>Enabled</th>   <th>Notes</th>
                        <th>Script</th>   <th>Next Run</th>  <th>Repeat</th>
                        <th>Schedule</th> <th>Delete</th>
                  </tr>
      <@ Cron_Row 5 @>

  </table>
  <$$ Paginator $$>
  <!-- pagination goes here. Under the hood, there must be a context container or a default tag, or even last list -->
</script>


<script type="text/template" class="yote_template_definition" template_name="Cron_Row">
  <tr> <td> <$ edit _ name $> </td>  <td> <$ checkbox _ enabled $> </td>  <td> <$ edit _ notes $> </td>
    <td> <$ edit _ script $> </td>  <td> <? cron_entry_next_time ?> </td>  <td> <$$ Entry_Repeat $$> </td>
    <td> <$$ Entry_Schedule $$> </td>  <td> <$ button Delete_Cron_Entry Delete $> </td>
  </tr>
</script>

<script type="text/template" class="yote_template_definition" template_name="Entry_Repeat">
 <$@ Entry_Repeat_Table Empty  _ repeats @$>
 Interval (min) : <$$$ new repeat_interval <input type="text"> $$$> <BR>
 Infinite Repeat : <$$$ new repeat_infinite <input type="checkbox"> $$$> <BR>
 Number Repeat Times : <$$$ new repeat_times <input type="text"> $$$> <BR>
 <$ newbutton _ repeats Add Repeat $>
</script>

<script type="text/template" class="yote_template_definition" template_name="Entry_Repeat_Table">

  <table border=1><tr>  <th>Interval (mins)</th>     <th>Infinite Repeat</th>   <th>Repeats</th>
                        <th>Delete</th>
                        <th>Schedule</th> <th>Delete</th>
                  </tr>
      <@ Cron_Repeat_Row 2 @>
  </table>
  <$$ Paginator $$>
  <!-- pagination goes here. Under the hood, there must be a context container or a default tag, or even last list -->
</script>

<script type="text/template" class="yote_template_definition" template_name="Cron_Repeat_Row">
  <tr>  <td><$ edit _ repeat_interval $></td>  <td><$ checkbox _ repeat_infinite $></td>  <td><$ edit _ repeat_times $></td>  <td><$ list_remove_button _ repeats $></td>
</script>


<script type="text/template" class="yote_template_definition" template_name="Entry_Schedule">
 <$@ Entry_Schedule_Table Empty _ scheduled_times @$>
 <$$$ control new_schedule_time <input type="datetime-local"> $$$>
 <$ button new_schedule Schedule Time $>
</script>

<script type="text/template" class="yote_template_definition" template_name="Entry_Schedule_Table">

  <table border=1><tr>  <th>Scheduled Time</th> <th>Delete</th> </tr>
      <@ Cron_Schedule_Row 2 @>
  </table>
  <$$ Paginator $$>
  <!-- pagination goes here. Under the hood, there must be a context container or a default tag, or even last list -->
</script>

<script type="text/template" class="yote_template_definition" template_name="Cron_Schedule_Row">
  <tr>  <td><$ show $></td> <td><$ button remove_scheduled_time Delete $></td> </tr>
</script>

<!-- ------------------------------ -->

<section id="templates">
<script type="text/template" class="yote_template_definition" template_name="Apps">
 <A NAME="App">
 <H3>Applications Installed</H3>
 <$% App_Table Empty _ _apps %$>
 <? PurgedApps ?>
 <$$ NewApp $$>
</script>

<script type="text/template" class="yote_template_definition" template_name="PurgedApps">
  <$$$ control pcount <span></span> $$$>
</script>

<script type="text/template" class="yote_template_definition" template_name="App_Table">
  <table border=1><tr>  <th>Name</th>     <th>Host</th>   <th>Host URL</th>
                        <th>Number of Users</th>   <th>Email Settings</th> 
                        <th>Attached Objects</th>  <th>Reset</th>
                  </tr>
      <% App_Row 2 %>
  </table>
  <$$ Paginator $$>
<BR>
 <$$ SearchHash $$>
</script>

<script type="text/template" class="yote_template_definition" template_name="NewApp">
<div class="newapp">
 <h3>Create a new App</h3>
 App Name <$$$ control name <input type="text"> $$$><BR>
 App Class <$$$ control class <input type="text" value="Yote::AppRoot"> $$$><BR>
 <$$$ control new_app_b <button type="BUTTON">Register App</BUTTON> $$$>
 <?? init_create_app  ??>
</div>
</script>

<script type="text/template" class="yote_template_definition" template_name="App_Row">
  <tr>   <td><$ hash_key $></td>     <td><$ edit _ host_name $></td>   <td><$ edit _ host_u2rl $></td>
    <td><? app_user_count ?></td>   <td><$$ Email_Settings $$></td>  <td><$$ Attached_Objects $$></td>
    <td><$ button reset_app Reset $></td>
  </tr>
</script>

<script type="text/template" class="yote_template_definition" template_name="Attached_Objects">
    <$% Attached_ObjTab Empty _ _attached_objects %$>
    <$$ Add_Attached $$>
</script>

<script type="text/template" class="yote_template_definition" template_name="Add_Attached">
  <$$$ control field <input type="text" placeholder="field"> $$$>
  <$$$ control objtype <select> <option value="1">All May Edit</option> <option value="2">User and Root May Edit</option> <option value="3">Root May Edit</option></select> $$$>
  <$$$ control add_attached_b <BUTTON type="BUTTON">Attach Object</BUTTON> $$$>
  <?? setup_attached ??>
</script>

<script type="text/template" class="yote_template_definition" template_name="Attached_Obj_Row">
    <$$$ var fieldname <$ hash_key $> $$$>
    <TR>
      <TD><$ hash_key $></TD>
      <TD><? ref ?></TD>
      <TD><$ button remove_attached Remove $></TD>
    </TR>
</script>

<script type="text/template" class="yote_template_definition" template_name="Attached_ObjTab">
    <table> <TR> <TH>Object Name</TH> <TH>Class</TH> <TH>Remove</TH> </TR>
    <% Attached_Obj_Row 10 %>
    </table>    
</script>

<script type="text/template" class="yote_template_definition" template_name="Email_Settings">
    <table>
      <tr> <td><nobr>Email Validation Required</nobr> </td> <td> <$ checkbox _ requires_validation $> </td> </tr>
      <tr> <td><nobr>Validation Email From</nobr> </td> <td> <$ edit _ validation_email_from $> </td> </tr>
      <tr> <td><nobr>Validation Subject Template</nobr> </td> <td> <$ edit _.validation_subject_template text $> </td> </tr>
      <tr> <td><nobr>Validation Message Template</nobr> </td> <td> <$ edit _.validation_message_template text $> </td> </tr>
      <tr> <td><nobr>Validation Link Template</nobr> </td> <td> <$ edit _.validation_link_template text $> </td> </tr>
    </table>
</script>

<!-- ------------------------------ -->

<script type="text/template" class="yote_template_definition" template_name="Users">
 <A NAME="Users">
 <H3>Users</H3>
 <$% User_Table Empty _ _handles %$>
</script>

<script type="text/template" class="yote_template_definition" template_name="User_Table">
  <table border=1><tr>  <th>Handle</th>     <th>Email</th>   <th>Is Root</th>
                        <th>Was Validated</th>
                  </tr>
  <% User_Row 10 %>
  </table>
  <$$ Paginator $$>
  <$$ SearchHash $$>
</script>

<script type="text/template" class="yote_template_definition" template_name="User_Row">
    <tr>   <th><$ hash_key $></th> <th><$ show _ email $></th>   <th><? root_status ?></th>
                        <th><? is_validated ?></th> </tr>
</script>

<script type="text/template" class="yote_template_definition" template_name="MainAdmin">
    <$$$ control messages <span class="message"></span> $$$>
    <$$ Apps $$>
    <$$ Cron $$>
    <$$ Users $$>
    <A HREF="#Top">Back to Top</A>
</script>

</section>
<!-- ------------------------------ -->

  </head>

  <BODY>

    <DIV class="header">
      <A href="/index.html" style="display:block">
	<img height="70px" width="151px" src="yotelogo.png">
      </A>
      <UL id="top_nav" class="nav"></UL>
      <DIV id="login_div" class="yote_template login" template="Log_in_box_admin"></div>
    </DIV>

    <A NAME="Top">

    <DIV id="errpanel" class="err">
      Must be logged in with a root account to view this page.
    </DIV>

    <DIV class="mainpanel" id="mainpanel">
	<SECTION>
	  <DIV class="page-header">
	    <H1>Yote Admin Page (YAP)</H1>
	  </DIV>
	  <P>
	    Welcome to the Yote Admin Page. This page manages
            the <A HREF="#Users">users</A>, <A HREF="#App">apps</A> and <A HREF="#Cron">cron</A>.
	  </P>
	</SECTION>

	<hr>

        <DIV class="yote_template side_panel" template="MainAdmin" default_variable="root"></div>

    </DIV>

    <hr>

    <footer>
    </footer>
  </body>
</html>