Select Git revision
project.class.php
projectlist.class.php 27.56 KiB
<?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;
}
}