TaskFreak Lien projet
L'application TaskFreak se veut très simple et sans fonctionnalité très évoluées. Elle est parfaite pour une gestion rapide des tâches à réaliser, avec une petite organisation par projet. L'unique moyen d'accéder aux tâches d'un projet spécifique se trouve au niveau du menu. Il est paru utile de pouvoir cliquer sur un lien, dans la liste, pour basculer sur ce projet.
Cet article présente les modifications mises en place pour répondre à ce besoin.
Sommaire
Votre avis
Nobody voted on this yet
|
|
Objectif
La présentation des tâches, sans filtre sur un projet, présente toutes les tâches accessibles à l'utilisateur connecté.
En cliquant sur la ligne, les propriétés de la tâche sont affichées à l'utilisateur. Après plusieurs mois d'utilisation, il a été souhaité de transformer le nom du projet en un lien cliquable. Celui-ci permet de rediriger vers les tâches actives du projet, comme cela pourrait être le cas en cliquant dans le menu. Après modification du code source, la liste des tâches se présente ainsi.
Code source
Génération lien
Comme décrit, le lien doit réaliser la même action qu'en passant par le menu. Donc pour reproduire ce lien hypertexte, il a été nécessaire d'étudier le code source du menu. Celui-ci se trouve dans le fichier include/html/header.php
.
La génération des menus pour chacun des projets s'effectue sur lignes 177 à 190.
<?php
while ($objProj = $objUserProjectList->rNext()) {
$pTmpLink = $objTzn->concatUrl($_SESSION['linkItems'],'sProject='.$objProj->id);
?>
<li class="more"><a href="<?php echo $objTzn->concatUrl($pTmpLink,'show=today'); ?>"><?php $objProj->p('name'); ?></a>
<ul class="level2">
<li><a href="<?php echo $objTzn->concatUrl($pTmpLink,'show=future')?>"><?php echo $langMenu['future_tasks']; ?></a></li>
<li><a href="<?php echo $objTzn->concatUrl($pTmpLink,'show=past')?>"><?php echo $langMenu['past_tasks']; ?></a></li>
<li><a href="<?php echo $objTzn->concatUrl($pTmpLink,'show=all')?>"><?php echo $langMenu['all_tasks']; ?></a></li>
</ul>
</li>
<?php
}
?>
La génération du lien, stocké dans la variable $pTmpLink
, est donc très simple. Elle utilise la variable de session linkItems
, l'identifiant du projet récupéré avec la propriété id
de l'objet objProj
, et un filtre show=future
. Tout cela est concaténé avec la fonction concatUrl
de l'objet objTzn
.
Affichage listing des tâches
Cette présentation est générée par le fichier principal index.php
. Il suffit de repérer la section TASK LIST (CONTENT)
, vers la ligne 270.
<tr id="<?php echo $objItem->id; ?>">
<td id="eprio<?php echo $objItem->id; ?>" class="prio">
<span class="pr<?php echo $priority; ?>" title="<?php echo $_GLOBALS['arrPriorities'][$objItem->priority]; ?>">
<?php echo $priority; ?></span>
</td>
<?php
if (@constant('FRK_CONTEXT_ENABLE')) {
?>
<td id="ectxt<?php echo $objItem->id; ?>" class="<?php echo (@constant('FRK_CONTEXT_LONG'))?'ctlg':'ctsh'; ?>">
<?php echo $objItem->getContext(@constant('FRK_CONTEXT_LONG')); ?>
</td>
<?php
}
?>
<td id="eproj<?php echo $objItem->id; ?>"><?php $objItem->project->p('name','-'); ?></td>
<td id="etitl<?php echo $objItem->id; ?>"><?php
echo $objItem->p('title');
if ($objItem->description) {
echo '<img src="skins/'.FRK_SKIN_FOLDER.'/images/desc.png" width="16" height="16" align="absmiddle" border="0" alt="" />';
}
switch ($objItem->showPrivate) {
case 1:
echo '<img src="skins/'.FRK_SKIN_FOLDER.'/images/priv1.png" width="12" height="16" align="absmiddle" border="0" alt="" />';
break;
case 2:
echo '<img src="skins/'.FRK_SKIN_FOLDER.'/images/priv2.png" width="12" height="16" align="absmiddle" border="0" alt="" />';
break;
}
?></td>
<td id="euser<?php echo $objItem->id; ?>"><?php echo $objItem->member->getShortName('-'); ?></td>
<td id="edead<?php echo $objItem->id; ?>"><?php echo $objItem->pDeadline(); ?></td>
<td><div style="float:right" id="ecomm<?php echo $objItem->id; ?>"><?php echo $objItem->p('itemCommentCount','0'); ?></div>
<a href="javascript:freak_view(<?php echo $objItem->id; ?>,'comm');">
<img src="skins/<?php echo FRK_SKIN_FOLDER; ?>/images/b_disc.png" width="14" height="16" alt="commentaires" border="0" />
</a></td>
<?php
$s = $objItem->itemStatus->statusKey;
for ($i = 0; $i < FRK_STATUS_LEVELS; $i++) {
$j = ($i < $s)?(FRK_STATUS_LEVELS - $i):0;
?>
<td id="est<?php echo ($i+1).$objItem->id; ?>" class="sts<?php echo $j; ?>"<?php
if ($objUser->checkLevel(14) || $objItem->checkRights($objUser->id,8,true)) {
echo ' onclick="freak_sts('.$objItem->id.','.($i+1).')" style="cursor:pointer"';
}
?>> </td>
<?php
}
?>
<td class="act">
<?php
// EDIT
if ($objUser->checkLevel(14) || $objItem->checkRights($objUser->id,7)) {
?><a href="javascript:freak_edit(<?php echo $objItem->id; ?>)" title="<?php echo $GLOBALS['langMessage']['task_edit']; ?>">
<img src="skins/<?php echo FRK_SKIN_FOLDER; ?>/images/b_edit.png" width="20" height="16" alt="edit" border="0" /></a><?php
} else {
?><img src="skins/<?php echo FRK_SKIN_FOLDER; ?>/images/b_edin.png" width="20" height="16" alt="del" border="0" /><?php
}
// DELETE
if ($objUser->checkLevel(14) || $objItem->checkRights($objUser->id,9)) {
?><a href="javascript:freak_del(<?php echo $objItem->id; ?>)" onClick="return confirm('<?php echo $GLOBALS['langMessage']['task_delete_confirm']; ?>')"
title="<?php echo $GLOBALS['langMessage']['task_delete']; ?>">
<img src="skins/<?php echo FRK_SKIN_FOLDER; ?>/images/b_dele.png" width="20" height="16" alt="del" border="0" /></a><?php
} else {
?><img src="skins/<?php echo FRK_SKIN_FOLDER; ?>/images/b_deln.png" width="20" height="16" alt="del" border="0" /><?php
}
?>
</td>
</tr>
Donc le nom du projet est récupéré à partir de l'objet $objItem->project
.
La mise en place des liens n'est pas utile lors que l'utilisateur affiche les tâches d'un projet, puisque le filtre est déjà en place. Les premières lignes de codes du script donnent des indices pour détecter si l'affichage est déjà filtré ou non.
// --- filter: project ---
if ($pProject) {
// load tasks for specific project
$sqlFilter = 'ii.projectId = \''.$pProject.'\'';
$pLink=$objTzn->concatUrl($pLink,'sProject='.$pProject);
} else if (!$objUser->checkLevel(6)) {
// user can only access his own projects
if ($objUserProjectList->rMore()) {
$arrProject = array();
while($objTmp = $objUserProjectList->rNext()) {
$arrProject[] = $objTmp->id;
}
if ($objUser->checkLevel(13)) {
$arrProject[] = '0';
}
$sqlFilter = 'ii.projectId IN ('.implode(',',$arrProject).')';
unset($arrProject);
$objUserProjectList->rReset();
}
}
La variable $pProject
contient donc l'identifiant du projet utilisé comme filtre. Si cette variable n'est pas initialisée, l'utilisateur est donc en train d'afficher toutes les tâches.
Génération lien
Après l'analyse du code original, la mise en place du lien devient aisé. Il faut générer le lien si la variable $pProject
n'est pas initialisée. Dans ce cas, une variable $pTmpLink
est intialisé avec la valeur du lien et le nom du projet est encadré par les balises HTML de lien hypertexte.
Dans un soucis de performance, la valeur de variable session linkItems
est récupérée avant de boucler sur les tâches.
if ($objItemList->rMore()) {
$pLinkItems = $_SESSION['linkItems'];
while ($objItem = $objItemList->rNext()) {
$priority = $objItem->priority;
if (!$pProject) {
$pTmpLink = $objTzn->concatUrl($pLinkItems,'sProject='.$objItem->project->id);
$pTmpLink = $objTzn->concatUrl($pTmpLink,'show=future');
}
?>
<tr id="<?php echo $objItem->id; ?>">
<td id="eprio<?php echo $objItem->id; ?>" class="prio">
<span class="pr<?php echo $priority; ?>" title="<?php echo $_GLOBALS['arrPriorities'][$objItem->priority]; ?>">
<?php echo $priority; ?></span>
</td>
<?php
if (@constant('FRK_CONTEXT_ENABLE')) {
?>
<td id="ectxt<?php echo $objItem->id; ?>" class="<?php echo (@constant('FRK_CONTEXT_LONG'))?'ctlg':'ctsh'; ?>">
<?php echo $objItem->getContext(@constant('FRK_CONTEXT_LONG')); ?>
</td>
<?php
}
?>
<td id="eproj<?php echo $objItem->id; ?>"><?php if (!$pProject) { ?><a href="<?php echo $pTmpLink; ?>"><?php }?>
<?php $objItem->project->p('name','-'); ?></a></td>
<td id="etitl<?php echo $objItem->id; ?>"><?php
echo $objItem->p('title');
if ($objItem->description) {
echo '<img src="skins/'.FRK_SKIN_FOLDER.'/images/desc.png" width="16" height="16" align="absmiddle" border="0" alt="" />';
}
switch ($objItem->showPrivate) {
case 1:
echo '<img src="skins/'.FRK_SKIN_FOLDER.'/images/priv1.png" width="12" height="16" align="absmiddle" border="0" alt="" />';
break;
case 2:
echo '<img src="skins/'.FRK_SKIN_FOLDER.'/images/priv2.png" width="12" height="16" align="absmiddle" border="0" alt="" />';
break;
}
?></td>
<td id="euser<?php echo $objItem->id; ?>"><?php echo $objItem->member->getShortName('-'); ?></td>
<td id="edead<?php echo $objItem->id; ?>"><?php echo $objItem->pDeadline(); ?></td>
<td><div style="float:right" id="ecomm<?php echo $objItem->id; ?>"><?php echo $objItem->p('itemCommentCount','0'); ?></div>
<a href="javascript:freak_view(<?php echo $objItem->id; ?>,'comm');">
<img src="skins/<?php echo FRK_SKIN_FOLDER; ?>/images/b_disc.png" width="14" height="16" alt="commentaires" border="0" />
</a></td>
<?php
$s = $objItem->itemStatus->statusKey;
for ($i = 0; $i < FRK_STATUS_LEVELS; $i++) {
$j = ($i < $s)?(FRK_STATUS_LEVELS - $i):0;
?>
<td id="est<?php echo ($i+1).$objItem->id; ?>" class="sts<?php echo $j; ?>"<?php
if ($objUser->checkLevel(14) || $objItem->checkRights($objUser->id,8,true)) {
echo ' onclick="freak_sts('.$objItem->id.','.($i+1).')" style="cursor:pointer"';
}
?>> </td>
<?php
}
?>
<td class="act">
<?php
// EDIT
if ($objUser->checkLevel(14) || $objItem->checkRights($objUser->id,7)) {
?><a href="javascript:freak_edit(<?php echo $objItem->id; ?>)" title="<?php echo $GLOBALS['langMessage']['task_edit']; ?>">
<img src="skins/<?php echo FRK_SKIN_FOLDER; ?>/images/b_edit.png" width="20" height="16" alt="edit" border="0" /></a><?php
} else {
?><img src="skins/<?php echo FRK_SKIN_FOLDER; ?>/images/b_edin.png" width="20" height="16" alt="del" border="0" /><?php
}
// DELETE
if ($objUser->checkLevel(14) || $objItem->checkRights($objUser->id,9)) {
?><a href="javascript:freak_del(<?php echo $objItem->id; ?>)" onClick="return confirm('<?php echo $GLOBALS['langMessage']['task_delete_confirm']; ?>')"
title="<?php echo $GLOBALS['langMessage']['task_delete']; ?>">
<img src="skins/<?php echo FRK_SKIN_FOLDER; ?>/images/b_dele.png" width="20" height="16" alt="del" border="0" /></a><?php
} else {
?><img src="skins/<?php echo FRK_SKIN_FOLDER; ?>/images/b_deln.png" width="20" height="16" alt="del" border="0" /><?php
}
?>
</td>
</tr>
L' archive contient le fichier index.php
prêt à l'emploi.