TaskFreak Lien projet

De EjnTricks

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.

Hand-icon.png Votre avis

Nobody voted on this yet

 You need to enable JavaScript to vote


Viewer icon.png 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.


Update icon.png Code source

Study icon.png 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.

Study icon.png 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"';
                        }
                    ?>>&nbsp;</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 variabel n'est pas initialisée, l'utilisateur est donc en train d'afficher toutes les tâches.

Icon Personnalisation.png 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"';
                        }
                    ?>>&nbsp;</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.