Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/directory/controller/main/PhabricatorDirectoryMainController.php b/src/applications/directory/controller/main/PhabricatorDirectoryMainController.php
index 0fff29b9e6..e2879aab39 100644
--- a/src/applications/directory/controller/main/PhabricatorDirectoryMainController.php
+++ b/src/applications/directory/controller/main/PhabricatorDirectoryMainController.php
@@ -1,659 +1,659 @@
<?php
/*
* Copyright 2012 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.
*/
final class PhabricatorDirectoryMainController
extends PhabricatorDirectoryController {
private $filter;
private $subfilter;
public function willProcessRequest(array $data) {
$this->filter = idx($data, 'filter');
$this->subfilter = idx($data, 'subfilter');
}
public function shouldRequireAdmin() {
// These controllers are admin-only by default, but this one is public,
// so allow non-admin users to view it.
return false;
}
public function processRequest() {
$user = $this->getRequest()->getUser();
$nav = $this->buildNav();
$this->filter = $nav->selectFilter($this->filter, 'home');
switch ($this->filter) {
case 'jump':
break;
case 'home':
case 'feed':
$project_query = new PhabricatorProjectQuery();
$project_query->setMembers(array($user->getPHID()));
$projects = $project_query->execute();
break;
default:
throw new Exception("Unknown filter '{$this->filter}'!");
}
switch ($this->filter) {
case 'feed':
return $this->buildFeedResponse($nav, $projects);
case 'jump':
return $this->buildJumpResponse($nav);
default:
return $this->buildMainResponse($nav, $projects);
}
}
private function buildMainResponse($nav, $projects) {
if (PhabricatorEnv::getEnvConfig('maniphest.enabled')) {
$unbreak_panel = $this->buildUnbreakNowPanel();
$triage_panel = $this->buildNeedsTriagePanel($projects);
$tasks_panel = $this->buildTasksPanel();
} else {
$unbreak_panel = null;
$triage_panel = null;
$tasks_panel = null;
}
$jump_panel = $this->buildJumpPanel();
$revision_panel = $this->buildRevisionPanel();
$app_panel = $this->buildAppPanel();
$audit_panel = $this->buildAuditPanel();
$commit_panel = $this->buildCommitPanel();
$content = array(
$app_panel,
$jump_panel,
$unbreak_panel,
$triage_panel,
$revision_panel,
$tasks_panel,
$audit_panel,
$commit_panel,
);
$nav->appendChild($content);
return $this->buildStandardPageResponse(
$nav,
array(
'title' => 'Phabricator',
));
}
private function buildJumpResponse($nav) {
$request = $this->getRequest();
if ($request->isFormPost()) {
$jump = $request->getStr('jump');
$response = PhabricatorJumpNavHandler::jumpPostResponse($jump);
if ($response) {
return $response;
} else {
$query = new PhabricatorSearchQuery();
$query->setQuery($jump);
$query->save();
return id(new AphrontRedirectResponse())
->setURI('/search/'.$query->getQueryKey().'/');
}
}
$nav->appendChild($this->buildJumpPanel());
return $this->buildStandardPageResponse(
$nav,
array(
'title' => 'Jump Nav',
));
}
private function buildFeedResponse($nav, $projects) {
$subnav = new AphrontSideNavFilterView();
$subnav->setBaseURI(new PhutilURI('/feed/'));
$subnav->addFilter('all', 'All Activity', '/feed/');
$subnav->addFilter('projects', 'My Projects');
$filter = $subnav->selectFilter($this->subfilter, 'all');
switch ($filter) {
case 'all':
$phids = array();
break;
case 'projects':
$phids = mpull($projects, 'getPHID');
break;
}
$view = $this->buildFeedView($phids);
$subnav->appendChild($view);
$nav->appendChild($subnav);
return $this->buildStandardPageResponse(
$nav,
array(
'title' => 'Feed',
));
}
private function buildUnbreakNowPanel() {
$user = $this->getRequest()->getUser();
$user_phid = $user->getPHID();
$task_query = new ManiphestTaskQuery();
$task_query->withStatus(ManiphestTaskQuery::STATUS_OPEN);
$task_query->withPriority(ManiphestTaskPriority::PRIORITY_UNBREAK_NOW);
$task_query->setLimit(10);
$tasks = $task_query->execute();
if (!$tasks) {
return $this->renderMiniPanel(
'No "Unbreak Now!" Tasks',
'Nothing appears to be critically broken right now.');
}
$panel = new AphrontPanelView();
$panel->setHeader('Unbreak Now!');
$panel->setCaption('Open tasks with "Unbreak Now!" priority.');
$panel->addButton(
phutil_render_tag(
'a',
array(
'href' => '/maniphest/view/all/',
'class' => 'grey button',
),
"View All Unbreak Now \xC2\xBB"));
$panel->appendChild($this->buildTaskListView($tasks));
return $panel;
}
private function buildNeedsTriagePanel(array $projects) {
$user = $this->getRequest()->getUser();
$user_phid = $user->getPHID();
if ($projects) {
$task_query = new ManiphestTaskQuery();
$task_query->withStatus(ManiphestTaskQuery::STATUS_OPEN);
$task_query->withPriority(ManiphestTaskPriority::PRIORITY_TRIAGE);
$task_query->withProjects(mpull($projects, 'getPHID'));
$task_query->withAnyProject(true);
$task_query->setLimit(10);
$tasks = $task_query->execute();
} else {
$tasks = array();
}
if (!$tasks) {
return $this->renderMiniPanel(
'No "Needs Triage" Tasks',
'No tasks in <a href="/project/">projects you are a member of</a> '.
'need triage.</p>');
}
$panel = new AphrontPanelView();
$panel->setHeader('Needs Triage');
$panel->setCaption(
'Open tasks with "Needs Triage" priority in '.
'<a href="/project/">projects you are a member of</a>.');
$panel->addButton(
phutil_render_tag(
'a',
array(
// TODO: This should filter to just your projects' need-triage
// tasks?
- 'href' => '/maniphest/view/alltriage/',
+ 'href' => '/maniphest/view/projecttriage/',
'class' => 'grey button',
),
"View All Triage \xC2\xBB"));
$panel->appendChild($this->buildTaskListView($tasks));
return $panel;
}
private function buildRevisionPanel() {
$user = $this->getRequest()->getUser();
$user_phid = $user->getPHID();
$revision_query = new DifferentialRevisionQuery();
$revision_query->withStatus(DifferentialRevisionQuery::STATUS_OPEN);
$revision_query->withResponsibleUsers(array($user_phid));
$revision_query->needRelationships(true);
// NOTE: We need to unlimit this query to hit the responsible user
// fast-path.
$revision_query->setLimit(null);
$revisions = $revision_query->execute();
list($active, $waiting) = DifferentialRevisionQuery::splitResponsible(
$revisions,
$user_phid);
if (!$active) {
return $this->renderMiniPanel(
'No Waiting Revisions',
'No revisions are waiting on you.');
}
$panel = new AphrontPanelView();
$panel->setHeader('Revisions Waiting on You');
$panel->setCaption('Revisions waiting for you for review or commit.');
$panel->addButton(
phutil_render_tag(
'a',
array(
'href' => '/differential/',
'class' => 'button grey',
),
"View Active Revisions \xC2\xBB"));
$fields =
$revision_view = id(new DifferentialRevisionListView())
->setRevisions($active)
->setFields(DifferentialRevisionListView::getDefaultFields())
->setUser($user);
$phids = array_merge(
array($user_phid),
$revision_view->getRequiredHandlePHIDs());
$handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
$revision_view->setHandles($handles);
$panel->appendChild($revision_view);
return $panel;
}
private function buildTasksPanel() {
$user = $this->getRequest()->getUser();
$user_phid = $user->getPHID();
$task_query = new ManiphestTaskQuery();
$task_query->withStatus(ManiphestTaskQuery::STATUS_OPEN);
$task_query->setGroupBy(ManiphestTaskQuery::GROUP_PRIORITY);
$task_query->withOwners(array($user_phid));
$task_query->setLimit(10);
$tasks = $task_query->execute();
if (!$tasks) {
return $this->renderMiniPanel(
'No Assigned Tasks',
'You have no assigned tasks.');
}
$panel = new AphrontPanelView();
$panel->setHeader('Assigned Tasks');
$panel->setCaption('Tasks assigned to you.');
$panel->addButton(
phutil_render_tag(
'a',
array(
'href' => '/maniphest/',
'class' => 'button grey',
),
"View Active Tasks \xC2\xBB"));
$panel->appendChild($this->buildTaskListView($tasks));
return $panel;
}
private function buildTaskListView(array $tasks) {
$user = $this->getRequest()->getUser();
$phids = array_filter(mpull($tasks, 'getOwnerPHID'));
$handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
$view = new ManiphestTaskListView();
$view->setTasks($tasks);
$view->setUser($user);
$view->setHandles($handles);
return $view;
}
private function buildFeedView(array $phids) {
$request = $this->getRequest();
$user = $request->getUser();
$user_phid = $user->getPHID();
$feed_query = new PhabricatorFeedQuery();
if ($phids) {
$feed_query->setFilterPHIDs($phids);
}
// TODO: All this limit stuff should probably be consolidated into the
// feed query?
$old_link = null;
$new_link = null;
$feed_query->setAfter($request->getStr('after'));
$feed_query->setBefore($request->getStr('before'));
$limit = 500;
// Grab one more story than we intend to display so we can figure out
// if we need to render an "Older Posts" link or not (with reasonable
// accuracy, at least).
$feed_query->setLimit($limit + 1);
$feed = $feed_query->execute();
$extra_row = (count($feed) == $limit + 1);
$have_new = ($request->getStr('before')) ||
($request->getStr('after') && $extra_row);
$have_old = ($request->getStr('after')) ||
($request->getStr('before') && $extra_row) ||
(!$request->getStr('before') &&
!$request->getStr('after') &&
$extra_row);
$feed = array_slice($feed, 0, $limit, $preserve_keys = true);
if ($have_old) {
$old_link = phutil_render_tag(
'a',
array(
'href' => '?before='.end($feed)->getChronologicalKey(),
'class' => 'phabricator-feed-older-link',
),
"Older Stories \xC2\xBB");
}
if ($have_new) {
$new_link = phutil_render_tag(
'a',
array(
'href' => '?after='.reset($feed)->getChronologicalKey(),
'class' => 'phabricator-feed-newer-link',
),
"\xC2\xAB Newer Stories");
}
$builder = new PhabricatorFeedBuilder($feed);
$builder->setUser($user);
$feed_view = $builder->buildView();
return
'<div style="padding: 1em 3em;">'.
'<div style="margin: 0 1em;">'.
'<h1 style="font-size: 18px; '.
'border-bottom: 1px solid #aaaaaa; '.
'padding: 0;">Feed</h1>'.
'</div>'.
$feed_view->render().
'<div class="phabricator-feed-frame">'.
$new_link.
$old_link.
'</div>'.
'</div>';
}
private function buildJumpPanel() {
$request = $this->getRequest();
$user = $request->getUser();
$uniq_id = celerity_generate_unique_node_id();
Javelin::initBehavior(
'phabricator-autofocus',
array(
'id' => $uniq_id,
));
require_celerity_resource('phabricator-jump-nav');
$doc_href = PhabricatorEnv::getDocLink('article/Jump_Nav_User_Guide.html');
$doc_link = phutil_render_tag(
'a',
array(
'href' => $doc_href,
),
'Jump Nav User Guide');
$jump_input = phutil_render_tag(
'input',
array(
'type' => 'text',
'class' => 'phabricator-jump-nav',
'name' => 'jump',
'id' => $uniq_id,
));
$jump_caption = phutil_render_tag(
'p',
array(
'class' => 'phabricator-jump-nav-caption',
),
'Enter the name of an object like <tt>D123</tt> to quickly jump to '.
'it. See '.$doc_link.' or type <tt>help</tt>.');
$panel = new AphrontPanelView();
$panel->addClass('aphront-unpadded-panel-view');
$panel->appendChild(
phabricator_render_form(
$user,
array(
'action' => '/jump/',
'method' => 'POST',
'class' => 'phabricator-jump-nav-form',
),
$jump_input.
$jump_caption));
return $panel;
}
private function buildAppPanel() {
require_celerity_resource('phabricator-app-buttons-css');
$nav_buttons = array();
$nav_buttons[] = array(
'Differential',
'/differential/',
'differential');
if (PhabricatorEnv::getEnvConfig('maniphest.enabled')) {
$nav_buttons[] = array(
'Maniphest',
'/maniphest/',
'maniphest');
$nav_buttons[] = array(
'Create Task',
'/maniphest/task/create/',
'create-task');
}
$nav_buttons[] = array(
'Upload File',
'/file/',
'upload-file');
$nav_buttons[] = array(
'Create Paste',
'/paste/',
'create-paste');
if (PhabricatorEnv::getEnvConfig('phriction.enabled')) {
$nav_buttons[] = array(
'Browse Wiki',
'/w/',
'phriction');
}
$nav_buttons[] = array(
'Browse Code',
'/diffusion/',
'diffusion');
$nav_buttons[] = array(
'Audit Code',
'/audit/',
'audit');
$view = new AphrontNullView();
$view->appendChild('<div class="phabricator-app-buttons">');
foreach ($nav_buttons as $info) {
list($name, $uri, $icon) = $info;
$button = phutil_render_tag(
'a',
array(
'href' => $uri,
'class' => 'app-button icon-'.$icon,
),
phutil_render_tag(
'div',
array(
'class' => 'app-icon icon-'.$icon,
),
''));
$caption = phutil_render_tag(
'a',
array(
'href' => $uri,
'class' => 'phabricator-button-caption',
),
phutil_escape_html($name));
$view->appendChild(
'<div class="phabricator-app-button">'.
$button.
$caption.
'</div>');
}
$view->appendChild('<div style="clear: both;"></div></div>');
return $view;
}
private function renderMiniPanel($title, $body) {
$panel = new AphrontMiniPanelView();
$panel->appendChild(
phutil_render_tag(
'p',
array(
),
'<strong>'.$title.':</strong> '.$body));
return $panel;
}
public function buildAuditPanel() {
$request = $this->getRequest();
$user = $request->getUser();
$phids = PhabricatorAuditCommentEditor::loadAuditPHIDsForUser($user);
$query = new PhabricatorAuditQuery();
$query->withAuditorPHIDs($phids);
$query->withStatus(PhabricatorAuditQuery::STATUS_OPEN);
$query->needCommitData(true);
$query->setLimit(10);
$audits = $query->execute();
$commits = $query->getCommits();
if (!$audits) {
return $this->renderMinipanel(
'No Audits',
'No commits are waiting for you to audit them.');
}
$view = new PhabricatorAuditListView();
$view->setAudits($audits);
$view->setCommits($commits);
$phids = $view->getRequiredHandlePHIDs();
$handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
$view->setHandles($handles);
$panel = new AphrontPanelView();
$panel->setHeader('Audits');
$panel->setCaption('Commits awaiting your audit.');
$panel->appendChild($view);
$panel->addButton(
phutil_render_tag(
'a',
array(
'href' => '/audit/',
'class' => 'button grey',
),
"View Active Audits \xC2\xBB"));
return $panel;
}
public function buildCommitPanel() {
$request = $this->getRequest();
$user = $request->getUser();
$phids = array($user->getPHID());
$query = new PhabricatorAuditCommitQuery();
$query->withAuthorPHIDs($phids);
$query->withStatus(PhabricatorAuditQuery::STATUS_OPEN);
$query->needCommitData(true);
$query->setLimit(10);
$commits = $query->execute();
if (!$commits) {
return $this->renderMinipanel(
'No Problem Commits',
'No one has raised concerns with your commits.');
}
$view = new PhabricatorAuditCommitListView();
$view->setCommits($commits);
$view->setUser($user);
$phids = $view->getRequiredHandlePHIDs();
$handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
$view->setHandles($handles);
$panel = new AphrontPanelView();
$panel->setHeader('Problem Commits');
$panel->setCaption('Commits which auditors have raised concerns about.');
$panel->appendChild($view);
$panel->addButton(
phutil_render_tag(
'a',
array(
'href' => '/audit/',
'class' => 'button grey',
),
"View Problem Commits \xC2\xBB"));
return $panel;
}
}
diff --git a/src/applications/maniphest/controller/base/ManiphestController.php b/src/applications/maniphest/controller/base/ManiphestController.php
index 10a6899fb9..3b3a10e0d4 100644
--- a/src/applications/maniphest/controller/base/ManiphestController.php
+++ b/src/applications/maniphest/controller/base/ManiphestController.php
@@ -1,60 +1,64 @@
<?php
/*
* Copyright 2012 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.
*/
/**
* @group maniphest
*/
abstract class ManiphestController extends PhabricatorController {
public function buildStandardPageResponse($view, array $data) {
$page = $this->buildStandardPageView();
$page->setApplicationName('Maniphest');
$page->setBaseURI('/maniphest/');
$page->setTitle(idx($data, 'title'));
$page->setGlyph("\xE2\x9A\x93");
$page->appendChild($view);
$page->setSearchDefaultScope(PhabricatorSearchScope::SCOPE_OPEN_TASKS);
$response = new AphrontWebpageResponse();
return $response->setContent($page->render());
}
protected function buildBaseSideNav() {
$nav = new AphrontSideNavFilterView();
$nav->setBaseURI(new PhutilURI('/maniphest/view/'));
$nav->addLabel('User Tasks');
$nav->addFilter('action', 'Assigned');
$nav->addFilter('created', 'Created');
$nav->addFilter('subscribed', 'Subscribed');
$nav->addFilter('triage', 'Need Triage');
$nav->addSpacer();
+ $nav->addLabel('User Projects');
+ $nav->addFilter('projecttriage','Need Triage');
+ $nav->addFilter('projectall', 'All Tasks');
+ $nav->addSpacer();
$nav->addLabel('All Tasks');
$nav->addFilter('alltriage', 'Need Triage');
$nav->addFilter('all', 'All Tasks');
$nav->addSpacer();
$nav->addLabel('Custom');
$nav->addFilter('custom', 'Custom Query');
$nav->addSpacer();
$nav->addLabel('Reports');
$nav->addFilter('report', 'Reports', '/maniphest/report/');
return $nav;
}
}
diff --git a/src/applications/maniphest/controller/tasklist/ManiphestTaskListController.php b/src/applications/maniphest/controller/tasklist/ManiphestTaskListController.php
index 326c2904c2..b9889fcbd2 100644
--- a/src/applications/maniphest/controller/tasklist/ManiphestTaskListController.php
+++ b/src/applications/maniphest/controller/tasklist/ManiphestTaskListController.php
@@ -1,602 +1,620 @@
<?php
/*
* Copyright 2012 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.
*/
/**
* @group maniphest
*/
final class ManiphestTaskListController extends ManiphestController {
const DEFAULT_PAGE_SIZE = 1000;
private $view;
public function willProcessRequest(array $data) {
$this->view = idx($data, 'view');
}
private function getArrToStrList($key) {
$arr = $this->getRequest()->getArr($key);
$arr = implode(',', $arr);
return nonempty($arr, null);
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
if ($request->isFormPost()) {
// Redirect to GET so URIs can be copy/pasted.
$task_ids = $request->getStr('set_tasks');
$task_ids = nonempty($task_ids, null);
$uri = $request->getRequestURI()
->alter('users', $this->getArrToStrList('set_users'))
->alter('projects', $this->getArrToStrList('set_projects'))
->alter('xprojects', $this->getArrToStrList('set_xprojects'))
->alter('owners', $this->getArrToStrList('set_owners'))
->alter('authors', $this->getArrToStrList('set_authors'))
->alter('tasks', $task_ids);
return id(new AphrontRedirectResponse())->setURI($uri);
}
$nav = $this->buildBaseSideNav();
$this->view = $nav->selectFilter($this->view, 'action');
$has_filter = array(
'action' => true,
'created' => true,
'subscribed' => true,
'triage' => true,
+ 'projecttriage' => true,
+ 'projectall' => true,
);
list($status_map, $status_control) = $this->renderStatusLinks();
list($grouping, $group_control) = $this->renderGroupLinks();
list($order, $order_control) = $this->renderOrderLinks();
$user_phids = $request->getStrList(
'users',
array($user->getPHID()));
- $project_phids = $request->getStrList('projects');
+ if ($this->view == 'projecttriage' || $this->view == 'projectall') {
+ $project_query = new PhabricatorProjectQuery();
+ $project_query->setMembers($user_phids);
+ $projects = $project_query->execute();
+ $project_phids = mpull($projects, 'getPHID');
+ } else {
+ $project_phids = $request->getStrList('projects');
+ }
$exclude_project_phids = $request->getStrList('xprojects');
$task_ids = $request->getStrList('tasks');
$owner_phids = $request->getStrList('owners');
$author_phids = $request->getStrList('authors');
$page = $request->getInt('page');
$page_size = self::DEFAULT_PAGE_SIZE;
$query = new PhabricatorSearchQuery();
$query->setQuery('<<maniphest>>');
$query->setParameters(
array(
'view' => $this->view,
'userPHIDs' => $user_phids,
'projectPHIDs' => $project_phids,
'excludeProjectPHIDs' => $exclude_project_phids,
'ownerPHIDs' => $owner_phids,
'authorPHIDs' => $author_phids,
'taskIDs' => $task_ids,
'group' => $grouping,
'order' => $order,
'offset' => $page,
'limit' => $page_size,
'status' => $status_map,
));
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
$query->save();
unset($unguarded);
list($tasks, $handles, $total_count) = self::loadTasks($query);
$form = id(new AphrontFormView())
->setUser($user)
->setAction($request->getRequestURI());
if (isset($has_filter[$this->view])) {
$tokens = array();
foreach ($user_phids as $phid) {
$tokens[$phid] = $handles[$phid]->getFullName();
}
$form->appendChild(
id(new AphrontFormTokenizerControl())
->setDatasource('/typeahead/common/searchowner/')
->setName('set_users')
->setLabel('Users')
->setValue($tokens));
}
if ($this->view == 'custom') {
$form->appendChild(
id(new AphrontFormTextControl())
->setName('set_tasks')
->setLabel('Task IDs')
->setValue(join(',', $task_ids))
);
$tokens = array();
foreach ($owner_phids as $phid) {
$tokens[$phid] = $handles[$phid]->getFullName();
}
$form->appendChild(
id(new AphrontFormTokenizerControl())
->setDatasource('/typeahead/common/searchowner/')
->setName('set_owners')
->setLabel('Owners')
->setValue($tokens));
$tokens = array();
foreach ($author_phids as $phid) {
$tokens[$phid] = $handles[$phid]->getFullName();
}
$form->appendChild(
id(new AphrontFormTokenizerControl())
->setDatasource('/typeahead/common/users/')
->setName('set_authors')
->setLabel('Authors')
->setValue($tokens));
}
$tokens = array();
foreach ($project_phids as $phid) {
$tokens[$phid] = $handles[$phid]->getFullName();
}
- $form->appendChild(
- id(new AphrontFormTokenizerControl())
- ->setDatasource('/typeahead/common/searchproject/')
- ->setName('set_projects')
- ->setLabel('Projects')
- ->setValue($tokens));
+ if ($this->view != 'projectall' && $this->view != 'projecttriage') {
+ $form->appendChild(
+ id(new AphrontFormTokenizerControl())
+ ->setDatasource('/typeahead/common/searchproject/')
+ ->setName('set_projects')
+ ->setLabel('Projects')
+ ->setValue($tokens));
+ }
if ($this->view == 'custom') {
$tokens = array();
foreach ($exclude_project_phids as $phid) {
$tokens[$phid] = $handles[$phid]->getFullName();
}
$form->appendChild(
id(new AphrontFormTokenizerControl())
->setDatasource('/typeahead/common/projects/')
->setName('set_xprojects')
->setLabel('Exclude Projects')
->setValue($tokens));
}
$form
->appendChild($status_control)
->appendChild($group_control)
->appendChild($order_control);
$form->appendChild(
id(new AphrontFormSubmitControl())
->setValue('Filter Tasks'));
$create_uri = new PhutilURI('/maniphest/task/create/');
if ($project_phids) {
// If we have project filters selected, use them as defaults for task
// creation.
$create_uri->setQueryParam('projects', implode(';', $project_phids));
}
$filter = new AphrontListFilterView();
$filter->addButton(
phutil_render_tag(
'a',
array(
'href' => (string)$create_uri,
'class' => 'green button',
),
'Create New Task'));
$filter->appendChild($form);
$nav->appendChild($filter);
$have_tasks = false;
foreach ($tasks as $group => $list) {
if (count($list)) {
$have_tasks = true;
break;
}
}
require_celerity_resource('maniphest-task-summary-css');
$list_container = new AphrontNullView();
$list_container->appendChild('<div class="maniphest-list-container">');
if (!$have_tasks) {
$list_container->appendChild(
'<h1 class="maniphest-task-group-header">'.
'No matching tasks.'.
'</h1>');
} else {
$pager = new AphrontPagerView();
$pager->setURI($request->getRequestURI(), 'page');
$pager->setPageSize($page_size);
$pager->setOffset($page);
$pager->setCount($total_count);
$cur = ($pager->getOffset() + 1);
$max = min($pager->getOffset() + $page_size, $total_count);
$tot = $total_count;
$cur = number_format($cur);
$max = number_format($max);
$tot = number_format($tot);
$list_container->appendChild(
'<div class="maniphest-total-result-count">'.
"Displaying tasks {$cur} - {$max} of {$tot}.".
'</div>');
$selector = new AphrontNullView();
foreach ($tasks as $group => $list) {
$task_list = new ManiphestTaskListView();
$task_list->setShowBatchControls(true);
$task_list->setUser($user);
$task_list->setTasks($list);
$task_list->setHandles($handles);
$count = number_format(count($list));
$selector->appendChild(
'<h1 class="maniphest-task-group-header">'.
phutil_escape_html($group).' ('.$count.')'.
'</h1>');
$selector->appendChild($task_list);
}
$selector->appendChild($this->renderBatchEditor($query));
$selector = phabricator_render_form(
$user,
array(
'method' => 'POST',
'action' => '/maniphest/batch/',
),
$selector->render());
$list_container->appendChild($selector);
$list_container->appendChild($pager);
}
$list_container->appendChild('</div>');
$nav->appendChild($list_container);
return $this->buildStandardPageResponse(
$nav,
array(
'title' => 'Task List',
));
}
public static function loadTasks(PhabricatorSearchQuery $search_query) {
$user_phids = $search_query->getParameter('userPHIDs', array());
$project_phids = $search_query->getParameter('projectPHIDs', array());
$task_ids = $search_query->getParameter('taskIDs', array());
$xproject_phids = $search_query->getParameter(
'excludeProjectPHIDs',
array());
$owner_phids = $search_query->getParameter('ownerPHIDs', array());
$author_phids = $search_query->getParameter('authorPHIDs', array());
$query = new ManiphestTaskQuery();
$query->withProjects($project_phids);
$query->withTaskIDs($task_ids);
if ($xproject_phids) {
$query->withoutProjects($xproject_phids);
}
if ($owner_phids) {
$query->withOwners($owner_phids);
}
if ($author_phids) {
$query->withAuthors($author_phids);
}
$status = $search_query->getParameter('status', 'all');
if (!empty($status['open']) && !empty($status['closed'])) {
$query->withStatus(ManiphestTaskQuery::STATUS_ANY);
} else if (!empty($status['open'])) {
$query->withStatus(ManiphestTaskQuery::STATUS_OPEN);
} else {
$query->withStatus(ManiphestTaskQuery::STATUS_CLOSED);
}
switch ($search_query->getParameter('view')) {
case 'action':
$query->withOwners($user_phids);
break;
case 'created':
$query->withAuthors($user_phids);
break;
case 'subscribed':
$query->withSubscribers($user_phids);
break;
case 'triage':
$query->withOwners($user_phids);
$query->withPriority(ManiphestTaskPriority::PRIORITY_TRIAGE);
break;
case 'alltriage':
$query->withPriority(ManiphestTaskPriority::PRIORITY_TRIAGE);
break;
case 'all':
break;
+ case 'projecttriage':
+ $query->withPriority(ManiphestTaskPriority::PRIORITY_TRIAGE);
+ $query->withAnyProject(true);
+ break;
+ case 'projectall':
+ $query->withAnyProject(true);
+ break;
}
$order_map = array(
'priority' => ManiphestTaskQuery::ORDER_PRIORITY,
'created' => ManiphestTaskQuery::ORDER_CREATED,
);
$query->setOrderBy(
idx(
$order_map,
$search_query->getParameter('order'),
ManiphestTaskQuery::ORDER_MODIFIED));
$group_map = array(
'priority' => ManiphestTaskQuery::GROUP_PRIORITY,
'owner' => ManiphestTaskQuery::GROUP_OWNER,
'status' => ManiphestTaskQuery::GROUP_STATUS,
);
$query->setGroupBy(
idx(
$group_map,
$search_query->getParameter('group'),
ManiphestTaskQuery::GROUP_NONE));
$query->setCalculateRows(true);
$query->setLimit($search_query->getParameter('limit'));
$query->setOffset($search_query->getParameter('offset'));
$data = $query->execute();
$total_row_count = $query->getRowCount();
$handle_phids = mpull($data, 'getOwnerPHID');
$handle_phids = array_merge(
$handle_phids,
$project_phids,
$user_phids,
$xproject_phids,
$owner_phids,
$author_phids);
$handles = id(new PhabricatorObjectHandleData($handle_phids))
->loadHandles();
switch ($search_query->getParameter('group')) {
case 'priority':
$data = mgroup($data, 'getPriority');
krsort($data);
// If we have invalid priorities, they'll all map to "???". Merge
// arrays to prevent them from overwriting each other.
$out = array();
foreach ($data as $pri => $tasks) {
$out[ManiphestTaskPriority::getTaskPriorityName($pri)][] = $tasks;
}
foreach ($out as $pri => $tasks) {
$out[$pri] = array_mergev($tasks);
}
$data = $out;
break;
case 'status':
$data = mgroup($data, 'getStatus');
ksort($data);
$out = array();
foreach ($data as $status => $tasks) {
$out[ManiphestTaskStatus::getTaskStatusFullName($status)] = $tasks;
}
$data = $out;
break;
case 'owner':
$data = mgroup($data, 'getOwnerPHID');
$out = array();
foreach ($data as $phid => $tasks) {
if ($phid) {
$out[$handles[$phid]->getFullName()] = $tasks;
} else {
$out['Unassigned'] = $tasks;
}
}
if (isset($out['Unassigned'])) {
// If any tasks are unassigned, move them to the front of the list.
$data = array('Unassigned' => $out['Unassigned']) + $out;
} else {
$data = $out;
}
ksort($data);
break;
default:
$data = array(
'Tasks' => $data,
);
break;
}
return array($data, $handles, $total_row_count);
}
public function renderStatusLinks() {
$request = $this->getRequest();
$statuses = array(
'o' => array('open' => true),
'c' => array('closed' => true),
'oc' => array('open' => true, 'closed' => true),
);
$status = $request->getStr('s');
if (empty($statuses[$status])) {
$status = 'o';
}
$status_control = id(new AphrontFormToggleButtonsControl())
->setLabel('Status')
->setValue($status)
->setBaseURI($request->getRequestURI(), 's')
->setButtons(
array(
'o' => 'Open',
'c' => 'Closed',
'oc' => 'All',
));
return array($statuses[$status], $status_control);
}
public function renderOrderLinks() {
$request = $this->getRequest();
$order = $request->getStr('o');
$orders = array(
'u' => 'updated',
'c' => 'created',
'p' => 'priority',
);
if (empty($orders[$order])) {
$order = 'p';
}
$order_by = $orders[$order];
$order_control = id(new AphrontFormToggleButtonsControl())
->setLabel('Order')
->setValue($order)
->setBaseURI($request->getRequestURI(), 'o')
->setButtons(
array(
'p' => 'Priority',
'u' => 'Updated',
'c' => 'Created',
));
return array($order_by, $order_control);
}
public function renderGroupLinks() {
$request = $this->getRequest();
$group = $request->getStr('g');
$groups = array(
'n' => 'none',
'p' => 'priority',
's' => 'status',
'o' => 'owner',
);
if (empty($groups[$group])) {
$group = 'p';
}
$group_by = $groups[$group];
$group_control = id(new AphrontFormToggleButtonsControl())
->setLabel('Group')
->setValue($group)
->setBaseURI($request->getRequestURI(), 'g')
->setButtons(
array(
'p' => 'Priority',
'o' => 'Owner',
's' => 'Status',
'n' => 'None',
));
return array($group_by, $group_control);
}
private function renderBatchEditor(PhabricatorSearchQuery $search_query) {
Javelin::initBehavior(
'maniphest-batch-selector',
array(
'selectAll' => 'batch-select-all',
'selectNone' => 'batch-select-none',
'submit' => 'batch-select-submit',
'status' => 'batch-select-status-cell',
));
$select_all = javelin_render_tag(
'a',
array(
'href' => '#',
'mustcapture' => true,
'class' => 'grey button',
'id' => 'batch-select-all',
),
'Select All');
$select_none = javelin_render_tag(
'a',
array(
'href' => '#',
'mustcapture' => true,
'class' => 'grey button',
'id' => 'batch-select-none',
),
'Clear Selection');
$submit = phutil_render_tag(
'button',
array(
'id' => 'batch-select-submit',
'disabled' => 'disabled',
'class' => 'disabled',
),
'Batch Edit Selected Tasks &raquo;');
$export = javelin_render_tag(
'a',
array(
'href' => '/maniphest/export/'.$search_query->getQueryKey().'/',
'class' => 'grey button',
),
'Export Tasks to Excel...');
return
'<div class="maniphest-batch-editor">'.
'<div class="batch-editor-header">Batch Task Editor</div>'.
'<table class="maniphest-batch-editor-layout">'.
'<tr>'.
'<td>'.
$select_all.
$select_none.
'</td>'.
'<td>'.
$export.
'</td>'.
'<td id="batch-select-status-cell">'.
'0 Selected Tasks'.
'</td>'.
'<td class="batch-select-submit-cell">'.$submit.'</td>'.
'</tr>'.
'</table>'.
'</table>';
}
}
diff --git a/src/applications/maniphest/controller/tasklist/__init__.php b/src/applications/maniphest/controller/tasklist/__init__.php
index 5a0301fb21..5e1f9e3e09 100644
--- a/src/applications/maniphest/controller/tasklist/__init__.php
+++ b/src/applications/maniphest/controller/tasklist/__init__.php
@@ -1,35 +1,36 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/redirect');
phutil_require_module('phabricator', 'aphront/writeguard');
phutil_require_module('phabricator', 'applications/maniphest/constants/priority');
phutil_require_module('phabricator', 'applications/maniphest/constants/status');
phutil_require_module('phabricator', 'applications/maniphest/controller/base');
phutil_require_module('phabricator', 'applications/maniphest/query');
phutil_require_module('phabricator', 'applications/maniphest/view/tasklist');
phutil_require_module('phabricator', 'applications/phid/handle/data');
+phutil_require_module('phabricator', 'applications/project/query/project');
phutil_require_module('phabricator', 'applications/search/storage/query');
phutil_require_module('phabricator', 'infrastructure/celerity/api');
phutil_require_module('phabricator', 'infrastructure/javelin/api');
phutil_require_module('phabricator', 'infrastructure/javelin/markup');
phutil_require_module('phabricator', 'view/control/pager');
phutil_require_module('phabricator', 'view/form/base');
phutil_require_module('phabricator', 'view/form/control/submit');
phutil_require_module('phabricator', 'view/form/control/text');
phutil_require_module('phabricator', 'view/form/control/togglebuttons');
phutil_require_module('phabricator', 'view/form/control/tokenizer');
phutil_require_module('phabricator', 'view/layout/listfilter');
phutil_require_module('phabricator', 'view/null');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'parser/uri');
phutil_require_module('phutil', 'utils');
phutil_require_source('ManiphestTaskListController.php');

File Metadata

Mime Type
text/x-diff
Expires
Thu, Jul 24, 10:41 AM (22 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
182701
Default Alt Text
(41 KB)

Event Timeline