From c8b1ef1ebcaf42502a5939876715e63fdcebb652 Mon Sep 17 00:00:00 2001
From: "Hahn Axel (hahn)" <axel.hahn@unibe.ch>
Date: Wed, 22 Nov 2023 12:35:33 +0100
Subject: [PATCH] update ui

---
 .../deployment/classes/project.class.php      |   4 +-
 .../deployment/classes/project_gui.class.php  |   2 +-
 .../classes/render-adminlte.class.php         |  37 +-
 public_html/deployment/inc_functions.php      | 279 +-----------
 public_html/deployment/index.php              | 408 +++++++++---------
 public_html/deployment/main.css               |  15 +-
 public_html/deployment/main_new_ui.css        |  12 +-
 7 files changed, 235 insertions(+), 522 deletions(-)

diff --git a/public_html/deployment/classes/project.class.php b/public_html/deployment/classes/project.class.php
index 9d6ea14c..c9f50b5b 100644
--- a/public_html/deployment/classes/project.class.php
+++ b/public_html/deployment/classes/project.class.php
@@ -2488,11 +2488,11 @@ class project extends base {
             echo "DELETE Config ...<br>";
             // echo "config file: $sCfgfile<br>";
             if (file_exists($sCfgfile . ".ok")) {
-                // echo "Delete ${sCfgfile}.ok<br>";
+                // echo "Delete $sCfgfile.ok<br>";
                 unlink($sCfgfile . ".ok");
             }
             if (file_exists($sCfgfile)) {
-                // echo "Delete ${sCfgfile}<br>";
+                // echo "Delete $sCfgfile<br>";
                 if (!unlink($sCfgfile)) {
                     $sError = t("class-project-error-delete-project-deletion-failed-configfile");
                     $this->_logaction(t('aborted') . " " . $sError, __FUNCTION__);
diff --git a/public_html/deployment/classes/project_gui.class.php b/public_html/deployment/classes/project_gui.class.php
index 31ea97c9..27c33a44 100644
--- a/public_html/deployment/classes/project_gui.class.php
+++ b/public_html/deployment/classes/project_gui.class.php
@@ -1615,7 +1615,7 @@ class projectgui extends project {
 
         $aBranches=$this->getRemoteBranches();
         if(!is_array($aBranches)){
-            return $this->_oHtml->getBox("error", t("project-setup-incomplete"));
+            return '<br>'.$this->_oHtml->getBox("error", t("project-setup-incomplete"));
         }
 
         $sRepoBar = '';
diff --git a/public_html/deployment/classes/render-adminlte.class.php b/public_html/deployment/classes/render-adminlte.class.php
index 0c4dc7a2..58f65373 100755
--- a/public_html/deployment/classes/render-adminlte.class.php
+++ b/public_html/deployment/classes/render-adminlte.class.php
@@ -158,26 +158,6 @@ class renderadminlte {
     // 
     // ----------------------------------------------------------------------
     
-    /**
-     * verify if an item has a correct value
-     * it returns false if a key is not defined to be checked
-     * it returns true if it was validated successfully
-     * it dies with an errror, if a value check failed
-     * 
-     * @param string  $sType      type; key in $_aValidItems; one of bgcolor|color|type|size
-     * @param string  $sValue     value to check
-     * @param string  $sReferrer  optional: method that called this function
-     */
-    protected function _DELETE_ME___checkValue($sType, $sValue, $sReferrer=false){
-        if (!$sValue || !array_key_exists($sType, $this->_aValidItems)){
-            return false;
-        }
-        if(array_search($sValue, $this->_aValidItems[$sType])===false){
-            echo "ERROR: ".($sReferrer ? $sReferrer.' - ' : '')."value [$sValue] is not a valid for type [$sType]; it must be one of ".implode("|", $this->_aValidItems[$sType]).'<br>';
-        }
-        return true;
-    }
-
     /**
      * used in cosntructor
      * initialize all element definitions
@@ -580,13 +560,16 @@ class renderadminlte {
             $iCounter=0;
         }
         
-        // special menu entry: horizontal bar (label is "-")
-        if($aLink['label']=='-'){
-            return '<div class="dropdown-divider"></div>';
-        }
-        // special menu entry: hamburger menu item (label is "=")
-        if($aLink['label']=='='){
-            return '<li class="nav-item"><a class="nav-link" data-widget="pushmenu" href="#" role="button"><i class="fas fa-bars"></i></a></li>';
+        switch ($aLink['label']) {
+            // special menu entry: horizontal bar (label is "-")
+            case '-': return '<div class="dropdown-divider"></div>'; break;
+
+            // special menu entry: hamburger menu item (label is "=")
+            case '=': return '<li class="nav-item"><a class="nav-link" data-widget="pushmenu" href="#" role="button"><i class="fas fa-bars"></i></a></li>'; break;
+
+            // special menu entry: hamburger menu item (label is "|")
+            // requires css: .navbar-nav li.divider{border-left: 1px solid rgba(0,0,0,0.2);}
+            case '|': return '<li class="divider"></li>'; break;
         }
 
         $aChildren=isset($aLink['children']) && is_array($aLink['children']) && count($aLink['children']) ? $aLink['children'] : false;
diff --git a/public_html/deployment/inc_functions.php b/public_html/deployment/inc_functions.php
index e4f24f5a..e6f6f345 100644
--- a/public_html/deployment/inc_functions.php
+++ b/public_html/deployment/inc_functions.php
@@ -214,7 +214,7 @@ function getTopNavLeft($aEmbed=[]) {
     $sLiActive=' class="active"';
 
     // $aReturn[]=['label'=>'=' ];
-    $aReturn[]=['href'=>$sBaseUrl . '', 'label'=>'&nbsp;Deployment UI <small>v2</small>',    'icon'=>'', 'class'=>'imllogo topbrand' ];
+    $aReturn[]=['href'=>$sBaseUrl . '', 'label'=>'&nbsp;Deployment UI <small class="badge bg-info"><nobr>v'.APP_VERSION.'</nobr></small>',    'icon'=>'', 'class'=>'imllogo topbrand' ];
 
     if($oUser->getUsername()){
         $oPrj1 = new project();
@@ -300,10 +300,12 @@ function getTopNavRight() {
             ['href'=>'#', 'label'=>$oUser->getUsername(),    'icon'=>'fa-solid fa-user', 
                 'class'=>($sCurrentAction=='login' ? 'active' :''),
                 'children'=>[
-                    ['href'=>$sBaseUrl . 'all/login/',           'label'=>t("login"),            'icon'=>'fa-solid fa-right-to-bracket' ],
+                    ['href'=>$sBaseUrl . 'all/login/',           'label'=>t("login"),            'icon'=>'fa-solid fa-right-to-bracket', 'class'=>($sCurrentAction=='login' ? 'active' :'') ],
                 ]
             ]
         ];
+    } else{
+        $aReturn[]=['href'=>$sBaseUrl . 'all/login/',           'label'=>t("login"),            'icon'=>'fa-solid fa-right-to-bracket', 'class'=>($sCurrentAction=='login' ? 'active' :'') ];
     }
     $aReturn[]=['href'=>'#', 'label'=>t('menu-help'), 'icon'=>'fa-solid fa-life-ring', 'class'=>'',
             'children'=>[
@@ -319,281 +321,10 @@ function getTopNavRight() {
     return $aReturn;
 }
 
-/**
- * auto generate upper part of the page with header and navigation 
- * @global type $aParams
- * @return type
- */
-function getTopArea($aEmbed=[]) {
-    global $aParams, $oHtml;
-    $sReturn = '';
-    require_once("./classes/project.class.php");
-    require_once("./classes/user.class.php");
-    $oUser = new user();
-
-    $sMyPhase = "[phase]";
-    $sMyRev = " [no rev] ";
-    // bug#1511 json file was moved 1 level up
-    $sJsonfile = dirname(dirname(__DIR__)) . "/ciserver.json";
-    if (file_exists($sJsonfile)) {
-        $aJson = json_decode(file_get_contents($sJsonfile), true);
-        if (array_key_exists("date", $aJson))
-            $sMyRev = $aJson["date"];
-    }
-
-    $sBaseUrl = '/deployment/';
-    $sWikiBaseUrl = 'https://intranet.iml.unibe.ch/wiki/doku.php';
-    $sCurrentProject=(array_key_exists("prj", $aParams) && $aParams["prj"] <> "all") ? $aParams["prj"] : false;
-    $sCurrentAction=(array_key_exists("action", $aParams) && $aParams["action"]) ? $aParams["action"] : false;
-    $sCurrentPar3=(array_key_exists("par3", $aParams) && $aParams["par3"]) ? $aParams["par3"] : false;
-    $sLiActive=' class="active"';
-    
-    $sReturn = '
-        <span id="top"></span>
-        <nav class="navbar navbar-inverse" role="navigation">
-          <div class="container-fluid">
-            <!-- Brand and toggle get grouped for better mobile display -->
-            <div class="navbar-header">
-              <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
-                <span class="sr-only">Toggle navigation</span>
-                <span class=" glyphicon glyphicon-bar"></span>
-                <span class=" glyphicon glyphicon-bar"></span>
-                <span class=" glyphicon glyphicon-bar"></span>
-              </button>
-              <nobr>
-                <a class="navbar-brand" href="' . $sBaseUrl . '"><span class="imllogo"></span> '.t("menu-brand").'</a>
-                <span class="badge"></span>
-              </nobr>
-              &nbsp;&nbsp;&nbsp;
-            </div>
-            <!-- Collect the nav links, forms, and other content for toggling -->
-            <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
-            ';
-    if($oUser->getUsername()){
-        $sReturn.='
-              <ul class="nav navbar-nav">
-              
-                <li class="dropdown';
-                if (array_key_exists("prj", $aParams) && $aParams['prj']==='all'){
-                    $sReturn.=' active';
-                }
-                $sReturn.='">'
-                        . $oHtml->getLink(array(
-                            'href'=>$sBaseUrl,
-                            'class'=>'dropdown-toggle',
-                            'data-toggle'=>'dropdown',
-                            'role'=>'button',
-                            'aria-expanded'=>'false',
-                            'icon'=>'menu',
-                            'label'=>t("menu").' <span class="caret"></span>',
-                        ))
-                  .'<ul class="dropdown-menu" role="menu">
-                    <li'.($sCurrentPar3=== 'new' ? $sLiActive :'') .'>'
-                        .$oHtml->getLink(array(
-                            'href'=>$sBaseUrl . 'all/setup/new/',
-                            'icon'=>'new',
-                            'label'=>t("menu-new-project"),
-                        )).'</li>
-                    <li'.($sCurrentPar3=== 'actionlog' ? $sLiActive :'') .'>'
-                            
-                        .$oHtml->getLink(array(
-                            'href'=>$sBaseUrl . 'all/setup/actionlog/',
-                            'icon'=>'actionlog',
-                            'label'=>t("menu-logs"),
-                        )).'</li>
-                    <li'.($sCurrentPar3=== 'checklang' ? $sLiActive :'') .'>'
-                        .$oHtml->getLink(array(
-                            'href'=>$sBaseUrl . 'all/setup/checklang/',
-                            'icon'=>'checklang',
-                            'label'=>t("menu-checklang"),
-                        )).'</li>
-                    <li'.($sCurrentProject=='' && $sCurrentAction=='setup' && $sCurrentPar3=='' ? $sLiActive :'') .'>'
-                        .$oHtml->getLink(array(
-                            'href'=>$sBaseUrl . 'all/setup/',
-                            'icon'=>'setup',
-                            'label'=>t("menu-settings"),
-                        )).'</li>
-                  </ul>
-                </li>
-                
-
-                <li class="dropdown">'
-                    . $oHtml->getLink(array(
-                        'href'=>'#',
-                        'class'=>'dropdown-toggle',
-                        'data-toggle'=>'dropdown',
-                        'role'=>'button',
-                        'aria-expanded'=>'false',
-                        'icon'=>'projects',
-                        'label'=>t("menu-projects") . ' <span class="caret"></span>',
-                    ))
-                    .'<ul class="dropdown-menu" role="menu">'
-                    ;
-                
-                    $oPrj1 = new project();
-                    foreach ($oPrj1->getProjects() as $sPrj) {
-                        $oPrj = new project($sPrj);
-                        $sReturn.='<li'
-                                . ($sCurrentProject===$oPrj->getId() ? $sLiActive:'')
-                                . '>'
-                                . $oHtml->getLink(array(
-                                    'href'=>$sBaseUrl . $sPrj .'/',
-                                    'icon'=>'project',
-                                    'label'=>$oPrj->getLabel(),
-                                ))
-                                . '</li>';
-                    }
-                    $sReturn.='
-                  </ul>
-                </li>
-              ';
-
-                if (array_key_exists("prj", $aParams) && $aParams["prj"] <> "all") {
-                    $oPrj = new project($aParams["prj"]);
-                    $sReturn.='
-                    <li class="dropdown active">'
-                        .$oHtml->getLink(array(
-                            'href'=>'#',
-                            'class'=>'dropdown-toggle',
-                            'data-toggle'=>'dropdown',
-                            'role'=>'button',
-                            'aria-expanded'=>'false',
-                            'icon'=>'project',
-                            'label'=>$oPrj->getLabel() .' <span class="caret"></span>',
-                        ))
-                        .'
-                        <ul class="dropdown-menu" role="menu">
-                            <li'.($sCurrentAction===false ? $sLiActive :'') .'>'
-                            . $oHtml->getLink(array(
-                                'href'=>$sBaseUrl . $aParams["prj"] .'/',
-                                'icon'=>'project-home',
-                                'label'=>t("project-home"),
-                            ))
-                            .'</li>
-                        ';
-                        $aPhases = $oPrj->getActivePhases();
-                        if (count($aPhases)) {
-                            $sReturn.='<li role="separator" class="divider"></li>
-                                    <li'.($sCurrentAction==='build' ? $sLiActive :'') .'>'
-                                    .$oHtml->getLink(array(
-                                        'href'=>$sBaseUrl . $aParams["prj"] . '/build/',
-                                        'icon'=>'build',
-                                        'label'=>t("build"),
-                                    ))
-                                    .'</li> 
-                                    <li role="separator" class="divider"></li>
-                                    <li class="dropdown-header">'.t("menu-project-phases").'</li>';
-                            foreach ($aPhases as $sPhase) {
-                                $sReturn.='<li'.(isset($aParams['par3']) && $aParams['par3']===$sPhase ? $sLiActive :'') .'>'
-                                        . '<a href="' . $sBaseUrl . $aParams["prj"] . '/phase/' . $sPhase . '/">' . $oHtml->getIcon('phase').$sPhase . '</a></li>';
-                            }
-                        }
-                        $sReturn.='
-                            <li role="separator" class="divider"></li>
-                            <li'.($sCurrentAction==='setup' ? $sLiActive :'') .'>'
-                            .$oHtml->getLink(array(
-                                'href'=>$sBaseUrl . $aParams["prj"] . '/setup/',
-                                'icon'=>'setup',
-                                'label'=>t("menu-project-settings"),
-                            ))
-                            .'</li> 
-                            <li'.($sCurrentAction==='cleanup' ? $sLiActive :'') .'>'
-                            .$oHtml->getLink(array(
-                                'href'=>$sBaseUrl . $aParams["prj"] . '/cleanup/',
-                                'icon'=>'cleanup',
-                                'label'=>t("menu-project-cleanup"),
-                            ))
-                            .'</li> 
-                            <li'.($sCurrentAction==='delete' ? $sLiActive :'') .'>'
-                            .$oHtml->getLink(array(
-                                'href'=>$sBaseUrl . $aParams["prj"] . '/delete/',
-                                'icon'=>'delete',
-                                'label'=>t("menu-project-delete"),
-                            ))
-                            .'</li> 
-                        </ul></li>';
-                }
-    }
-                    
-            $sReturn.='
-              </ul>
-            
-            <ul class="nav navbar-nav navbar-right">'
-                .(isset($aEmbed['right'])
-                    ? $aEmbed['right']
-                    : ''
-                )
-                . ($oUser->getUsername() 
-                    ? '
-                    <!-- userdata -->
-                    <li class="dropdown">'
-                        .$oHtml->getLink(array(
-                            'href'=>'#',
-                            'class'=>'dropdown-toggle',
-                            'data-toggle'=>'dropdown',
-                            'role'=>'button',
-                            'aria-expanded'=>'false',
-                            'icon'=>'user',
-                            'label'=>$oUser->getUsername() .' <span class="caret"></span>',
-                        ))
-                        .'<ul class="dropdown-menu" role="menu">
-                            <li>'
-                            .$oHtml->getLink(array(
-                                'href'=>$sBaseUrl . 'all/login/',
-                                'icon'=>'login',
-                                'label'=>t("menu-login"),
-                            ))
-                            .'</li> 
-                        </ul>
-                    </li>'
-                        
-                    : '<li>'
-                        .$oHtml->getLink(array(
-                            'href'=>$sBaseUrl . 'all/login/',
-                            'icon'=>'login',
-                            'label'=>t("login"),
-                        ))
-                      .'</li>'
-                )
-                .'<li class="dropdown">
-                        <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"
-                        >'.$oHtml->getIcon('help'). t("menu-help") . ' <b class="caret"></b></a>
-                        <ul class="dropdown-menu">
-                            <li><a href="' . $sWikiBaseUrl . '/it/entwicklung/continuous_deployment">WIKI: Übersicht Continous Deployment</a></li>
-                            <li><a href="' . $sWikiBaseUrl . '/it/entwicklung/continuous_deployment#konventionen">WIKI: Konventionen für Entwickler</a></li>
-                            <li><a href="' . $sWikiBaseUrl . '/it/infrastruktur/dienste/puppet/snippets#iml-deployment">WIKI (Admin): Puppet-Snippets für den Sysadmin</a></li>
-                            <li><a href="' . $sWikiBaseUrl . '/it/infrastruktur/dienste/imldeployment">WIKI (Admin): Verzeichnisse und Dateien</a></li>
-                            <li><a href="/deployment/all/doc/">' . t("menu-help-classes") . '</a></li>
-                        </ul>
-                    </li>
-            </ul>
-            </div><!-- /.navbar-collapse -->
-          </div><!-- /.container-fluid -->
-        </nav>    
-         
-          <span id="swversion">' . $sMyRev . ' @ ' . php_uname("n") . '</span>
-        </div><div id="header2">';
-
-    if (!array_key_exists("prj", $aParams)) {
-        $sReturn.='<h1>' . t("overview-label") . '</h1><span class="description">' . t("overview-hint") . '</span>';
-    } else {
-        if ($aParams["prj"] <> "all") {
-            $oPrj = new project($aParams["prj"]);
-            $sReturn.='<h1>' . $oPrj->getLabel() . '</h1>'
-                    . '<span class="description">' . $oPrj->getDescription() . '</span>';
-            if (array_key_exists("action", $aParams)) {
-                // $sReturn.='<h2>Aktion: '.$aParams["action"].'</h2>';
-            }
-        }
-    }
-    $sReturn.='</div>';
-
-    return $sReturn;
-}
-
 /**
  * get h2 headline with action
  * @global type $aParams
+ * @param  string  $sLinkClass  classname for links; default: "" (adds class="btn btn-default")
  * @return string
  */
 function getBreadcrumb($sLinkClass="") {
diff --git a/public_html/deployment/index.php b/public_html/deployment/index.php
index bbcd34da..71068b29 100644
--- a/public_html/deployment/index.php
+++ b/public_html/deployment/index.php
@@ -1,248 +1,238 @@
 <?php
 
-define("APP_VERSION", '2.0.0-ALPHA');
+define("APP_VERSION", '2.0-alpha');
 
-require_once('./classes/render-adminlte.class.php');
+require_once("./classes/project_gui.class.php");
 require_once('./classes/queryparam.class.php');
 # require_once('./classes/icon.class.php');
 
 
 $sPpage=queryparam::get('page', '/^[a-z]*$/');
 
+require_once('./classes/render-adminlte.class.php');
 $renderAdminLTE=new renderadminlte();
+
 $aReplace=include("./ui/page_replacements.php");
 
 
-    // detect first run
-    $bFirstRun=!file_exists("../../config/config_custom.php") || !file_exists("../../config/inc_user2roles.php");
+// detect first run
+$bFirstRun=!file_exists("../../config/config_custom.php") || !file_exists("../../config/inc_user2roles.php");
 
-    require_once("../../config/inc_projects_config.php");
-    require_once("./classes/logger.class.php");
-    require_once("./classes/user.class.php");
-    global $oCLog;
-    $oCLog = new logger();
-    $oCLog->enableDebugByIp($aConfig['showdebug']['ip']);
+require_once("../../config/inc_projects_config.php");
+require_once("./classes/logger.class.php");
+require_once("./classes/user.class.php");
+global $oCLog;
+$oCLog = new logger();
+$oCLog->enableDebugByIp($aConfig['showdebug']['ip']);
 
-    require_once("./inc_functions.php");
-    require_once("./classes/htmlguielements.class.php");
-    require_once("./classes/plugins_renderer.class.php");
-    $oHtml=new htmlguielements();
-    
-    $sPrj = "";
-    $sAction = "overview";
-    
-    // ----------------------------------------------------------------------
-    // check params
-    // ----------------------------------------------------------------------
-    
-    if (array_key_exists("prj", $aParams)) {
-        $sPrj = $aParams["prj"];
+require_once("./inc_functions.php");
+require_once("./classes/htmlguielements.class.php");
+require_once("./classes/plugins_renderer.class.php");
+$oHtml=new htmlguielements();
+
+$sPrj = "";
+$sAction = "overview";
+
+// ----------------------------------------------------------------------
+// check params
+// ----------------------------------------------------------------------
+
+if (array_key_exists("prj", $aParams)) {
+    $sPrj = $aParams["prj"];
+}
+if (array_key_exists("action", $aParams)) {
+    if (file_exists(__DIR__ . '/pages/act_' . $aParams["action"] . ".php")) {
+        $sAction = $aParams["action"];
     }
-    if (array_key_exists("action", $aParams)) {
-        if (file_exists(__DIR__ . '/pages/act_' . $aParams["action"] . ".php")) {
-            $sAction = $aParams["action"];
+}
+$oCLog->add("parsing params "
+        . '<pre>GET '.print_r($_GET, true).'</pre>'
+        . '<pre>POST '.print_r($_POST, true).'</pre>'
+        . '<pre>aParams: '.print_r($aParams, true).'</pre>'
+        );
+
+if($bFirstRun){
+    $sAction='installer';
+}
+
+// ------ action 
+$oUser = new user();
+
+if (isset($aConfig["auth"]['forceuser']) && $aConfig["auth"]['forceuser']){
+    $oCLog->add("Found config -> auth -> forceuser: using fake identity [".$aConfig["auth"]['forceuser'].']', "warning");
+    $oUser->setUser($aConfig["auth"]['forceuser']);
+}
+        
+// ----------------------------------------------------------------------
+// html header
+// ----------------------------------------------------------------------
+
+$sHeader = "\n<!-- generated CSS for phases -->\n<style>\n";
+foreach ($aConfig["phases"] as $sPhase => $aData) {
+    $sHeader.=array_key_exists("bgdark", $aData["css"]) ? 'th.' . $sPhase . '{' . $aData["css"]["bgdark"] . '}' : '';
+    $sHeader.=array_key_exists("bglight", $aData["css"]) ? 'td.' . $sPhase . ', div.' . $sPhase . '{' . $aData["css"]["bglight"] . '}' : '';
+    $sHeader.=array_key_exists("bgbutton", $aData["css"]) ? 'a.' . $sPhase . ',a.' . $sPhase . ':hover,button.' . $sPhase . ',button.' . $sPhase . ':hover{' . $aData["css"]["bgbutton"] . '}' : '';
+}
+$sHeader.="</style>\n";
+
+// add shellcmd files
+$sShellOuptut='';
+$sTopRight='';
+
+$CI_plugins=new plugin_renderer(isset($aConfig['plugins']) ? $aConfig['plugins'] : []);
+$CI_plugins->setType('shellcmd');
+
+$aEnabledShellPlugins=$CI_plugins->getEnabledPlugins('shellcmd');
+$sHeader.= count($aEnabledShellPlugins) 
+    ? '' 
+        ."\n<!-- for shellcmd plugins -->\n"
+        .'<script src="/vendor/axelhahn/js/ubd.class.js"></script>'."\n"
+        .'<script src="/vendor/winbox/0.2.82/winbox.min.js"></script>'."\n"
+        .'<link rel="stylesheet" type="text/css" href="/vendor/winbox/0.2.82/winbox.min.css"/>'."\n"
+        ."<!-- shellcmd scripts -->\n"
+    : ''
+    ;
+$aNavRight=[];
+if($oUser->getUsername()){
+    foreach ($aEnabledShellPlugins as $sPlugin){
+        if ($CI_plugins->testPlugin($sPlugin)){
+            $aPluginConfig=$CI_plugins->getPluginConfig();
+            $sHeader.=$CI_plugins->getHtmlLoadScript('render.js');
+            $sShellOuptut.=$CI_plugins->getHtmlOutwindow();
+            $aNavRight[]=['href'=>'#' , 'label'=>$sPlugin, 'icon'=>(isset($aPluginConfig['icon']) ? $aPluginConfig['icon'] : ''), 'onclick'=>'toggleShellWindow(\''.$CI_plugins->getHtmlOutId().'\', this);'];
+            /*
+            $sTopRight.=''
+                .'<li >'
+                .$oHtml->getLink(array(
+                    'href'=>'#',
+                    // 'onclick'=>'toggleShellWindow(\''.$CI_plugins->getHtmlOutIdWrapper().'\', this);',
+                    'onclick'=>'toggleShellWindow(\''.$CI_plugins->getHtmlOutId().'\', this);',
+                    'role'=>'button',
+                    'aria-expanded'=>'false',
+                    'icon'=> (isset($aPluginConfig['icon']) ? $aPluginConfig['icon'] : ''),
+                    'label'=>$sPlugin,
+                ))
+                .'</li>'
+            ;
+            */
         }
     }
-    $oCLog->add("parsing params "
-            . '<pre>GET '.print_r($_GET, true).'</pre>'
-            . '<pre>POST '.print_r($_POST, true).'</pre>'
-            . '<pre>aParams: '.print_r($aParams, true).'</pre>'
-            );
-    
-    if($bFirstRun){
-        $sAction='installer';
+    if(count($aNavRight)){
+        $aNavRight[]=['label'=>'|'];
     }
-            
-    // ----------------------------------------------------------------------
-    // html header
-    // ----------------------------------------------------------------------
+}
 
+// ----------------------------------------------------------------------
+// html body
+// ----------------------------------------------------------------------
+$BODY="";
+$TITLE="";
 
-    $oUser=new user();
+$sBanner=isset($aConfig['banner']) && $aConfig['banner'] ? '<div class="alert alert-info">'.$aConfig['banner'].'</div>' : '';
+
+if(isset($aParams["prj"])){
+    $oPrj = new project($aParams["prj"]);
+    $TITLE=$oPrj->getLabel().' <div class="description">'.$oPrj->getDescription().'</div>';
+} else {
+    $TITLE=t("overview-label") . '<div class="description">' . t("overview-hint") . '</div>';
+}
+// $sReturn.='<h1>' . $oPrj->getLabel() . '</h1>'
+//         . '<span class="description">' . $oPrj->getDescription() . '</span>';
+
+// ------ action 
+if (isset($aConfig["auth"]['forceuser']) && $aConfig["auth"]['forceuser']){
+    $oCLog->add("Found config -> auth -> forceuser: using fake identity [".$aConfig["auth"]['forceuser'].']', "warning");
+    $oUser->setUser($aConfig["auth"]['forceuser']);
+}
+
+// ------ action
+if (isset($aConfig["auth"]['forceuser']) && $aConfig["auth"]['forceuser']){
+    $oCLog->add("Found config -> auth -> forceuser: using fake identity [".$aConfig["auth"]['forceuser'].']', "warning");
+    $oUser->setUser($aConfig["auth"]['forceuser']);
+}
 
-    $sHeader = "\n<!-- generated CSS for phases -->\n<style>\n";
-    foreach ($aConfig["phases"] as $sPhase => $aData) {
-        $sHeader.=array_key_exists("bgdark", $aData["css"]) ? 'th.' . $sPhase . '{' . $aData["css"]["bgdark"] . '}' : '';
-        $sHeader.=array_key_exists("bglight", $aData["css"]) ? 'td.' . $sPhase . ', div.' . $sPhase . '{' . $aData["css"]["bglight"] . '}' : '';
-        $sHeader.=array_key_exists("bgbutton", $aData["css"]) ? 'a.' . $sPhase . ',a.' . $sPhase . ':hover,button.' . $sPhase . ',button.' . $sPhase . ':hover{' . $aData["css"]["bgbutton"] . '}' : '';
+if ($oUser->hasPermission('page_'.$sAction)){
+
+    $sActionFile = __DIR__ . '/pages/act_' . $sAction . ".php";
+
+    $oCLog->add("including $sActionFile");
+    ob_start();
+    if (!@include($sActionFile)) {
+        include("./pages/error_404.php");
     }
-    $sHeader.="</style>\n";
-
-    // add shellcmd files
-    $sShellOuptut='';
-    $sTopRight='';
-
-    $CI_plugins=new plugin_renderer(isset($aConfig['plugins']) ? $aConfig['plugins'] : []);
-    $CI_plugins->setType('shellcmd');
-
-    $aEnabledShellPlugins=$CI_plugins->getEnabledPlugins('shellcmd');
-    $sHeader.= count($aEnabledShellPlugins) 
-        ? '' 
-            ."\n<!-- for shellcmd plugins -->\n"
-            .'<script src="/vendor/axelhahn/js/ubd.class.js"></script>'."\n"
-            .'<script src="/vendor/winbox/0.2.82/winbox.min.js"></script>'."\n"
-            .'<link rel="stylesheet" type="text/css" href="/vendor/winbox/0.2.82/winbox.min.css"/>'."\n"
-            ."<!-- shellcmd scripts -->\n"
-        : ''
+    $OUT = ob_get_contents();
+    ob_end_clean();
+    $oCLog->add("including done $sActionFile");
+
+    // echo "BODY is $BODY";
+    // echo "OUT is $OUT";
+    if(!$BODY){
+        $BODY=""
+            // ."INFO: $sActionFile did not set \$BODY<br><br>"
+            .$renderAdminLTE->getCard([
+                // 'title'=>'Hello',
+                'type'=>'gray',
+                'variant'=>'outline',
+                'text'=>$OUT,
+            ])
         ;
-    $aNavRight=[];
+    }
+    if(!$TITLE){
+        $TITLE="WARNING: $sActionFile did not set \$TITLE";
+    }
+    $oCLog->add("adding actionlog.class");
+
     if ($oUser->getUsername()){
-        foreach ($aEnabledShellPlugins as $sPlugin){
-            if ($CI_plugins->testPlugin($sPlugin)){
-                $aPluginConfig=$CI_plugins->getPluginConfig();
-                $sHeader.=$CI_plugins->getHtmlLoadScript('render.js');
-                $sShellOuptut.=$CI_plugins->getHtmlOutwindow();
-                $aNavRight[]=['href'=>'#' , 'label'=>$sPlugin, 'icon'=>(isset($aPluginConfig['icon']) ? $aPluginConfig['icon'] : ''), 'onclick'=>'toggleShellWindow(\''.$CI_plugins->getHtmlOutId().'\', this);'];
-                /*
-                $sTopRight.=''
-                    .'<li >'
-                    .$oHtml->getLink(array(
-                        'href'=>'#',
-                        // 'onclick'=>'toggleShellWindow(\''.$CI_plugins->getHtmlOutIdWrapper().'\', this);',
-                        'onclick'=>'toggleShellWindow(\''.$CI_plugins->getHtmlOutId().'\', this);',
-                        'role'=>'button',
-                        'aria-expanded'=>'false',
-                        'icon'=> (isset($aPluginConfig['icon']) ? $aPluginConfig['icon'] : ''),
-                        'label'=>$sPlugin,
-                    ))
-                    .'</li>'
-                ;
-                */
-            }
-        }
-        if(count($aNavRight)){
-            $aNavRight[]=['label'=>'|'];
+        require_once("./classes/actionlog.class.php");
+        $aFilter=array('limit'=>'0, 10');
+        if ($sPrj && $sPrj!="all"){
+            $aFilter['project']=$sPrj;
         }
-    }
+        $oLog=new Actionlog($sPrj);
+        $sLogOutput=$oLog->renderLogs($aFilter);
+        $BODY.=($sLogOutput > ' '
+            ? $renderAdminLTE->getCard([
+                'type'=>'',
+                'variant'=>'outline',
+                'text'=>$sLogOutput
+            ])
+            : ''
+        )
+        ;
 
-    // ----------------------------------------------------------------------
-    // html body
-    // ----------------------------------------------------------------------
-    $BODY="";
-    $TITLE="";
-    
-    $sTopArea=getTopArea(['right'=>$sTopRight]);
-    $sBanner=isset($aConfig['banner']) && $aConfig['banner'] ? '<div class="alert alert-info">'.$aConfig['banner'].'</div>' : '';
-
-    if(isset($aParams["prj"])){
-        $oPrj = new project($aParams["prj"]);
-        $TITLE=$oPrj->getLabel().' <div class="description">'.$oPrj->getDescription().'</div>';
-    } else {
-        $TITLE=t("overview-label") . '<div class="description">' . t("overview-hint") . '</div>';
     }
-    // $sReturn.='<h1>' . $oPrj->getLabel() . '</h1>'
-    //         . '<span class="description">' . $oPrj->getDescription() . '</span>';
+    $oCLog->add("adding actionlog.class done");
+} else {
+    $BODY=$oUser->showDenied();
+    // return false;
+}
 
-    // ------ action 
-    if (isset($aConfig["auth"]['forceuser']) && $aConfig["auth"]['forceuser']){
-        $oCLog->add("Found config -> auth -> forceuser: using fake identity [".$aConfig["auth"]['forceuser'].']', "warning");
-        $oUser->setUser($aConfig["auth"]['forceuser']);
-    }
 
-    if ($oUser->hasPermission('page_'.$sAction)){
 
-        $sActionFile = __DIR__ . '/pages/act_' . $sAction . ".php";
-
-        $oCLog->add("including $sActionFile");
-        ob_start();
-        if (!@include($sActionFile)) {
-            include("./pages/error_404.php");
-        }
-        $OUT = ob_get_contents();
-        ob_end_clean();
-        $oCLog->add("including done $sActionFile");
-    
-        // echo "BODY is $BODY";
-        // echo "OUT is $OUT";
-        if(!$BODY){
-            $BODY=""
-                // ."INFO: $sActionFile did not set \$BODY<br><br>"
-                .$renderAdminLTE->getCard([
-                    // 'title'=>'Hello',
-                    'type'=>'gray',
-                    'variant'=>'outline',
-                    'text'=>$OUT,
-                ])
-            ;
-        }
-        if(!$TITLE){
-            $TITLE="WARNING: $sActionFile did not set \$TITLE";
-        }
-        $oCLog->add("adding actionlog.class");
-
-        if ($oUser->getUsername()){
-            require_once("./classes/actionlog.class.php");
-            $aFilter=array('limit'=>'0, 10');
-            if ($sPrj && $sPrj!="all"){
-                $aFilter['project']=$sPrj;
-            }
-            $oLog=new Actionlog($sPrj);
-            $sLogOutput=$oLog->renderLogs($aFilter);
-            $BODY.=($sLogOutput > ' '
-                ? $renderAdminLTE->getCard([
-                    'type'=>'',
-                    'variant'=>'outline',
-                    'text'=>$sLogOutput
-                ])
-                : ''
-            )
-            ;
-
-        }
-        $oCLog->add("adding actionlog.class done");
-    } else {
-        $BODY=$oUser->showDenied();
-        // return false;
-    }
+// ----------------------------------------------------------------------
+// render page
+// ----------------------------------------------------------------------
 
+$oCLog->add("Finally: rendering page ...");
 
+$BODY = '
+    ' 
+    . $sHeader
+    . $sShellOuptut
+    .'
+        ' . $sBanner . ($oUser->getUsername() ? getBreadcrumb() : '') . '
+    
+        ' . $BODY . '
     
-    // ----------------------------------------------------------------------
-    // render page
-    // ----------------------------------------------------------------------
-
-    $oCLog->add("Finally: rendering page ...");
-
-    $BODY = '
-        ' 
-        . $sHeader
-        . $sShellOuptut
-        .'
-            ' . $sBanner . ($oUser->getUsername() ? getBreadcrumb() : '') . '
-        
-            ' . $BODY . '
-        
 
-        <!--        
-        <div id="footer">
-            '.t("menu-brand").' &copy; 2013-' . date("Y") . ' <a href="https://git-repo.iml.unibe.ch/iml-open-source/imldeployment/" target="_blank">Institut f&uuml;r Medizinische Lehre; Universit&auml;t Bern</a>
-        </div>
-        -->
-        '
-        .$oCLog->render();
-
-    /*
-    $oPage = new Page();
-    $oPage->addResponseHeader("Pragma: no-cache");
-    $oPage->setOutputtype('html');
-    $oPage->setHeader($sHeader);
-    $oPage->addJsOnReady('');
-
-    $oPage->setContent($BODY);
-    echo $oPage->render();
-    */
-
-/*
-$sObject=queryparam::get('object', '/^[a-z\_]*$/');
-
-$sTabApp=queryparam::get('app', '/^[a-z\-]*$/');
-if(!$sTabApp && !$sPpage){
-    // $sTabApp=array_key_first($aObjects);
-    header('location: ?page=home');
-    return true;
-}
+    <!--        
+    <div id="footer">
+        '.t("menu-brand").' &copy; 2013-' . date("Y") . ' <a href="https://git-repo.iml.unibe.ch/iml-open-source/imldeployment/" target="_blank">Institut f&uuml;r Medizinische Lehre; Universit&auml;t Bern</a>
+    </div>
+    -->
+    '
+    .$oCLog->render();
 
-*/
 $aTopnav=getTopNavLeft();
 
 $aReplace['{{NAVI_TOP}}']=''
diff --git a/public_html/deployment/main.css b/public_html/deployment/main.css
index b942558f..e098c712 100644
--- a/public_html/deployment/main.css
+++ b/public_html/deployment/main.css
@@ -142,11 +142,15 @@ tr:hover{background:#ddd; background: linear-gradient(#f4f4f4,#fff,#f4f4f4);}
 .trprojectfiltered a.btn,
 .trproject:hover a.btn{opacity: 1;}
 
-.trproject{border-left:0.5em solid rgba(0,0,0,0);}
-tr.progressinprogress{border-left:0.5em solid #8db;}
-div.progressinprogress{color: #6a9;}
-tr.progresshasqueue{border-left:0.5em solid #f81;}
+div.progressinprogress{color: #17a2b8;}
 div.progresshasqueue{color: #d61;}
+tr.progressinprogress{border-left:0.3em solid #17a2b8; }
+tr.progresshasqueue{border-left:0.3em solid #f81;}
+
+td.prj:nth-child(1) a{display: block; padding: 0.3em 0.5em; border-radius: 0.3em; background-color: #e8ecf0;}
+tr.progressinprogress td.prj:nth-child(1) a{ background-color: #17a2b8; color:#fff;}
+tr.progresshasqueue td.prj:nth-child(1) a{ background-color: #d61; color:#fff;}
+
 
 .filterbar{border-bottom: 0px solid #ccc; ;}
 button.prjprogress>span{font-size: 130%;}
@@ -166,6 +170,7 @@ button.prjprogress.selected{box-shadow: 0 0 3em #abc inset; border: 0px solid #a
     display: none;
 }
 
+th.tdphase{border-radius: 0.5em 0.5em 0 0;}
 td.preview{}
 td.stage{}
 td.live{}
@@ -322,7 +327,7 @@ input[type="radio"]:checked+label, input[type="checkbox"]:checked+label{
 /* ----- visualized process ----- */
 .visualprocess{float: left; margin-top: 1em;}
 .visualprocess .process{float:left; text-align: center; padding: 0 0 5px; }
-.visualprocess .process.box{border: 3px dotted #bcd; padding: 0.5em; min-height: 16em;} 
+.visualprocess .process.box{border: 2px dotted #bcd; padding: 0.5em; min-height: 16em;} 
 
 .visualprocess .action{float:left;padding: 0em 1em 1em 1em; background: #fff;}
 .visualprocess .process .title{margin-bottom: 1em; font-weight: bold; font-size: 120%; color:#aaa;}
diff --git a/public_html/deployment/main_new_ui.css b/public_html/deployment/main_new_ui.css
index 028fe392..cf16219e 100644
--- a/public_html/deployment/main_new_ui.css
+++ b/public_html/deployment/main_new_ui.css
@@ -8,10 +8,14 @@ pre.config{background:#f4f4f4; color:#448; border-radius: 0.5em; max-height: aut
 	border-color: #dee2e6 #dee2e6 #fff;
 }
 
-a{color: #06c;}
+a{color: #05c;}
 li a i{color: #699;}
-a.topbrand{font-size: 150%; margin-top: -0.2em; margin-right: 1em;}
-a.topbrand small{margin-left: 0.3em; margin-top: -0.3em; position: absolute;}
+li a i{color: #17a2b8;}
+
+a.topbrand{font-size: 150%; margin-top: -0.2em; margin-right: 0.5em;}
+a.topbrand small{margin-left: 0.3em; font-weight: normal;}
 
 /* no line break in top menu */
-.dropdown-menu a{white-space: nowrap;}
\ No newline at end of file
+.dropdown-menu a{white-space: nowrap;}
+
+.navbar-nav li.divider{border-left: 1px solid rgba(0,0,0,0.2);}
\ No newline at end of file
-- 
GitLab