diff --git a/src/applications/differential/view/DifferentialRevisionListView.php b/src/applications/differential/view/DifferentialRevisionListView.php index 74e3f7633f..7ab0f2d183 100644 --- a/src/applications/differential/view/DifferentialRevisionListView.php +++ b/src/applications/differential/view/DifferentialRevisionListView.php @@ -1,186 +1,180 @@ unlandedDependencies = $unlanded_dependencies; return $this; } public function getUnlandedDependencies() { return $this->unlandedDependencies; } public function setNoDataString($no_data_string) { $this->noDataString = $no_data_string; return $this; } public function setHeader($header) { $this->header = $header; return $this; } public function setRevisions(array $revisions) { assert_instances_of($revisions, 'DifferentialRevision'); $this->revisions = $revisions; return $this; } - public function setHighlightAge($bool) { - $this->highlightAge = $bool; - return $this; - } - public function setNoBox($box) { $this->noBox = $box; return $this; } public function setBackground($background) { $this->background = $background; return $this; } public function getRequiredHandlePHIDs() { $phids = array(); foreach ($this->revisions as $revision) { $phids[] = array($revision->getAuthorPHID()); // TODO: Switch to getReviewerStatus(), but not all callers pass us // revisions with this data loaded. $phids[] = $revision->getReviewers(); } return array_mergev($phids); } public function setHandles(array $handles) { assert_instances_of($handles, 'PhabricatorObjectHandle'); $this->handles = $handles; return $this; } public function render() { $viewer = $this->getViewer(); $this->initBehavior('phabricator-tooltips', array()); $this->requireResource('aphront-tooltip-css'); $list = new PHUIObjectItemListView(); foreach ($this->revisions as $revision) { $item = id(new PHUIObjectItemView()) ->setUser($viewer); $icons = array(); $phid = $revision->getPHID(); $flag = $revision->getFlag($viewer); if ($flag) { $flag_class = PhabricatorFlagColor::getCSSClass($flag->getColor()); $icons['flag'] = phutil_tag( 'div', array( 'class' => 'phabricator-flag-icon '.$flag_class, ), ''); } if ($revision->getDrafts($viewer)) { $icons['draft'] = true; } $modified = $revision->getDateModified(); if (isset($icons['flag'])) { $item->addHeadIcon($icons['flag']); } $item->setObjectName('D'.$revision->getID()); $item->setHeader($revision->getTitle()); $item->setHref('/D'.$revision->getID()); if (isset($icons['draft'])) { $draft = id(new PHUIIconView()) ->setIcon('fa-comment yellow') ->addSigil('has-tooltip') ->setMetadata( array( 'tip' => pht('Unsubmitted Comments'), )); $item->addAttribute($draft); } // Author $author_handle = $this->handles[$revision->getAuthorPHID()]; $item->addByline(pht('Author: %s', $author_handle->renderLink())); $unlanded = idx($this->unlandedDependencies, $phid); if ($unlanded) { $item->addAttribute( array( id(new PHUIIconView())->setIcon('fa-chain-broken', 'red'), ' ', pht('Open Dependencies'), )); } $reviewers = array(); // TODO: As above, this should be based on `getReviewerStatus()`. foreach ($revision->getReviewers() as $reviewer) { $reviewers[] = $this->handles[$reviewer]->renderLink(); } if (!$reviewers) { $reviewers = phutil_tag('em', array(), pht('None')); } else { $reviewers = phutil_implode_html(', ', $reviewers); } $item->addAttribute(pht('Reviewers: %s', $reviewers)); $item->setEpoch($revision->getDateModified()); if ($revision->isClosed()) { $item->setDisabled(true); } $item->setStatusIcon( $revision->getStatusIcon(), $revision->getStatusDisplayName()); $list->addItem($item); } $list->setNoDataString($this->noDataString); if ($this->header && !$this->noBox) { $list->setFlush(true); $list = id(new PHUIObjectBoxView()) ->setBackground($this->background) ->setObjectList($list); if ($this->header instanceof PHUIHeaderView) { $list->setHeader($this->header); } else { $list->setHeaderText($this->header); } } else { $list->setHeader($this->header); } return $list; } } diff --git a/src/applications/home/controller/PhabricatorHomeMainController.php b/src/applications/home/controller/PhabricatorHomeMainController.php index 7bc8b06573..592478c894 100644 --- a/src/applications/home/controller/PhabricatorHomeMainController.php +++ b/src/applications/home/controller/PhabricatorHomeMainController.php @@ -1,411 +1,230 @@ getUser(); + $viewer = $request->getViewer(); $dashboard = PhabricatorDashboardInstall::getDashboard( - $user, - $user->getPHID(), + $viewer, + $viewer->getPHID(), get_class($this->getCurrentApplication())); if (!$dashboard) { $dashboard = PhabricatorDashboardInstall::getDashboard( - $user, + $viewer, PhabricatorHomeApplication::DASHBOARD_DEFAULT, get_class($this->getCurrentApplication())); } if ($dashboard) { $content = id(new PhabricatorDashboardRenderingEngine()) - ->setViewer($user) + ->setViewer($viewer) ->setDashboard($dashboard) ->renderDashboard(); } else { - $project_query = new PhabricatorProjectQuery(); - $project_query->setViewer($user); - $project_query->withMemberPHIDs(array($user->getPHID())); - $projects = $project_query->execute(); - - $content = $this->buildMainResponse($projects); + $content = $this->buildMainResponse(); } if (!$request->getURIData('only')) { $nav = $this->buildNav(); $nav->appendChild( array( $content, - id(new PhabricatorGlobalUploadTargetView())->setUser($user), + id(new PhabricatorGlobalUploadTargetView())->setUser($viewer), )); $content = $nav; } return $this->newPage() ->setTitle('Phabricator') ->addClass('phabricator-home') ->appendChild($content); } - private function buildMainResponse(array $projects) { - assert_instances_of($projects, 'PhabricatorProject'); - $viewer = $this->getRequest()->getUser(); + private function buildMainResponse() { + require_celerity_resource('phabricator-dashboard-css'); + $viewer = $this->getViewer(); $has_maniphest = PhabricatorApplication::isClassInstalledForViewer( 'PhabricatorManiphestApplication', $viewer); - $has_audit = PhabricatorApplication::isClassInstalledForViewer( - 'PhabricatorAuditApplication', + $has_diffusion = PhabricatorApplication::isClassInstalledForViewer( + 'PhabricatorDiffusionApplication', $viewer); $has_differential = PhabricatorApplication::isClassInstalledForViewer( 'PhabricatorDifferentialApplication', $viewer); + $revision_panel = null; + if ($has_differential) { + $revision_panel = $this->buildRevisionPanel(); + } + + $tasks_panel = null; if ($has_maniphest) { - $unbreak_panel = $this->buildUnbreakNowPanel(); - $triage_panel = $this->buildNeedsTriagePanel($projects); $tasks_panel = $this->buildTasksPanel(); - } else { - $unbreak_panel = null; - $triage_panel = null; - $tasks_panel = null; } - if ($has_audit) { - $audit_panel = $this->buildAuditPanel(); - $commit_panel = $this->buildCommitPanel(); - } else { - $audit_panel = null; - $commit_panel = null; + $repository_panel = null; + if ($has_diffusion) { + $repository_panel = $this->buildRepositoryPanel(); } - if (PhabricatorEnv::getEnvConfig('welcome.html') !== null) { - $welcome_panel = $this->buildWelcomePanel(); - } else { - $welcome_panel = null; - } + $feed_panel = $this->buildFeedPanel(); - if ($has_differential) { - $revision_panel = $this->buildRevisionPanel(); - } else { - $revision_panel = null; - } + $dashboard = id(new AphrontMultiColumnView()) + ->setFluidlayout(true) + ->setGutter(AphrontMultiColumnView::GUTTER_LARGE); - $home = phutil_tag( + $main_panel = phutil_tag( 'div', array( 'class' => 'homepage-panel', ), array( - $welcome_panel, - $unbreak_panel, - $triage_panel, $revision_panel, $tasks_panel, - $audit_panel, - $commit_panel, - $this->minipanels, + $repository_panel, )); - return $home; - } - - private function buildUnbreakNowPanel() { - $unbreak_now = PhabricatorEnv::getEnvConfig( - 'maniphest.priorities.unbreak-now'); - if (!$unbreak_now) { - return null; - } - - $user = $this->getRequest()->getUser(); - - $task_query = id(new ManiphestTaskQuery()) - ->setViewer($user) - ->withStatuses(ManiphestTaskStatus::getOpenStatusConstants()) - ->withPriorities(array($unbreak_now)) - ->needProjectPHIDs(true) - ->setLimit(10); - - $tasks = $task_query->execute(); - - if (!$tasks) { - return $this->renderMiniPanel( - pht('No "Unbreak Now!" Tasks'), - pht('Nothing appears to be critically broken right now.')); - } - - $href = urisprintf( - '/maniphest/?statuses=open()&priorities=%s#R', - $unbreak_now); - $title = pht('Unbreak Now!'); - $panel = new PHUIObjectBoxView(); - $panel->setHeader($this->renderSectionHeader($title, $href)); - $panel->setObjectList($this->buildTaskListView($tasks)); - - return $panel; - } - - private function buildNeedsTriagePanel(array $projects) { - assert_instances_of($projects, 'PhabricatorProject'); - - $needs_triage = PhabricatorEnv::getEnvConfig( - 'maniphest.priorities.needs-triage'); - if (!$needs_triage) { - return null; - } - - $user = $this->getRequest()->getUser(); - if (!$user->isLoggedIn()) { - return null; - } - - if ($projects) { - $task_query = id(new ManiphestTaskQuery()) - ->setViewer($user) - ->withStatuses(ManiphestTaskStatus::getOpenStatusConstants()) - ->withPriorities(array($needs_triage)) - ->withEdgeLogicPHIDs( - PhabricatorProjectObjectHasProjectEdgeType::EDGECONST, - PhabricatorQueryConstraint::OPERATOR_OR, - mpull($projects, 'getPHID')) - ->needProjectPHIDs(true) - ->setLimit(10); - $tasks = $task_query->execute(); - } else { - $tasks = array(); - } - - if (!$tasks) { - return $this->renderMiniPanel( - pht('No "Needs Triage" Tasks'), - pht('No tasks tagged with projects you are a member of need triage.')); - } - - $title = pht('Needs Triage'); - $href = urisprintf( - '/maniphest/?statuses=open()&priorities=%s&projects=projects(%s)#R', - $needs_triage, - $user->getPHID()); - $panel = new PHUIObjectBoxView(); - $panel->setHeader($this->renderSectionHeader($title, $href)); - $panel->setObjectList($this->buildTaskListView($tasks)); - - return $panel; - } - - private function buildRevisionPanel() { - $viewer = $this->getViewer(); - - $revisions = PhabricatorDifferentialApplication::loadNeedAttentionRevisions( - $viewer); - - if (!$revisions) { - return $this->renderMiniPanel( - pht('No Waiting Revisions'), - pht('No revisions are waiting on you.')); - } - - $title = pht('Revisions Waiting on You'); - $href = '/differential/'; - $panel = new PHUIObjectBoxView(); - $panel->setHeader($this->renderSectionHeader($title, $href)); - - $revision_view = id(new DifferentialRevisionListView()) - ->setHighlightAge(true) - ->setRevisions($revisions) - ->setUser($viewer); - - $phids = array_merge( - array($viewer->getPHID()), - $revision_view->getRequiredHandlePHIDs()); - $handles = $this->loadViewerHandles($phids); + $dashboard->addColumn($main_panel, 'thirds'); - $revision_view->setHandles($handles); - - $list_view = $revision_view->render(); - - $panel->setObjectList($list_view); - - return $panel; - } - - private function buildWelcomePanel() { - $panel = new PHUIObjectBoxView(); - $panel->setHeaderText(pht('Welcome')); - $panel->appendChild( - phutil_safe_html( - PhabricatorEnv::getEnvConfig('welcome.html'))); - - return $panel; - } - - private function buildTasksPanel() { - $user = $this->getRequest()->getUser(); - $user_phid = $user->getPHID(); - - $task_query = id(new ManiphestTaskQuery()) - ->setViewer($user) - ->withStatuses(ManiphestTaskStatus::getOpenStatusConstants()) - ->setGroupBy(ManiphestTaskQuery::GROUP_PRIORITY) - ->withOwners(array($user_phid)) - ->needProjectPHIDs(true) - ->setLimit(10); - - $tasks = $task_query->execute(); - - - if (!$tasks) { - return $this->renderMiniPanel( - pht('No Assigned Tasks'), - pht('You have no assigned tasks.')); - } - - $title = pht('Assigned Tasks'); - $href = '/maniphest/query/assigned/'; - $panel = new PHUIObjectBoxView(); - $panel->setHeader($this->renderSectionHeader($title, $href)); - $panel->setObjectList($this->buildTaskListView($tasks)); - - return $panel; - } - - private function buildTaskListView(array $tasks) { - assert_instances_of($tasks, 'ManiphestTask'); - $user = $this->getRequest()->getUser(); - - $phids = array_merge( - array_filter(mpull($tasks, 'getOwnerPHID')), - array_mergev(mpull($tasks, 'getProjectPHIDs'))); - - $handles = $this->loadViewerHandles($phids); + $side_panel = phutil_tag( + 'div', + array( + 'class' => 'homepage-side-panel', + ), + array( + $feed_panel, + )); + $dashboard->addColumn($side_panel, 'third'); - $view = new ManiphestTaskListView(); - $view->setTasks($tasks); - $view->setUser($user); - $view->setHandles($handles); + $view = id(new PHUIBoxView()) + ->addClass('dashboard-view') + ->appendChild($dashboard); - return $view; + return $view; } - private function renderSectionHeader($title, $href) { + private function buildHomepagePanel($title, $href, $view) { $title = phutil_tag( 'a', array( 'href' => $href, ), $title); + $icon = id(new PHUIIconView()) ->setIcon('fa-search') ->setHref($href); + $header = id(new PHUIHeaderView()) ->setHeader($title) ->addActionItem($icon); - return $header; - } - private function renderMiniPanel($title, $body) { - $panel = new PHUIInfoView(); - $panel->setSeverity(PHUIInfoView::SEVERITY_NODATA); - $panel->appendChild( - phutil_tag( - 'p', - array( - ), - array( - phutil_tag('strong', array(), $title.': '), - $body, - ))); - $this->minipanels[] = $panel; - } + $box = id(new PHUIObjectBoxView()) + ->setHeader($header); - public function buildAuditPanel() { - $request = $this->getRequest(); - $user = $request->getUser(); - - $phids = PhabricatorAuditCommentEditor::loadAuditPHIDsForUser($user); - - $query = id(new DiffusionCommitQuery()) - ->setViewer($user) - ->withNeedsAuditByPHIDs($phids) - ->withAuditStatus(DiffusionCommitQuery::AUDIT_STATUS_OPEN) - ->needAuditRequests(true) - ->needCommitData(true) - ->setLimit(10); + if ($view->getObjectList()) { + $box->setObjectList($view->getObjectList()); + } + if ($view->getContent()) { + $box->appendChild($view->getContent()); + } - $commits = $query->execute(); + return $box; + } - if (!$commits) { - return $this->renderMinipanel( - pht('No Audits'), - pht('No commits are waiting for you to audit them.')); + private function buildRevisionPanel() { + $viewer = $this->getViewer(); + if (!$viewer->isLoggedIn()) { + return null; } - $view = id(new PhabricatorAuditListView()) - ->setCommits($commits) - ->setUser($user); + $engine = new DifferentialRevisionSearchEngine(); + $engine->setViewer($viewer); + $saved = $engine->buildSavedQueryFromBuiltin('active'); + $query = $engine->buildQueryFromSavedQuery($saved); + $pager = $engine->newPagerForSavedQuery($saved); + $pager->setPageSize(15); + $results = $engine->executeQuery($query, $pager); + $view = $engine->renderResults($results, $saved); - $phids = $view->getRequiredHandlePHIDs(); - $handles = $this->loadViewerHandles($phids); - $view->setHandles($handles); + $title = pht('Active Revisions'); + $href = '/differential/query/active/'; - $title = pht('Audits'); - $href = '/audit/'; - $panel = new PHUIObjectBoxView(); - $panel->setHeader($this->renderSectionHeader($title, $href)); - $panel->setObjectList($view); - - return $panel; + return $this->buildHomepagePanel($title, $href, $view); } - public function buildCommitPanel() { - $request = $this->getRequest(); - $user = $request->getUser(); + private function buildTasksPanel() { + $viewer = $this->getViewer(); - $phids = array($user->getPHID()); + $query = 'assigned'; + $title = pht('Assigned Tasks'); + $href = '/maniphest/query/assigned/'; + if (!$viewer->isLoggedIn()) { + $query = 'open'; + $title = pht('Open Tasks'); + $href = '/maniphest/query/open/'; + } + + $engine = new ManiphestTaskSearchEngine(); + $engine->setViewer($viewer); + $saved = $engine->buildSavedQueryFromBuiltin($query); + $query = $engine->buildQueryFromSavedQuery($saved); + $pager = $engine->newPagerForSavedQuery($saved); + $pager->setPageSize(15); + $results = $engine->executeQuery($query, $pager); + $view = $engine->renderResults($results, $saved); + + return $this->buildHomepagePanel($title, $href, $view); + } - $query = id(new DiffusionCommitQuery()) - ->setViewer($user) - ->withAuthorPHIDs($phids) - ->withAuditStatus(DiffusionCommitQuery::AUDIT_STATUS_CONCERN) - ->needCommitData(true) - ->needAuditRequests(true) - ->setLimit(10); + public function buildFeedPanel() { + $viewer = $this->getViewer(); - $commits = $query->execute(); + $engine = new PhabricatorFeedSearchEngine(); + $engine->setViewer($viewer); + $saved = $engine->buildSavedQueryFromBuiltin('all'); + $query = $engine->buildQueryFromSavedQuery($saved); + $pager = $engine->newPagerForSavedQuery($saved); + $pager->setPageSize(40); + $results = $engine->executeQuery($query, $pager); + $view = $engine->renderResults($results, $saved); - if (!$commits) { - return $this->renderMinipanel( - pht('No Problem Commits'), - pht('No one has raised concerns with your commits.')); - } + $title = pht('Recent Activity'); + $href = '/feed/'; - $view = id(new PhabricatorAuditListView()) - ->setCommits($commits) - ->setUser($user); + return $this->buildHomepagePanel($title, $href, $view); + } + + public function buildRepositoryPanel() { + $viewer = $this->getViewer(); - $phids = $view->getRequiredHandlePHIDs(); - $handles = $this->loadViewerHandles($phids); - $view->setHandles($handles); + $engine = new PhabricatorRepositorySearchEngine(); + $engine->setViewer($viewer); + $saved = $engine->buildSavedQueryFromBuiltin('active'); + $query = $engine->buildQueryFromSavedQuery($saved); + $pager = $engine->newPagerForSavedQuery($saved); + $pager->setPageSize(5); + $results = $engine->executeQuery($query, $pager); + $view = $engine->renderResults($results, $saved); - $title = pht('Problem Commits'); - $href = '/audit/'; - $panel = new PHUIObjectBoxView(); - $panel->setHeader($this->renderSectionHeader($title, $href)); - $panel->setObjectList($view); + $title = pht('Active Repositories'); + $href = '/diffusion/'; - return $panel; + return $this->buildHomepagePanel($title, $href, $view); } } diff --git a/src/applications/maniphest/view/ManiphestTaskResultListView.php b/src/applications/maniphest/view/ManiphestTaskResultListView.php index 52f4a3b2d6..9e28e89d8d 100644 --- a/src/applications/maniphest/view/ManiphestTaskResultListView.php +++ b/src/applications/maniphest/view/ManiphestTaskResultListView.php @@ -1,270 +1,271 @@ savedQuery = $query; return $this; } public function setTasks(array $tasks) { $this->tasks = $tasks; return $this; } public function setCanEditPriority($can_edit_priority) { $this->canEditPriority = $can_edit_priority; return $this; } public function setCanBatchEdit($can_batch_edit) { $this->canBatchEdit = $can_batch_edit; return $this; } public function setShowBatchControls($show_batch_controls) { $this->showBatchControls = $show_batch_controls; return $this; } public function render() { $viewer = $this->getUser(); $tasks = $this->tasks; $query = $this->savedQuery; // If we didn't match anything, just pick up the default empty state. if (!$tasks) { return id(new PHUIObjectItemListView()) - ->setUser($viewer); + ->setUser($viewer) + ->setNoDataString(pht('No tasks found.')); } $group_parameter = nonempty($query->getParameter('group'), 'priority'); $order_parameter = nonempty($query->getParameter('order'), 'priority'); $handles = ManiphestTaskListView::loadTaskHandles($viewer, $tasks); $groups = $this->groupTasks( $tasks, $group_parameter, $handles); $can_edit_priority = $this->canEditPriority; $can_drag = ($order_parameter == 'priority') && ($can_edit_priority) && ($group_parameter == 'none' || $group_parameter == 'priority'); if (!$viewer->isLoggedIn()) { // TODO: (T7131) Eventually, we conceivably need to make each task // draggable individually, since the user may be able to edit some but // not others. $can_drag = false; } $result = array(); $lists = array(); foreach ($groups as $group => $list) { $task_list = new ManiphestTaskListView(); $task_list->setShowBatchControls($this->showBatchControls); if ($can_drag) { $task_list->setShowSubpriorityControls(true); } $task_list->setUser($viewer); $task_list->setTasks($list); $task_list->setHandles($handles); $header = id(new PHUIHeaderView()) ->addSigil('task-group') ->setMetadata(array('priority' => head($list)->getPriority())) ->setHeader(pht('%s (%s)', $group, phutil_count($list))); $lists[] = id(new PHUIObjectBoxView()) ->setHeader($header) ->setObjectList($task_list); } if ($can_drag) { Javelin::initBehavior( 'maniphest-subpriority-editor', array( 'uri' => '/maniphest/subpriority/', )); } return array( $lists, $this->showBatchControls ? $this->renderBatchEditor($query) : null, ); } private function groupTasks(array $tasks, $group, array $handles) { assert_instances_of($tasks, 'ManiphestTask'); assert_instances_of($handles, 'PhabricatorObjectHandle'); $groups = $this->getTaskGrouping($tasks, $group); $results = array(); foreach ($groups as $label_key => $tasks) { $label = $this->getTaskLabelName($group, $label_key, $handles); $results[$label][] = $tasks; } foreach ($results as $label => $task_groups) { $results[$label] = array_mergev($task_groups); } return $results; } private function getTaskGrouping(array $tasks, $group) { switch ($group) { case 'priority': return mgroup($tasks, 'getPriority'); case 'status': return mgroup($tasks, 'getStatus'); case 'assigned': return mgroup($tasks, 'getOwnerPHID'); case 'project': return mgroup($tasks, 'getGroupByProjectPHID'); default: return array(pht('Tasks') => $tasks); } } private function getTaskLabelName($group, $label_key, array $handles) { switch ($group) { case 'priority': return ManiphestTaskPriority::getTaskPriorityName($label_key); case 'status': return ManiphestTaskStatus::getTaskStatusFullName($label_key); case 'assigned': if ($label_key) { return $handles[$label_key]->getFullName(); } else { return pht('(Not Assigned)'); } case 'project': if ($label_key) { return $handles[$label_key]->getFullName(); } else { // This may mean "No Projects", or it may mean the query has project // constraints but the task is only in constrained projects (in this // case, we don't show the group because it would always have all // of the tasks). Since distinguishing between these two cases is // messy and the UI is reasonably clear, label generically. return pht('(Ungrouped)'); } default: return pht('Tasks'); } } private function renderBatchEditor(PhabricatorSavedQuery $saved_query) { $user = $this->getUser(); if (!$this->canBatchEdit) { return null; } if (!$user->isLoggedIn()) { // Don't show the batch editor or excel export for logged-out users. // Technically we //could// let them export, but ehh. return null; } Javelin::initBehavior( 'maniphest-batch-selector', array( 'selectAll' => 'batch-select-all', 'selectNone' => 'batch-select-none', 'submit' => 'batch-select-submit', 'status' => 'batch-select-status-cell', 'idContainer' => 'batch-select-id-container', 'formID' => 'batch-select-form', )); $select_all = javelin_tag( 'a', array( 'href' => '#', 'mustcapture' => true, 'class' => 'grey button', 'id' => 'batch-select-all', ), pht('Select All')); $select_none = javelin_tag( 'a', array( 'href' => '#', 'mustcapture' => true, 'class' => 'grey button', 'id' => 'batch-select-none', ), pht('Clear Selection')); $submit = phutil_tag( 'button', array( 'id' => 'batch-select-submit', 'disabled' => 'disabled', 'class' => 'disabled', ), pht("Batch Edit Selected \xC2\xBB")); $export = javelin_tag( 'a', array( 'href' => '/maniphest/export/'.$saved_query->getQueryKey().'/', 'class' => 'grey button', ), pht('Export to Excel')); $hidden = phutil_tag( 'div', array( 'id' => 'batch-select-id-container', ), ''); $editor = hsprintf( ''. ''. ''. ''. ''. ''. ''. '
%s%s%s%s%s%s
', $select_all, $select_none, $export, '', $submit, $hidden); $editor = phabricator_form( $user, array( 'method' => 'POST', 'action' => '/maniphest/batch/', 'id' => 'batch-select-form', ), $editor); $box = id(new PHUIObjectBoxView()) ->setHeaderText(pht('Batch Task Editor')) ->appendChild($editor); $content = phutil_tag_div('maniphest-batch-editor', $box); return $content; } }