<?php /* ###################################################################### IML DEPLOYMENT class projectlist to render overview page --------------------------------------------------------------------- 2013-11-08 Axel <axel.hahn@iml.unibe.ch> ###################################################################### */ require_once 'base.class.php'; require_once 'project_gui.class.php'; /** * class for project overview */ class projectlist extends base { // ---------------------------------------------------------------------- // CONFIG // ---------------------------------------------------------------------- // ---------------------------------------------------------------------- // constructor // ---------------------------------------------------------------------- /** * constructor2 called from constructor of base class */ public function __construct() { $this->oUser = new user(); } // ---------------------------------------------------------------------- // private functions // ---------------------------------------------------------------------- // ---------------------------------------------------------------------- // GETTER // ---------------------------------------------------------------------- // ---------------------------------------------------------------------- // SETTER // ---------------------------------------------------------------------- // ---------------------------------------------------------------------- // ACTIONS // ---------------------------------------------------------------------- /** * render html for overview table * @return string */ public function renderOverview() { global $renderAdminLTE; $sOut = ''; // table $sOut2 = ''; // tiles $oPrj = false; $sTrClass = "trproject"; $sColClass = "tdphase"; $sNone = 'none'; $oPrj1 = new projectgui(); $oHtml = new htmlguielements(); $sPrjFilter = ''; $sPrjGroupFilter = ''; $sPhaseFilter = ''; $sPrjFilter .= '<option value="">' . t("all") . '</option>'; $sPrjGroupFilter .= '<option value="">' . t("all") . '</option>'; $sPhaseFilter .= '<option value="' . $sColClass . '">' . t("all") . '</option>'; $iInprogress = 0; $iHasqueue = 0; $aPrjGroups = []; $sDivInprogress = '<div class="progressinprogress" title="' . t("progress-inprogress") . '">' . $oHtml->getIcon('refresh') . t("progress-inprogress") . '</div>'; $sDivHasqueue = '<div class="progresshasqueue" title="' . t("progress-hasqueue") . '">' . $oHtml->getIcon('waiting') . t("progress-hasqueue") . '</div>'; $sErrors = ''; // foreach (array_keys($this->_aPhases) as $sPhase) { foreach (array_keys($oPrj1->getPhases()) as $sPhase) { $sPhaseFilter .= '<option value="' . $sPhase . '" >' . $sPhase . '</option>'; } // #6611 Übersichtsseite nach Project Name sortieren // foreach ($oPrj1->getProjects() as $sPrj) { $oPrj = new projectgui(); $aProjectByLabel = $oPrj->getProjects("label"); foreach ($aProjectByLabel as $aProject) { $sPrj=$aProject['id']; $oPrj = new projectgui($sPrj); $sPrjFilter .= '<option value="' . $sPrj . '">' . $aProject['label'] . '</option>'; $sOutPhases = ''; $sOutPhases2 = ''; $sProgress = ''; // loop over phases ... foreach (array_keys($oPrj->getPhases()) as $sPhase) { $sOutPhases .= $oPrj->renderAllPhaseDetails($sPhase, true, false); if ($oPrj->canAcceptPhase($sPhase)) { // $sOutPhases2.=' <span class="'.$sPhase.'" style="padding: 1em 0.5em 0.5em;">'.$oPrj->renderLink("accept", $sPhase).'</span>'; $sOutPhases2 .= ' ' . $oPrj->renderLink("accept", $sPhase); } } $aProgress = $oPrj->getProgress(); $sPrjGroup = $oPrj->getProjectGroup(); $sPrjGroup = $sPrjGroup ? $sPrjGroup : $sNone; $sClasses = $sPrj . ' ' . $sTrClass . ' trprogress' . ($aProgress['inprogress'] ? ' progressinprogress' : '') . ($aProgress['hasQueue'] ? ' progresshasqueue' : '') . ' group-' . $sPrjGroup; if ($aProgress['inprogress']) { $iInprogress++; $sProgress .= $sDivInprogress; } if ($aProgress['hasQueue']) { $iHasqueue++; $sProgress .= $sDivHasqueue; } if ($sPrjGroup) { $sPrjLabel = $oPrj->getProjectGroupLabel(); $sPrjLabel = $sPrjLabel ? $sPrjLabel : $sNone; if (!isset($aPrjGroups[$sPrjLabel])) { $aPrjGroups[$sPrjLabel] = [ 'id' => $sPrjGroup, 'count' => 1 ]; } else { $aPrjGroups[$sPrjLabel]['count']++; } } $sErrors .= $oPrj->renderErrorBoxes(); /* $sOut2 .= '<div class="' . $sClasses . ' prjbox"><div class="title">' .$oHtml->getLink(array( 'href'=>'#', 'onclick'=>'$(\'#prjfilter\').val(\'' . $sPrj . '\'); window.setTimeout(\'filterOverviewTable();\', 10);setview(\'extended\'); return false;', 'style'=>'float: right;', 'title'=>t("overview-filter-hint"), 'icon'=>'filter', 'label'=>t("overview-filter") )) . '<span class="float-right">'.$sPrjGroup.' </span>' .'<strong>' .$oHtml->getLink(array( 'href'=>'/deployment/' . $sPrj . '/', 'title'=>t("menu-project-home"). ' ' . $oPrj->getLabel(), 'icon'=>'project', 'label'=>'<strong>'.$oPrj->getLabel().'</strong>' )) .'</strong>' // . $sProgress . '</div>' . '<div class="box" ' . 'onclick="location.href=\'/deployment/' . $sPrj . '/\'">' . $oPrj->getDescription() . '<br>' . ''; */ // render output $sOut .= ' <tr class="' . $sClasses . '" ' . 'ondblclick="location.href=\'/deployment/' . $sPrj . '/\'" ' . 'title="' . sprintf(t("overview-hint-dblclick"), $sPrj) . '"> <td class="prj"> <span class="float-right"><i class="fa-solid fa-tag"></i> ' . $sPrjGroup . '</span> <strong>' . $oHtml->getLink(array( 'href' => '/deployment/' . $sPrj . '/', 'title' => $oPrj->getDescription(), 'icon' => 'project', 'label' => $oPrj->getLabel() )) . '</strong>' . '<div class="descr">' . $oPrj->getDescription() . '</div>' . ($sProgress ? '<div class="deployprogress">' . $sProgress . '</div>' : '') // . ' <br>' . '</td>' . '<td class="prj">' . $oHtml->getLinkButton(array( 'href' => '#', 'onclick' => 'setProjectFilter(\'' . $sPrj . '\'); return false;', 'style' => 'float: right', 'title' => t("overview-filter-hint"), 'icon' => 'filter', 'label' => t("overview-filter"), )) . '</td>' . '<td class="prj">'; if ($oPrj->canAcceptPhase()) { $sOut .= $oPrj->renderLink("build"); // $sOut2.=$oPrj->renderLink("build"); // $sOut.='<a href="/deployment/'.$sPrj.'/build/" class="btn btn-default '.$sNext.'"><i class=" icon-forward"></i> Build für ['.$sNext.']</a><br>'; } $sOut .= '</td> ' . $sOutPhases . ' </tr>'; // $sOut2.=$sOutPhases2 . '</div></div>'; } if ($sOut) { $sRowHead1 = ''; $sRowHead2 = ''; $aGrouplist = array_keys($aPrjGroups); sort($aGrouplist); $iNone = isset($aPrjGroups[$sNone]['count']) && $aPrjGroups[$sNone]['count'] ? $aPrjGroups[$sNone]['count'] : 0; $sPrjGroupFilter .= ($iNone ? '<option value="none">' . t("none") . ' (' . $iNone . ')</option>' : '') . '<option value="">-----</option>'; foreach ($aGrouplist as $sLabel) { $sId = $aPrjGroups[$sLabel]['id']; $iCount = $aPrjGroups[$sLabel]['count']; $sPrjGroupFilter .= ($sLabel != $sNone) ? '<option value="' . $sId . '">' . $sLabel . ' (' . $iCount . ')</option>' : ''; } foreach (array_keys($oPrj1->getPhases()) as $sPhase) { // Anzahl colspan ist hartcodiert :-/ $sRowHead1 .= '<th class="' . $sPhase . ' ' . $sColClass . '" colspan="3">' . $oHtml->getIcon('phase') . $sPhase . '</th>'; $sRowHead2 .= $oPrj->renderPlacesAsTd($sPhase); } $sOutTop = ' <script> /** * filter table by chosen select values for project and phase */ function filterOverviewTable(){ // --- reset $(\'.' . $sTrClass . '\').removeClass("trproject-textfilter"); $(\'.' . $sTrClass . '\').removeClass("trproject-progressfilter"); $(\'.' . $sTrClass . '\').removeClass("trproject-projectfilter"); $(\'.' . $sTrClass . '\').removeClass("trproject-projectgroupfilter"); $(\'.' . $sTrClass . '\').removeClass("trprojectfiltered"); $(\'button.prjprogress\').removeClass(\'selected\'); // --- get free filter var sSearch=$("#efilter").val(); localStorage.setItem("efilter", sSearch); $("table").removeHighlight(); if (sSearch) { // $("tr:regex(\'" + sSearch + "\')").show(); // $("tr:not(:regex(\'" + sSearch + "\'))").hide(); // $("tr").first().show(); $("td").highlight(sSearch); } else { $("td").removeHighlight(); $(\'tr\').show(); } var RegexFreetext = new RegExp(sSearch, "i"); // --- get project filter var sPrj=$("#prjfilter").val(); localStorage.setItem("selectedPrj", sPrj); // --- get project group filter var sPrjGroup=$("#prjgroupfilter").val(); localStorage.setItem("selectedPrjGroup", sPrjGroup); // --- get progress filter var sProgress=$("#progressfilter").val(); localStorage.setItem("progress", sProgress); $(\'#btnProgress\'+sProgress).addClass(\'selected\').blur(); // --- loop over project rows $(".trproject").each(function() { if ( !RegexFreetext.exec(this.innerHTML)) { $(this).addClass("trproject-textfilter"); } if (sPrj){ if ($(this).hasClass(sPrj)){ $(this).addClass("trprojectfiltered"); } else { $(this).addClass("trproject-projectfilter"); } } if (sPrjGroup){ if ($(this).hasClass("group-"+sPrjGroup)){ $(this).addClass("trprojectgroupfiltered"); } else { $(this).addClass("trproject-projectgroupfilter"); } } if (sProgress && !$(this).hasClass("progress" + sProgress)){ $(this).addClass("trproject-progressfilter"); } }); showResetbtn(); } /** * onclick event of [filter] button in table row of a project * toggle: show a single project/ all projects */ function setProjectFilter(sPrj){ var sCurrentPrj=$(\'#prjfilter\').val(); if (sCurrentPrj != \'\'){ $(\'#prjfilter\').val(\'\'); } else { $(\'#prjfilter\').val(sPrj); } window.setTimeout(\'filterOverviewTable();\', 10); setview(\'extended\'); } /** * filter table and tiles by filtertext */ function filterTableByTyping(){ filterOverviewTable(); return false; } /** * switch view between tiles and table */ function setview(sMode){ $(\'.view\').hide(); $(\'.view\'+sMode).show(); localStorage.setItem("mode", sMode); return false; } /** * filter table by role */ function setrole(){ var sRole=$("#rolefilter").val(); $(\'.role\').hide(); $(\'.role\'+sRole).show(); localStorage.setItem("role", sRole); showResetbtn(); return false; } /** * filter table by progress status */ function setprogress(){ filterOverviewTable(); return false; } /** * set default view; it gets the last values for filter text, * and selected values in dropdowns and restores the * last view */ function setDefaultView(){ if (localStorage.getItem("progress") && localStorage.getItem("progress")!=\'null\'){ $("#progressfilter").val(localStorage.getItem("progress")); } else { $("#progressfilter").val($("#progressfilter option:first").val()); } if (localStorage.getItem("efilter") && localStorage.getItem("efilter")!=\'null\') { $("#efilter").val(localStorage.getItem("efilter")); window.setTimeout("filterTableByTyping();", 10); } if(localStorage.getItem("selectedPrjGroup") && localStorage.getItem("selectedPrjGroup")!=\'null\'){ $("#prjgroupfilter").val(localStorage.getItem("selectedPrjGroup")); } else { // $("#selectedPrjGroup").val($("#selectedPrjgroup option:first").val()); } // window.setTimeout("filterOverviewTable();", 10); filterOverviewTable(); /* if(localStorage.getItem("selectedPrj") && localStorage.getItem("selectedPrj")!=\'null\'){ $("#prjfilter").val(localStorage.getItem("selectedPrj")); } else { $("#prjfilter").val($("#prjfilter option:first").val()); } if (localStorage.getItem("selectedPhase") && localStorage.getItem("selectedPhase")!=\'null\'){ $("#phasefilter").val(localStorage.getItem("selectedPhase")); } else { $("#phasefilter").val($("#phasefilter option:first").val()); } if (localStorage.getItem("role") && localStorage.getItem("role")!=\'null\') { $("#rolefilter").val(localStorage.getItem("role")); window.setTimeout("setrole();", 20); } if (localStorage.getItem("mode") && localStorage.getItem("mode")!=\'null\') { var sMode=localStorage.getItem("mode"); if (sMode)setview(sMode); } */ } /** * Button zum Filter reset anzeigen/ verbergen */ function showResetbtn(){ var sVisible=$("#efilter").val()?"visible":"hidden"; if ($("#prjfilter").val()>"")sVisible="visible"; if ($("#prjgroupfilter").val()>"")sVisible="visible"; // if ($("#phasefilter").val()!="' . $sColClass . '")sVisible="visible"; if ($("#rolefilter").val())sVisible="visible"; if ($("#progressfilter").val())sVisible="visible"; $("#btnresetfilter").css("visibility", sVisible); $("#btnresetefilter").css("visibility", $("#efilter").val()?"visible":"hidden"); return false; } /** * Aktion des Filter reset: Filter zurücksetzen */ function resetFilter(){ $("#prjfilter").val(""); $("#prjgroupfilter").val(""); // $("#phasefilter").val(""); filterOverviewTable(); $("#efilter").val(""); window.setTimeout("filterTableByTyping();", 10); $("#rolefilter").val(""); window.setTimeout("setrole();", 20); $("#progressfilter").val(""); window.setTimeout("setprogress();", 30); showResetbtn(); return false; } </script> <div class="filterbar"> <form class="form-inline"> <!-- <a href="#" class="view viewextended" onclick="setview(\'simple\');"><i class="glyphicon glyphicon-th-large"></i> ' . t("overview-simpleview") . '</a> <a href="#" class="view viewsimple" onclick="setview(\'extended\');" ><i class="glyphicon glyphicon-th-list"></i> ' . t("overview-extview") . '</a> | --> <label for="efilter"> ' . $oHtml->getIcon('filter') . ' ' . t("overview-textsearch") . ': </label> <input type="text" id="efilter" name="efilter" class="form-control" style="width: 200px;" onchange="filterTableByTyping();" onKeypress="filterTableByTyping(); " onKeyup="filterTableByTyping(); " title="' . t("overview-textsearch-hint") . '" > <button class="btn btn-default" onclick="$(\'#efilter\').val(\'' . $this->oUser->getUsername() . '\'); filterTableByTyping(); return false;"> ' . $oHtml->getIcon('user') . $this->oUser->getUsername() . ' </button> <button id="btnresetefilter" class="btn btn-default" onclick="$(\'#efilter\').val(\'\'); filterTableByTyping(); return false;"> ' . $oHtml->getIcon('close') . ' </button> <span style="display: none;"> <label for="progressfilter"> ' . t("overview-filterprogress") . ': </label> <select id="progressfilter" class="form-control" onchange="setprogress(); return false;"> <option value="">' . t("all") . '</option> <option value="inprogress">' . t("progress-inprogress") . '</option> <option value="hasqueue">' . t("progress-hasqueue") . '</option> </select> </span> <div class="btn-group"> <button id="btnProgress" class="btn btn-default prjprogress" onclick="$(\'#progressfilter\').val(\'\'); return setprogress();" >' . t("overview-projectcount") . '<br><span>' . count($oPrj1->getProjects()) . '</span></button> <button id="btnProgressinprogress" class="btn btn-default prjprogress" onclick="$(\'#progressfilter\').val(\'inprogress\'); return setprogress();" >' . $sDivInprogress . '<span>' . $iInprogress . '</span></button> <button id="btnProgresshasqueue" class="btn btn-default prjprogress" onclick="$(\'#progressfilter\').val(\'hasqueue\'); return setprogress();" >' . $sDivHasqueue . '<span>' . $iHasqueue . '</span></button> </div> <label for="prjgroupfilter"> ' . t("projectgroup") . ': </label> <select id="prjgroupfilter" class="form-control" onchange="filterOverviewTable(); return false;"> ' . $sPrjGroupFilter . ' </select> <span style="display: none;"> <span class="view viewextended"> <label for="prjfilter"> ' . t("overview-filterprj") . ': </label> <select id="prjfilter" class="form-control" onchange="filterOverviewTable(); return false;"> ' . $sPrjFilter . ' </select> <span style="display: none;"> <label for="phasefilter">Phasen:</label> <select id="phasefilter" class="form-control" onchange="filterOverviewTable(); return false;"> ' . $sPhaseFilter . ' </select> </span> </span> </span> <input type="hidden" id="rolefilter" value="" /> <!-- <label for="rolefilter"> ' . t("overview-filterrole") . ': </label> <select id="rolefilter" class="form-control" onchange="setrole(); return false;"> <option value="">' . t("all") . '</option> <option value="developer">' . t("developer") . '</option> <option value="pl">' . t("projectmanager") . '</option> </select> --> <a href="#" class="btn btn-danger" id="btnresetfilter" title="' . t("overview-filterreset-hint") . '" onclick="resetFilter();">' . $oHtml->getIcon('close') . t("overview-filterreset") . '</a> </form> <div style="clear: both; margin-bottom: 1em"></div> </div>'; $sOut = $sErrors /* .' <div class="view viewsimple"> ' . $sOut2 . ' <div style="clear: both;"></div> <br> </div>' */ . ' <table class="table view viewextended" id="tbloverview"> <thead> <tr> <th class="prj" rowspan="2">' . t("project") . '<br><br></th> <th class="prj" rowspan="2"></th> <th class="prj" rowspan="2"></th> ' . $sRowHead1 . ' </tr> <tr> ' . $sRowHead2 . ' </tr> </thead> <tbody> ' . $sOut . '</tbody></table>' . '<script>window.setTimeout("setDefaultView();", 50); window.setTimeout("window.location.replace(window.location.pathname + window.location.search + window.location.hash);", 60000);</script>'; } else { $sOut = t("class-pl-error-no-project") . '<br><br>' . $oPrj1->renderLink("new"); } $sOut = '' . $renderAdminLTE->addRow( $renderAdminLTE->addCol($sOutTop, 12) ) . $renderAdminLTE->addRow( $renderAdminLTE->addCol( $renderAdminLTE->getCard([ 'type' => '', 'variant' => 'outline', 'text' => $sOut, ]), 12 ) ); return $sOut; } }