diff --git a/src/applications/maniphest/controller/tasklist/ManiphestTaskListController.php b/src/applications/maniphest/controller/tasklist/ManiphestTaskListController.php index 9613fb93f2..cc29ad47c7 100644 --- a/src/applications/maniphest/controller/tasklist/ManiphestTaskListController.php +++ b/src/applications/maniphest/controller/tasklist/ManiphestTaskListController.php @@ -1,105 +1,131 @@ <?php /* * Copyright 2011 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ class ManiphestTaskListController extends ManiphestController { private $view; public function willProcessRequest(array $data) { $this->view = idx($data, 'view'); } public function processRequest() { $views = array( + 'Your Tasks', 'action' => 'Action Required', // 'activity' => 'Recently Active', // 'closed' => 'Recently Closed', 'created' => 'Created', 'triage' => 'Need Triage', + '<hr />', + 'All Open Tasks', + 'alltriage' => 'Need Triage', + 'unassigned' => 'Unassigned', + 'allopen' => 'All Open', + ); if (empty($views[$this->view])) { - $this->view = key($views); + $this->view = 'action'; } $tasks = $this->loadTasks(); $nav = new AphrontSideNavView(); foreach ($views as $view => $name) { - $nav->addNavItem( - phutil_render_tag( - 'a', - array( - 'href' => '/maniphest/view/'.$view.'/', - 'class' => ($this->view == $view) - ? 'aphront-side-nav-selected' - : null, - ), - phutil_escape_html($name))); + if (is_integer($view)) { + $nav->addNavItem( + phutil_render_tag( + 'span', + array(), + $name)); + } else { + $nav->addNavItem( + phutil_render_tag( + 'a', + array( + 'href' => '/maniphest/view/'.$view.'/', + 'class' => ($this->view == $view) + ? 'aphront-side-nav-selected' + : null, + ), + phutil_escape_html($name))); + } } $handle_phids = mpull($tasks, 'getOwnerPHID'); $handles = id(new PhabricatorObjectHandleData($handle_phids)) ->loadHandles(); $task_list = new ManiphestTaskListView(); $task_list->setTasks($tasks); $task_list->setHandles($handles); $nav->appendChild( '<div style="text-align: right; padding: 1em 1em 0;">'. '<a href="/maniphest/task/create/" class="green button">'. 'Create New Task'. '</a>'. '</div>'); $nav->appendChild($task_list); return $this->buildStandardPageResponse( $nav, array( 'title' => 'Task List', )); } private function loadTasks() { $request = $this->getRequest(); $user = $request->getUser(); $phids = array($user->getPHID()); switch ($this->view) { case 'action': return id(new ManiphestTask())->loadAllWhere( 'ownerPHID in (%Ls) AND status = 0', $phids); case 'created': return id(new ManiphestTask())->loadAllWhere( 'authorPHID in (%Ls) AND status = 0', $phids); case 'triage': + return id(new ManiphestTask())->loadAllWhere( + 'ownerPHID in (%Ls) and status = %d', + $phids, + ManiphestTaskPriority::PRIORITY_TRIAGE); + case 'alltriage': return id(new ManiphestTask())->loadAllWhere( 'status = %d', ManiphestTaskPriority::PRIORITY_TRIAGE); + case 'unassigned': + return id(new ManiphestTask())->loadAllWhere( + 'ownerPHID IS NULL'); + case 'allopen': + return id(new ManiphestTask())->loadAllWhere( + 'status = 0'); } return array(); } } diff --git a/src/applications/maniphest/editor/transaction/ManiphestTransactionEditor.php b/src/applications/maniphest/editor/transaction/ManiphestTransactionEditor.php index 97bcb9886e..a6a0c8abbd 100644 --- a/src/applications/maniphest/editor/transaction/ManiphestTransactionEditor.php +++ b/src/applications/maniphest/editor/transaction/ManiphestTransactionEditor.php @@ -1,170 +1,169 @@ <?php /* * Copyright 2011 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ class ManiphestTransactionEditor { public function applyTransactions($task, array $transactions) { $email_cc = $task->getCCPHIDs(); $email_to = array(); $email_to[] = $task->getOwnerPHID(); foreach ($transactions as $key => $transaction) { $type = $transaction->getTransactionType(); $new = $transaction->getNewValue(); $email_to[] = $transaction->getAuthorPHID(); switch ($type) { case ManiphestTransactionType::TYPE_NONE: $old = null; break; case ManiphestTransactionType::TYPE_STATUS: $old = $task->getStatus(); break; case ManiphestTransactionType::TYPE_OWNER: $old = $task->getOwnerPHID(); break; case ManiphestTransactionType::TYPE_CCS: $old = $task->getCCPHIDs(); break; case ManiphestTransactionType::TYPE_PRIORITY: $old = $task->getPriority(); break; default: throw new Exception('Unknown action type.'); } if (($old !== null) && ($old == $new)) { if (count($transactions) > 1 && !$transaction->hasComments()) { // If we have at least one other transaction and this one isn't // doing anything and doesn't have any comments, just throw it // away. unset($transactions[$key]); continue; } else { $transaction->setOldValue(null); $transaction->setNewValue(null); $transaction->setTransactionType(ManiphestTransactionType::TYPE_NONE); } } else { switch ($type) { case ManiphestTransactionType::TYPE_NONE: break; case ManiphestTransactionType::TYPE_STATUS: $task->setStatus($new); break; case ManiphestTransactionType::TYPE_OWNER: $task->setOwnerPHID($new); break; case ManiphestTransactionType::TYPE_CCS: $task->setCCPHIDs($new); break; case ManiphestTransactionType::TYPE_PRIORITY: $task->setPriority($new); break; default: throw new Exception('Unknown action type.'); } $transaction->setOldValue($old); $transaction->setNewValue($new); } } $task->save(); foreach ($transactions as $transaction) { $transaction->setTaskID($task->getID()); $transaction->save(); } $email_to[] = $task->getOwnerPHID(); $email_cc = array_merge( $email_cc, $task->getCCPHIDs()); $this->sendEmail($task, $transactions, $email_to, $email_cc); } private function sendEmail($task, $transactions, $email_to, $email_cc) { $email_to = array_filter(array_unique($email_to)); $email_cc = array_filter(array_unique($email_cc)); $phids = array(); foreach ($transactions as $transaction) { foreach ($transaction->extractPHIDs() as $phid) { $phids[$phid] = true; } } $phids = array_keys($phids); $handles = id(new PhabricatorObjectHandleData($phids)) ->loadHandles(); $view = new ManiphestTransactionDetailView(); $view->setTransactionGroup($transactions); $view->setHandles($handles); list($action, $body) = $view->renderForEmail($with_date = false); $is_create = false; foreach ($transactions as $transaction) { $type = $transaction->getTransactionType(); if (($type == ManiphestTransactionType::TYPE_STATUS) && ($transaction->getOldValue() === null) && ($transaction->getNewValue() == ManiphestTaskStatus::STATUS_OPEN)) { $is_create = true; } } $task_uri = PhabricatorEnv::getURI('/T'.$task->getID()); if ($is_create) { $body .= "\n\n". "TASK DESCRIPTION\n". " ".$task->getDescription(); } $body .= "\n\n". "TASK DETAIL\n". " ".$task_uri."\n"; - $base = substr(md5($task->getPHID()), 0, 27).' '.pack("N", time()); $thread_index = base64_encode($base); $message_id = '<maniphest-task-'.$task->getPHID().'>'; id(new PhabricatorMetaMTAMail()) ->setSubject( '[Maniphest] '.$action.': T'.$task->getID().' '.$task->getTitle()) ->setFrom($transaction->getAuthorPHID()) ->addTos($email_to) ->addCCs($email_cc) ->addHeader('Thread-Index', $thread_index) ->addHeader('Thread-Topic', 'Maniphest Task '.$task->getID()) ->addHeader('In-Reply-To', $message_id) ->addHeader('References', $message_id) ->setRelatedPHID($task->getPHID()) ->setBody($body) ->save(); } } diff --git a/webroot/rsrc/css/aphront/side-nav-view.css b/webroot/rsrc/css/aphront/side-nav-view.css index 4ace0af0ee..fd4080e027 100644 --- a/webroot/rsrc/css/aphront/side-nav-view.css +++ b/webroot/rsrc/css/aphront/side-nav-view.css @@ -1,43 +1,44 @@ /** * @provides aphront-side-nav-view-css */ table.aphront-side-nav-view { width: 100%; font-size: 13px; } td.aphront-side-nav-content { width: 100%; } th.aphront-side-nav-navigation { border-right: 1px solid #bbbbbb; } -th.aphront-side-nav-navigation a { +th.aphront-side-nav-navigation a, +th.aphront-side-nav-navigation span { display: block; margin: 0 0 2px; min-width: 150px; padding: 3px 8px 3px 24px; font-weight: bold; white-space: nowrap; text-decoration: none; } th.aphront-side-nav-navigation a:hover { text-decoration: none; background: #f3f3f9; } th.aphront-side-nav-navigation hr { height: 1px; background: #eeeeee; border: 0px; margin: 12px 0px; } th.aphront-side-nav-navigation a.aphront-side-nav-selected, th.aphront-side-nav-navigation a.aphront-side-nav-selected:hover { background: #d8dfea; }