From 0f8622f8abcf985cf1553d3624cdfc642a9c6bc6 Mon Sep 17 00:00:00 2001 From: "Hahn Axel (hahn)" <axel.hahn@unibe.ch> Date: Tue, 21 Nov 2023 14:55:21 +0100 Subject: [PATCH] update ui; add shellcmd windows --- config/lang/de-de.json | 4 +- config/lang/en-en.json | 6 +- .../deployment/classes/actionlog.class.php | 4 +- .../deployment/classes/htmlelements.class.php | 2 +- .../classes/htmlguielements.class.php | 9 ++- .../deployment/classes/project_gui.class.php | 39 +++++------- .../deployment/classes/projectlist.class.php | 27 +++++++-- .../deployment/classes/rollout.interface.php | 11 ++-- .../deployment/classes/rollout_base.class.php | 12 +++- .../deployment/images/process/bg_archive.png | Bin 2650 -> 0 bytes .../deployment/images/process/bg_phase.png | Bin 6053 -> 0 bytes .../deployment/images/process/bg_vcs.png | Bin 4615 -> 0 bytes public_html/deployment/inc_functions.php | 5 +- public_html/deployment/index.php | 11 +++- public_html/deployment/js/functions.js | 47 +++++++++++++-- public_html/deployment/main.css | 24 ++++---- public_html/deployment/main_new_ui.css | 3 + public_html/deployment/pages/act_login.php | 2 +- public_html/deployment/pages/act_overview.php | 14 ++++- public_html/deployment/pages/act_phase.php | 57 ++++++++++++++---- .../deployment/ui/page_replacements.php | 2 +- 21 files changed, 199 insertions(+), 80 deletions(-) delete mode 100644 public_html/deployment/images/process/bg_archive.png delete mode 100644 public_html/deployment/images/process/bg_phase.png delete mode 100644 public_html/deployment/images/process/bg_vcs.png diff --git a/config/lang/de-de.json b/config/lang/de-de.json index cb4cd76c..55e082a6 100644 --- a/config/lang/de-de.json +++ b/config/lang/de-de.json @@ -35,6 +35,8 @@ "overview-filterreset-hint":"Filter zurücksetzen", "overview-filterprogress":"Fortschritt", "overview-projectcount":"Anzahl der Projekte", + "overview-actions-title":"Actionen", + "overview-actions-hint":"Die wichtigsten Aktionen:", "class-actionlog-title": "Action-Log", "class-actionlog-filter": "Filter", @@ -303,7 +305,7 @@ "ok": "OK", "packages": "Pakete", "phase": "Phase", - "phase-details": "Details", + "phase-details": "Details %s", "phase-details-hint": "Details zur Phase [%s]", "phase-is-active": "Phase aktivieren", "phase-targethosts": "Zielsysteme", diff --git a/config/lang/en-en.json b/config/lang/en-en.json index 0f301b35..8b9d9e3b 100644 --- a/config/lang/en-en.json +++ b/config/lang/en-en.json @@ -20,7 +20,7 @@ "overview-label": "Overview", - "overview-hint":"all projects and versions in all phases", + "overview-hint":"All projects and versions in all phases", "overview-hint-dblclick":"Double click to open the project [%s]", "overview-filter":"Filter", "overview-filter-hint":"Show only this project", @@ -34,6 +34,8 @@ "overview-filterreset-hint":"Remove all filter settings", "overview-filterprogress":"Progress", "overview-projectcount":"Count of projects", + "overview-actions-title":"Actions", + "overview-actions-hint":"Most relevant actions for this project:", "class-actionlog-title": "Action-Log", "class-actionlog-filter": "Filter", @@ -305,7 +307,7 @@ "ok": "OK", "packages": "packages", "phase": "Phase", - "phase-details": "Details", + "phase-details": "Details %s", "phase-details-hint": "Details of phase [%s]", "phase-is-active": "Activate phase", "phase-targethosts": "Target hosts", diff --git a/public_html/deployment/classes/actionlog.class.php b/public_html/deployment/classes/actionlog.class.php index d0a386bc..6a86b3ac 100644 --- a/public_html/deployment/classes/actionlog.class.php +++ b/public_html/deployment/classes/actionlog.class.php @@ -348,8 +348,8 @@ class Actionlog { } else { $sReturn= '<strong>' - . '<button onclick="setLogVisibility(\'block\');" id="btnShowLogs" class="btn btn-secondary btnLogs"><i class="fa-solid fa-chevron-right"></i> </button>' - . '<button onclick="setLogVisibility(\'none\');" id="btnHideLogs" class="btn btn-secondary btnLogs"><i class="fa-solid fa-chevron-down"></i> </button>' + . '<button onclick="setLogVisibility(\'block\');" id="btnShowLogs" class="btn btn-default btnLogs"><i class="fa-solid fa-chevron-right"></i> </button>' + . '<button onclick="setLogVisibility(\'none\');" id="btnHideLogs" class="btn btn-default btnLogs"><i class="fa-solid fa-chevron-down"></i> </button>' . ' ' . t("class-actionlog-title") .(isset($aFilter["project"]) ? ' ['.$aFilter["project"].'] ' : '') . '</strong>' diff --git a/public_html/deployment/classes/htmlelements.class.php b/public_html/deployment/classes/htmlelements.class.php index 91943c7c..0296b178 100755 --- a/public_html/deployment/classes/htmlelements.class.php +++ b/public_html/deployment/classes/htmlelements.class.php @@ -133,7 +133,7 @@ class htmlelements { } // do not use this .. it overrides internal attribute vars // return $this->getTag('i', array('class'=>$sPrefix.$sIconclass)); - return '<i class="'.$sPrefix.$sIconclass.'"></i> '; + return '<i class="'.$sPrefix.$sIconclass.'"></i> '; } diff --git a/public_html/deployment/classes/htmlguielements.class.php b/public_html/deployment/classes/htmlguielements.class.php index 4ebc0406..7c3e2cec 100644 --- a/public_html/deployment/classes/htmlguielements.class.php +++ b/public_html/deployment/classes/htmlguielements.class.php @@ -354,13 +354,18 @@ class htmlguielements{ $aItem[$sKey]=''; } } - $aItem['class'].='btn btn-default'; + // if not class "btn" was added: add "btn" + // if not class "btn-[something]" was added: add "btn-default" + $sClass=$aItem['class']; + $sClass=(strstr($sClass, 'btn-') ? '' : 'btn-default ').$sClass; + $sClass=(strstr($sClass, 'btn ') ? '' : 'btn ').$sClass; + $aItem['class']=$sClass; if (isset($aItem['type'])){ $aItem=$this->_getButtonattributesByType($aItem); unset($aItem['type']); } - + // $aItem['label'].=' -> '.$sClass; return $this->getLink($aItem); } diff --git a/public_html/deployment/classes/project_gui.class.php b/public_html/deployment/classes/project_gui.class.php index 15c1e845..31ea97c9 100644 --- a/public_html/deployment/classes/project_gui.class.php +++ b/public_html/deployment/classes/project_gui.class.php @@ -320,7 +320,7 @@ class projectgui extends project { ), 'phase' => array('icon' => $this->_oHtml->getIcon('phase'), 'class' => $sPhase, 'hint' => sprintf(t('phase-details-hint'), $sPhase), - 'label' => t('phase-details') + 'label' => sprintf(t('phase-details'), $sPhase), ), 'rollback' => array('class' => $sPhase, 'hint' => sprintf(t('rollback-hint'), $sPhase, $sVersion), @@ -328,7 +328,8 @@ class projectgui extends project { ), 'setup' => array('class' => $sPhase, 'hint' => sprintf(t('setup-hint'), $sPhase, $sVersion), - 'label' => t('setup') + 'label' => t('setup'), + 'class' => 'btn-primary' ), ); /* @@ -392,10 +393,11 @@ class projectgui extends project { return '<span class="btn disabled btn-default" title="no permission [project-action-' . $sFunction . '] for user [' . $this->oUser->getUsername() . ']"><i class="' . $sIconClass . '"></i> ' . $sLabel . '</span>'; } + // $sClass='btn ' . (strstr('btn-', $sClass) ? '': 'btn-default ') .$sClass; return $this->_oHtml->getLinkButton(array( 'href' => $sLink, 'title' => $sHint, - 'class' => 'btn btn-default ' . $sClass, + 'class' => $sClass, 'type' => $sFunction, 'onmouseover' => $sOnMouseover, 'onmouseout' => $sOnMouseout, @@ -1361,8 +1363,8 @@ class projectgui extends project { foreach (array_keys($this->getPhases()) as $sPhase) { if ($this->isActivePhase($sPhase)){ $sRolloutDebug.='<strong>'.$sPhase.'</strong>' - . '<pre>Config = '.print_r($this->oRolloutPlugin->getConfig($sPhase), 1).'</pre>' - . '<pre>Commands = '.print_r($this->oRolloutPlugin->getDeployCommands($sPhase), 1).'</pre>' + . '<pre>Config = '.print_r($this->oRolloutPlugin->getConfig($sPhase, 1), 1).'</pre>' + . '<pre>Commands = '.print_r($this->oRolloutPlugin->getDeployCommands($sPhase, 1), 1).'</pre>' ; } } @@ -1609,7 +1611,7 @@ class projectgui extends project { */ public function renderVisual() { $sReturn = ''; - $sContinue = '<span style="font-size: 300%; color:#ace;">»»</span><br><br>'; + $sContinue = '<span style="font-size: 300%; color:#ace;">»»</span><br>'; $aBranches=$this->getRemoteBranches(); if(!is_array($aBranches)){ @@ -1655,32 +1657,25 @@ class projectgui extends project { $sDetail = $sFullbar . '<br>' . $sPhase; $sPhaseImg.=' - <div class="process ' . $sPhase . '"> + <div class="process"> <div class="details">' . $sDetail . ' </div> - <div><img src="/deployment/images/process/bg_phase.png" alt="' . t("phase") . ' ' . $sPhase . '"></div> </div>'; } $sReturn = ' <div class="visualprocess"> <div class="process box"> - <div class="title">' . $this->_oHtml->getIcon('repository') . t("versioncontrol") . '</div> + <div class="title">' . t("versioncontrol") . '</div> <div class="details"> ' . $sRepoBar . '<br> - <!-- - <a href="#h3repo" class="scroll-link">' . t("repositoryinfos") . '</a><br> - --> ' . t("repositoryinfos") . '<br> - ' . $this->_aPrjConfig["build"]["type"] . '</strong> ' . preg_replace('/.*\@(.*):.*/', '($1)', $this->_aPrjConfig["build"]["url"]) - . ': <strong title="' . t('branch-select') . '">' . count($aBranches) . '</strong>' - . '<br> - </div> - <div> - <img src="/deployment/images/process/bg_vcs.png" alt="' . t("versioncontrol") . '"> + ' // . $this->_aPrjConfig["build"]["type"] + . preg_replace('/.*\@(.*):.*/', '$1', $this->_aPrjConfig["build"]["url"]) + . '<br>(<strong title="' . t('branch-select') . '">' . count($aBranches) . '</strong>)' + . ' </div> </div> <div class="process"> - <div class="title"> </div> <div class="action">' . $sContinue . t("build-hint-overview") . '<br><br>' . ($this->canAcceptPhase() ? $this->renderLink("build") : '') . '</div> </div> @@ -1689,17 +1684,12 @@ class projectgui extends project { <div class="title">' . $this->_oHtml->getIcon('package') . t("archive") . '</div> <div class="details"> ' . $sPackagebar . '<br> - <!-- - <a href="#h3versions" class="scroll-link">' . t("packages") . '</a><br> - --> ' . t("packages") . '<br> (<strong>' . count($this->_getVersionUsage()) . '</strong>) </div> - <div><img src="/deployment/images/process/bg_archive.png" alt="' . t("archive") . '"></div> </div> <div class="process"> - <div class="title"> </div> <div class="action">'.$sContinue . sprintf(t("queue-hint-overview"), $this->getNextPhase()).'</div> </div> @@ -1710,7 +1700,6 @@ class projectgui extends project { </div> <div style="clear:both"></div> '; - return $sReturn; } diff --git a/public_html/deployment/classes/projectlist.class.php b/public_html/deployment/classes/projectlist.class.php index 332f48be..72f7065d 100644 --- a/public_html/deployment/classes/projectlist.class.php +++ b/public_html/deployment/classes/projectlist.class.php @@ -49,7 +49,8 @@ class projectlist extends base{ * @return string */ public function renderOverview() { - + global $renderAdminLTE; + $sOut = ''; // table $sOut2 = ''; // tiles $oPrj = false; @@ -57,7 +58,7 @@ class projectlist extends base{ $sColClass = "tdphase"; $sNone='none'; - $oPrj1 = new project(); + $oPrj1 = new projectgui(); $oHtml=new htmlguielements(); $sPrjFilter = ''; @@ -238,7 +239,7 @@ class projectlist extends base{ $sRowHead1.='<th class="' . $sPhase . ' ' . $sColClass . '" colspan="3">' . $oHtml->getIcon('phase').$sPhase . '</th>'; $sRowHead2.=$oPrj->renderPlacesAsTd($sPhase); } - $sOut = ' + $sOutTop = ' <script> /** @@ -550,9 +551,8 @@ class projectlist extends base{ onclick="resetFilter();">'.$oHtml->getIcon('close').t("overview-filterreset") . '</a> </form> <div style="clear: both; margin-bottom: 1em"></div> - </div> - - '.$sErrors + </div>'; + $sOut=$sErrors /* .' @@ -584,6 +584,21 @@ class projectlist extends base{ . $oPrj1->renderLink("new") ; } + + $sOut='' + .$renderAdminLTE->addRow( + $renderAdminLTE->addCol($sOutTop, 12) + ) + .$renderAdminLTE->addRow( + $renderAdminLTE->addCol( + $renderAdminLTE->getCard([ + 'type'=>'gray', + 'variant'=>'outline', + 'text'=>$sOut, + ]), + 12 + ) + ); return $sOut; } diff --git a/public_html/deployment/classes/rollout.interface.php b/public_html/deployment/classes/rollout.interface.php index 5b84025c..5b973b93 100644 --- a/public_html/deployment/classes/rollout.interface.php +++ b/public_html/deployment/classes/rollout.interface.php @@ -30,16 +30,19 @@ interface iRolloutplugin { /** * get configuration for the project .. or more specifi for a given phase - * @param string $sPhase + * @param string $sPhase + * @param boolean $bMask Flag for public output; if true then mask your secrets + * @return array */ - public function getConfig($sPhase=false); + public function getConfig($sPhase=false, $bMask=false); /** * get an array with shell commands to execute - * @param string $sPhase + * @param string $sPhase + * @param boolean $bMask Flag for public output; if true then mask your secrets * @return array */ - public function getDeployCommands($sPhase); + public function getDeployCommands($sPhase, $bMask=false); /** * get name of plugin as string ... language specific diff --git a/public_html/deployment/classes/rollout_base.class.php b/public_html/deployment/classes/rollout_base.class.php index f16760c0..8d804d55 100644 --- a/public_html/deployment/classes/rollout_base.class.php +++ b/public_html/deployment/classes/rollout_base.class.php @@ -456,12 +456,22 @@ class rollout_base implements iRolloutplugin{ * @param string $sPhase * @return array */ - public function getConfig($sPhase=false){ + public function getConfig($sPhase=false, $bMask=false){ + $aReturn=array_merge($this->_aCfgGlobal, $this->_aCfgProject['plugins']['rollout'][$this->getId()]); + if($sPhase && isset($this->_aCfgProject['phases'][$sPhase]['plugins']['rollout'][$this->getId()])){ + $aReturn=array_merge($aReturn, $this->_aCfgProject['phases'][$sPhase]['plugins']['rollout'][$this->getId()]); + } + if ($bMask && isset($aReturn['password'])){ + $aReturn['password']='**********'; + } + return $aReturn; + /* return ($sPhase && isset($this->_aCfgProject['phases'][$sPhase]['plugins']['rollout'][$this->getId()])) ? array_merge($this->_aCfgGlobal, $this->_aCfgProject['plugins']['rollout'][$this->getId()], $this->_aCfgProject['phases'][$sPhase]['plugins']['rollout'][$this->getId()]) : array_merge($this->_aCfgGlobal, $this->_aCfgProject['plugins']['rollout'][$this->getId()]) ; + */ } /** diff --git a/public_html/deployment/images/process/bg_archive.png b/public_html/deployment/images/process/bg_archive.png deleted file mode 100644 index ed08763510365a868d96887e1bf3b434fd66b0de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2650 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 F2>{4j?+O3_ diff --git a/public_html/deployment/images/process/bg_phase.png b/public_html/deployment/images/process/bg_phase.png deleted file mode 100644 index 583be7a4f1872ec49c7b8c4f2cd7a67f9bf803cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6053 zcmeAS@N?(olHy`uVBq!ia0y~yV8~-&U|7Y$#=yYfqf`~iz`($g?&#~tz_78O`%fY( z0|NtRfk$L90|Vbd5N6ylG5ak81A|nFYeY$Kep*R+Vo@qXKw@TIiJqTph(ejMo~fRp zfx(xeg$xYhik>cxAr*0N=UNshyH9JoE>nEQ@OVt|SukOGJf>JTc42_VmR(NEw{H9t zHfiDM3zCX!w*+l*3VOlu)vI>G-8X7C6&ybta*Sc=PupH}fBK2=xuI)VJeXRwGG6sp z#D3khiL3Mb)zga^O#U-U`Y*MYuUoU>${!6Tai!H-f17^hMQ5F3IdSsD^g6wPlSqHU z&&FK*^HXZ^?{B%qkB{}9d2?-T^s{dLeH+&II=u}PJ=!lS=4t=;%jBKq@8h18Ra9hb zm#_b`vHI!H02V!$Fw^Y+mzH`jZ?e&~wzS-M;KZxA_3340Wj_1wo6FaJnOObx<^K6A zf9FM8oMn>PU^Tbz=8YQ$SF^4%eR(Jv*)XT4#;tDJgTDTLU5ib*`T6J9tXUJ$k;C|+ zeD=a`D?fcoZgma1_F&6wmOGa&P10S?Q<3sOeSXcOs30HL2Tm!Wo4=*AuDh8tEBpGo zo9`wkbLH38?!A#b@3xrVW|rfdoDU{)@&EpCm_N3=OVz>8%}%*~+JlIy9}f	`~# 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 diff --git a/public_html/deployment/images/process/bg_vcs.png b/public_html/deployment/images/process/bg_vcs.png deleted file mode 100644 index 305dd07539cd62795aea535572bf2a7f64396188..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4615 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 diff --git a/public_html/deployment/inc_functions.php b/public_html/deployment/inc_functions.php index ac094fee..0d522afc 100644 --- a/public_html/deployment/inc_functions.php +++ b/public_html/deployment/inc_functions.php @@ -228,7 +228,7 @@ function getTopNavLeft($aEmbed=[]) { $aReturn=[ // ['label'=>'=' ], - ['href'=>$sBaseUrl . '', 'label'=>' CI server <small>v2</small>', 'icon'=>'', 'class'=>'imllogo topbrand' ], + ['href'=>$sBaseUrl . '', 'label'=>' Deployment UI <small>v2</small>', 'icon'=>'', 'class'=>'imllogo topbrand' ], [ 'href'=>$sBaseUrl, 'label'=>t("menu"), 'class'=>(array_key_exists("prj", $aParams) && $aParams['prj']==='all' ? 'active' : ''), 'icon'=>'fa-solid fa-chevron-right', @@ -628,6 +628,9 @@ function getBreadcrumb($sLinkClass="") { // .'<h2 class="'.$sClass.'"> '.$sLabel.'</h2>' ; $sReturn.=($sNav ? '' . $sNav . ' ' . $sDelim . ' <span class="current">'.$sLabel.'</span>':''); + if($sLinkClass){ + $sReturn=str_replace(['btn-default ', 'btn '], ['', ''], $sReturn); + } return $sReturn; } diff --git a/public_html/deployment/index.php b/public_html/deployment/index.php index ed0b89c5..2527c111 100644 --- a/public_html/deployment/index.php +++ b/public_html/deployment/index.php @@ -82,11 +82,14 @@ $aReplace=include("./ui/page_replacements.php"); ."<!-- shellcmd scripts -->\n" : '' ; + $aNavRight=[]; 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( @@ -100,8 +103,12 @@ $aReplace=include("./ui/page_replacements.php"); )) .'</li>' ; + */ } } + if(count($aNavRight)){ + $aNavRight[]=['label'=>'|']; + } // ---------------------------------------------------------------------- @@ -170,7 +177,7 @@ $aReplace=include("./ui/page_replacements.php"); $sLogOutput=$oLog->renderLogs($aFilter); $BODY.=($sLogOutput > ' ' ? $renderAdminLTE->getCard([ - 'type'=>'gray', + 'type'=>'', 'variant'=>'outline', 'text'=>$sLogOutput ]) @@ -238,7 +245,7 @@ $aTopnav=getTopNavLeft(); $aReplace['{{NAVI_TOP}}']='' . $renderAdminLTE->addWrapper( 'nav', ['class'=>'main-header navbar navbar-expand navbar-white navbar-light'], - $renderAdminLTE->getTopNavigation($aTopnav,false, getTopNavRight(), false) + $renderAdminLTE->getTopNavigation($aTopnav,false, array_merge($aNavRight, getTopNavRight()), false) // add 2nd navbar if needed ) ; diff --git a/public_html/deployment/js/functions.js b/public_html/deployment/js/functions.js index 2a68b11f..72ed6616 100644 --- a/public_html/deployment/js/functions.js +++ b/public_html/deployment/js/functions.js @@ -26,7 +26,9 @@ function showModalMessage(sMessage){ $('#divmodalmessage').html(sMessage); $('#divmodal').show(); } -function showIdAsModalMessage(sId){ + +function showIdAsModalMessage(sId, sTitle){ + var o=$('#'+sId); var sHtml='<a href="#" onclick="return hideModalMessage()" class="btn btn-danger" style="float:right"> X </a>' + o.html() @@ -34,7 +36,39 @@ function showIdAsModalMessage(sId){ ; $('#divmodalmessage').html(sHtml); $('#divmodal').show(); - return false; + + /* + var oWrapper=document.getElementById(sId); + new WinBox({ + title: sTitle, + id: 'winbox-'+sId, + border: 5, + background: "#628", + class: [ "no-min", "no-max", "no-full", "ciwinboxinfos" ], + + // modal: true, // collides with bootsrap3 .modal.less + + // position + size + x: "center", + y: "center", + width: 700, + height: 500, + + // viewport + top: 70, + right: 20, + bottom: 20, + left: 20, + + + // take content from existing div + // mount: oWrapper + html: oWrapper.innerHTML + // html: 'hello' + }); + + */ + return false; } function hideModalMessage(){ @@ -57,7 +91,8 @@ function toggleShellWindow(isPluginOutputDiv, oLink){ title: oLink.innerText, id: 'winbox-'+isPluginOutputDiv, border: 5, - background: "#628", + /*background: "#628",*/ + background: "#478", class: [ "no-min", "no-max", /* "no-full", "no-resize", "no-move"*/ "ciwinbox" ], // position + size @@ -77,10 +112,12 @@ function toggleShellWindow(isPluginOutputDiv, oLink){ onclose: function(){ delete aWinBoxes[isPluginOutputDiv]; - $(oLink).parent().removeClass('active'); + $(oLink).removeClass('active'); } }); - $(oLink).parent().addClass('active'); + if(oLink){ + $(oLink).addClass('active'); + } window.setTimeout("aWinBoxes['"+isPluginOutputDiv+"'].resize("+(oWrapper.clientWidth+25)+", "+(oWrapper.clientHeight+150)+").move('center', 'center')", 10); } } diff --git a/public_html/deployment/main.css b/public_html/deployment/main.css index d65f1c3e..f667b8dc 100644 --- a/public_html/deployment/main.css +++ b/public_html/deployment/main.css @@ -104,7 +104,7 @@ h4{color:#666;} */ #imgtop{float:left; margin: 0 20px 20px 0;} -pre{line-height: 1.2em; padding: 5px;} +pre{line-height: 1.2em; padding: 5px; background: #f0f4f4;} pre.cli{ color:#555;} pre.clistrong{color: #000;} td{vertical-align: top; border-left: 1px solid #fff;} @@ -127,10 +127,10 @@ ul li { .viewextended{} .viewsimple{display: none;} -thead{font-size: 130%;} +thead{font-size: 110%;} -#tbloverview th{} -#tbloverview td{} +#tbloverview th{ padding: 0.3em; } +#tbloverview td{padding: 0.2em;} th{/*border-radius: 0.7em 0.7em 0 0; background:#f0f0f0; */ text-align: center; border-right: 1px solid #fff; } thead tr th.prj{border-bottom: none;} th.versioncontrol{background: #eee; } @@ -198,7 +198,7 @@ a.expandable:before{ color:#a00; content: '+'; float: left; - font-size: 150%; + font-size: 120%; margin-right: 0em; text-align: center; transition: ease-in 0.3s; @@ -290,14 +290,14 @@ input[type="radio"]:checked+label, input[type="checkbox"]:checked+label{ .cmdoutbox{display: none;} .ciwinbox .wb-body{ background: #111 !important; - color: #ccf; + color: #cee; font-family: monospace; padding: 0.5em; overflow: scroll; white-space: nowrap; } .ciwinbox .bar{background: rgba(255,255,255,0.1);} -.ciwinbox .progress{background: #85a;} +.ciwinbox .progress{background: #367;} /* showIdAsModalMessage() - when using winbox */ .ciwinboxinfos .wb-body{ @@ -320,15 +320,13 @@ input[type="radio"]:checked+label, input[type="checkbox"]:checked+label{ .cmd-cols-100{width: 100em; max-width: 100em;} /* ----- visualized process ----- */ -.visualprocess{float: left; padding: 1em; box-shadow: 0 0 0em #ddd;} +.visualprocess{float: left; margin-top: 1em;} .visualprocess .process{float:left; text-align: center; padding: 0 0 5px; } -.visualprocess .process.box{border: 80 dashed #ddd; } +.visualprocess .process.box{border: 3px dotted #bcd; padding: 0.5em; min-height: 14em;} -.visualprocess .process img{} -.visualprocess .process img{} .visualprocess .action{float:left;padding: 0em 1em 1em 1em; background: #fff;} -.visualprocess .process .title{margin-bottom: 1em; font-weight: bold; font-size: 150%; color:#aaa;} -.visualprocess .process .details{background: #fff; min-height: 6em;} +.visualprocess .process .title{margin-bottom: 1em; font-weight: bold; font-size: 120%; color:#aaa;} +.visualprocess .process .details{} /* ----- replacemets with templates ----- */ span.replace{background:#fea; font-weight: bold;} diff --git a/public_html/deployment/main_new_ui.css b/public_html/deployment/main_new_ui.css index 63b4cde1..028fe392 100644 --- a/public_html/deployment/main_new_ui.css +++ b/public_html/deployment/main_new_ui.css @@ -8,7 +8,10 @@ pre.config{background:#f4f4f4; color:#448; border-radius: 0.5em; max-height: aut border-color: #dee2e6 #dee2e6 #fff; } +a{color: #06c;} +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;} /* no line break in top menu */ .dropdown-menu a{white-space: nowrap;} \ No newline at end of file diff --git a/public_html/deployment/pages/act_login.php b/public_html/deployment/pages/act_login.php index 08c14619..d760a4f7 100644 --- a/public_html/deployment/pages/act_login.php +++ b/public_html/deployment/pages/act_login.php @@ -61,7 +61,7 @@ if ($oUser->getUsername()) { . '<ul>'.$sGrouplist . '</ul><br>' . '<div style="clear: both; margin-bottom: 1em;"></div>' . ' ' . aPrjHome() . ' ' - . '<a href="?logoff=1" class="btn btn-default btn-danger">' . $oHtml->getIcon('poweroff') . t('logoff') . '</a>' + . '<a href="?logoff=1" class="btn btn-danger">' . $oHtml->getIcon('poweroff') . t('logoff') . '</a>' // . '<br><br>INFO: <pre style="">roles:<br>' . print_r($oUser->getUserPermission(), true) . '</pre>' . '</p>' diff --git a/public_html/deployment/pages/act_overview.php b/public_html/deployment/pages/act_overview.php index c6d2b6af..c148cf5d 100644 --- a/public_html/deployment/pages/act_overview.php +++ b/public_html/deployment/pages/act_overview.php @@ -23,7 +23,7 @@ if (!array_key_exists("prj", $aParams)) { // ---------------------------------------------------------------------- require_once("./classes/projectlist.class.php"); $oPrjList = new projectlist(); - $sOut = $oPrjList->renderOverview(); + $BODY = $oPrjList->renderOverview(); } else { // ---------------------------------------------------------------------- @@ -108,6 +108,14 @@ if (!array_key_exists("prj", $aParams)) { ]) ; + $sPhaselinks=''; + $sLastPhase = ''; + foreach($oPrj->getActivePhases() as $sPhase){ + $sPhaselinks.='<div class="btn-group w-100">'.$oPrj->renderLink("phase", $sPhase).'</div>' + //. (!$oPrj->canAcceptPhase($sPhase) ? '<div class="btn-group w-100">'.$oPrj->renderLink("accept", $sPhase).'</div>' : '') + .'<br><br>'; + $sLastPhase = $sPhase; + } $BODY= $renderAdminLTE->addRow( $renderAdminLTE->addCol( @@ -127,6 +135,10 @@ if (!array_key_exists("prj", $aParams)) { . t('overview-actions-hint').'<br>' . '<div class="btn-group w-100">'.$oPrj->renderLink("setup").'</div><br><br>' .($oPrj->canAcceptPhase() ? '<div class="btn-group w-100">'.$oPrj->renderLink("build").'</div><br><br>' : '') + .($sPhaselinks + ? t("page-overview-phase-infos").'<br>'.$sPhaselinks + : '' + ) ]), 2 ) diff --git a/public_html/deployment/pages/act_phase.php b/public_html/deployment/pages/act_phase.php index 718c9a80..d67e2be8 100644 --- a/public_html/deployment/pages/act_phase.php +++ b/public_html/deployment/pages/act_phase.php @@ -12,7 +12,7 @@ ###################################################################### */ require_once("./classes/project_gui.class.php"); -require_once("./inc_functions.php"); +// require_once("./inc_functions.php"); require_once("./classes/config-replacement.class.php"); @@ -37,7 +37,7 @@ if ($sPhase) { $aReplacements=$oConfig->getReplacements(); - $sOut.='<h3>' . $oHtml->getIcon('replace') . t("replacements") . '</h3>'; + $sOutReplace.='<h3>' . $oHtml->getIcon('replace') . t("replacements") . '</h3>'; // ---------------------------------------------------------------------- // Links to foreman @@ -48,7 +48,7 @@ if ($sPhase) { // echo '<pre>$aReplacements = '.print_r($aReplacements, 1) . '</pre>'; // echo '<pre>$aForeman = '.print_r($aForeman, 1) . '</pre>'; - $sOut.=($aForeman + $sOutReplace.=($aForeman ? $oConfig->getForemanlink2Hostgroup().' ' .$oConfig->getForemanlink2Host() : t('foreman-no-host') @@ -169,16 +169,18 @@ if ($sPhase) { .'</pre>'; // --- output with tabs for a template file - $sOutReplace.=$oHtml->getNav( - array( + $sOutReplace.='<div>' + .$renderAdminLTE->getTabbedContent( + [ 'options'=>array('type'=>'tabs'), 'tabs'=>array( $oHtml->getIcon('list') . t('replacement-fields') => '<br>'.$oHtml->getTable($aTable), $oHtml->getIcon('file-template') . $tTplFile => $ContentFile, ) - ) - ) - .'<br></div>'; + ]) + .'</div>' + + .'</div>'; } } else { $sOutReplace.=t('none'); @@ -219,9 +221,9 @@ if ($sPhase) { } if (count($aWarnings)){ - $sOut.=$oHtml->getBox('warning', '<ul><li>'.implode('<li>', $aWarnings).'</ul>'); + $sOutReplace.=$oHtml->getBox('warning', '<ul><li>'.implode('<li>', $aWarnings).'</ul>'); } - $sOut.=$sOutReplace; + // ---------------------------------------------------------------------- // versions @@ -248,7 +250,7 @@ if ($sPhase) { // ---------------------------------------------------------------------- // show all phases if there are more than one - $sOut.=(count($oPrj->getActivePhases())>1 + $sOutPhases=(count($oPrj->getActivePhases())>1 ? '<h3>' . $oHtml->getIcon('phase').t("phases") . '</h3>' . $oPrj->renderPhaseInfo() : '' ) @@ -263,7 +265,38 @@ if ($sPhase) { $sOut.=$oHtml->getBox("error", t("error-no-phase")); } + +$BODY=$renderAdminLTE->addRow( + $renderAdminLTE->addCol( + $renderAdminLTE->getCard([ + 'type'=>'gray', + 'variant'=>'outline', + 'text'=>$sOutReplace, + ]), 12 + ) +) +.$renderAdminLTE->addRow( + $renderAdminLTE->addCol( + $renderAdminLTE->getCard([ + 'type'=>'gray', + 'variant'=>'outline', + 'text'=>$sOut, + ]), 12 + ) +) +.$renderAdminLTE->addRow( + $renderAdminLTE->addCol( + $renderAdminLTE->getCard([ + 'type'=>'gray', + 'variant'=>'outline', + 'text'=>$sOutPhases, + ]), 12 + ) +) + +; + // $sOut.= '<div id="navbuttom">' . aPrjHome() . '</div>'; // -- Ausgabe -echo $sOut; +// echo $sOut; diff --git a/public_html/deployment/ui/page_replacements.php b/public_html/deployment/ui/page_replacements.php index 68a225b0..6fb0fb3f 100644 --- a/public_html/deployment/ui/page_replacements.php +++ b/public_html/deployment/ui/page_replacements.php @@ -15,7 +15,7 @@ return [ // '{{NAVI_TOP}}' =>'<nav class="main-header navbar navbar-expand navbar-white navbar-light"><ul class="navbar-nav" id="instances"></ul></nav>', '{{BRAND}}' =>'<a href="?" class="brand-link bg-red"> <i class="fa-solid fa-cubes"></i> - IML <span class="brand-text">CI server</span> + IML <span class="brand-text">Deployment UI</span> <span class="brand-text font-weight-light">v2</span> </a>', '{{NAVI_LEFT}}' =>' -- GitLab