public function renderOpenTasks() { $request = $this->getRequest(); $viewer = $request->getUser(); $query = id(new ManiphestTaskQuery())->setViewer($viewer)->withStatuses(ManiphestTaskStatus::getOpenStatusConstants()); switch ($this->view) { case 'project': $query->needProjectPHIDs(true); break; } $project_phid = $request->getStr('project'); $project_handle = null; if ($project_phid) { $phids = array($project_phid); $handles = $this->loadViewerHandles($phids); $project_handle = $handles[$project_phid]; $query->withEdgeLogicPHIDs(PhabricatorProjectObjectHasProjectEdgeType::EDGECONST, PhabricatorQueryConstraint::OPERATOR_OR, $phids); } $tasks = $query->execute(); $recently_closed = $this->loadRecentlyClosedTasks(); $date = phabricator_date(time(), $viewer); switch ($this->view) { case 'user': $result = mgroup($tasks, 'getOwnerPHID'); $leftover = idx($result, '', array()); unset($result['']); $result_closed = mgroup($recently_closed, 'getOwnerPHID'); $leftover_closed = idx($result_closed, '', array()); unset($result_closed['']); $base_link = '/maniphest/?assigned='; $leftover_name = phutil_tag('em', array(), pht('(Up For Grabs)')); $col_header = pht('User'); $header = pht('Open Tasks by User and Priority (%s)', $date); break; case 'project': $result = array(); $leftover = array(); foreach ($tasks as $task) { $phids = $task->getProjectPHIDs(); if ($phids) { foreach ($phids as $project_phid) { $result[$project_phid][] = $task; } } else { $leftover[] = $task; } } $result_closed = array(); $leftover_closed = array(); foreach ($recently_closed as $task) { $phids = $task->getProjectPHIDs(); if ($phids) { foreach ($phids as $project_phid) { $result_closed[$project_phid][] = $task; } } else { $leftover_closed[] = $task; } } $base_link = '/maniphest/?projects='; $leftover_name = phutil_tag('em', array(), pht('(No Project)')); $col_header = pht('Project'); $header = pht('Open Tasks by Project and Priority (%s)', $date); break; } $phids = array_keys($result); $handles = $this->loadViewerHandles($phids); $handles = msort($handles, 'getName'); $order = $request->getStr('order', 'name'); list($order, $reverse) = AphrontTableView::parseSort($order); require_celerity_resource('aphront-tooltip-css'); Javelin::initBehavior('phabricator-tooltips', array()); $rows = array(); $pri_total = array(); foreach (array_merge($handles, array(null)) as $handle) { if ($handle) { if ($project_handle && $project_handle->getPHID() == $handle->getPHID()) { // If filtering by, e.g., "bugs", don't show a "bugs" group. continue; } $tasks = idx($result, $handle->getPHID(), array()); $name = phutil_tag('a', array('href' => $base_link . $handle->getPHID()), $handle->getName()); $closed = idx($result_closed, $handle->getPHID(), array()); } else { $tasks = $leftover; $name = $leftover_name; $closed = $leftover_closed; } $taskv = $tasks; $tasks = mgroup($tasks, 'getPriority'); $row = array(); $row[] = $name; $total = 0; foreach (ManiphestTaskPriority::getTaskPriorityMap() as $pri => $label) { $n = count(idx($tasks, $pri, array())); if ($n == 0) { $row[] = '-'; } else { $row[] = number_format($n); } $total += $n; } $row[] = number_format($total); list($link, $oldest_all) = $this->renderOldest($taskv); $row[] = $link; $normal_or_better = array(); foreach ($taskv as $id => $task) { // TODO: This is sort of a hard-code for the default "normal" status. // When reports are more powerful, this should be made more general. if ($task->getPriority() < 50) { continue; } $normal_or_better[$id] = $task; } list($link, $oldest_pri) = $this->renderOldest($normal_or_better); $row[] = $link; if ($closed) { $task_ids = implode(',', mpull($closed, 'getID')); $row[] = phutil_tag('a', array('href' => '/maniphest/?ids=' . $task_ids, 'target' => '_blank'), number_format(count($closed))); } else { $row[] = '-'; } switch ($order) { case 'total': $row['sort'] = $total; break; case 'oldest-all': $row['sort'] = $oldest_all; break; case 'oldest-pri': $row['sort'] = $oldest_pri; break; case 'closed': $row['sort'] = count($closed); break; case 'name': default: $row['sort'] = $handle ? $handle->getName() : '~'; break; } $rows[] = $row; } $rows = isort($rows, 'sort'); foreach ($rows as $k => $row) { unset($rows[$k]['sort']); } if ($reverse) { $rows = array_reverse($rows); } $cname = array($col_header); $cclass = array('pri right wide'); $pri_map = ManiphestTaskPriority::getShortNameMap(); foreach ($pri_map as $pri => $label) { $cname[] = $label; $cclass[] = 'n'; } $cname[] = pht('Total'); $cclass[] = 'n'; $cname[] = javelin_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => pht('Oldest open task.'), 'size' => 200)), pht('Oldest (All)')); $cclass[] = 'n'; $cname[] = javelin_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => pht('Oldest open task, excluding those with Low or Wishlist priority.'), 'size' => 200)), pht('Oldest (Pri)')); $cclass[] = 'n'; list($ignored, $window_epoch) = $this->getWindow(); $edate = phabricator_datetime($window_epoch, $viewer); $cname[] = javelin_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => pht('Closed after %s', $edate), 'size' => 260)), pht('Recently Closed')); $cclass[] = 'n'; $table = new AphrontTableView($rows); $table->setHeaders($cname); $table->setColumnClasses($cclass); $table->makeSortable($request->getRequestURI(), 'order', $order, $reverse, array('name', null, null, null, null, null, null, 'total', 'oldest-all', 'oldest-pri', 'closed')); $panel = new PHUIObjectBoxView(); $panel->setHeaderText($header); $panel->setTable($table); $tokens = array(); if ($project_handle) { $tokens = array($project_handle); } $filter = $this->renderReportFilters($tokens, $has_window = true); return array($filter, $panel); }
/** * @param string $col_header */ private function buildTableColumns($col_header) { $cname = array($col_header); $cclass = array('pri left narrow'); $pri_map = ManiphestTaskPriority::getShortNameMap(); foreach ($pri_map as $pri => $label) { $cname[] = $label; $cclass[] = 'center narrow'; } $cname[] = 'Total'; $cclass[] = 'center narrow'; $cname[] = javelin_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => pht('Oldest open task.'), 'size' => 200)), pht('Oldest (All)')); $cclass[] = 'center narrow'; $cname[] = javelin_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => pht('Oldest open task, excluding those with Low or ' . 'Wishlist priority.'), 'size' => 200)), pht('Oldest (Pri)')); $cclass[] = 'center narrow'; list($window_epoch) = $this->getWindow($this->request); $edate = phabricator_datetime($window_epoch, $this->user); $cname[] = javelin_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => pht('Closed after %s', $edate), 'size' => 260)), pht('Recently Closed')); $cclass[] = 'center narrow'; return array($cname, $cclass); }