@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Modernizing Flag Application

Summary:
Fixes a weird string in the flag dialog

Migrated to ObjectItemView (Cards)

Removed filters from side nav (unnecessary)

Go away, go away, panel. Nobody will miss you.

Adding sorting/ordering to Flag (separation like in Maniphest ordering still remaining)

Hacking our way in DifferentialRevisionListController thanks to panels (who added `->setFlush()` btw? It's awesome!)

Test Plan: I would not dare to stand here if it did not work.

Reviewers: epriestley, chad, btrahan

Reviewed By: epriestley

CC: aran, Korvin

Differential Revision: https://secure.phabricator.com/D5449

authored by

Anh Nhan Nguyen and committed by
epriestley
9a6c912e 8fc94b02

+137 -98
+1 -26
src/applications/differential/controller/DifferentialRevisionListController.php
··· 146 146 $handles = $this->loadViewerHandles($phids); 147 147 148 148 foreach ($views as $view) { 149 - if (empty($view['special'])) { 150 - $view['view']->setHandles($handles); 151 - } 149 + $view['view']->setHandles($handles); 152 150 $panel = new AphrontPanelView(); 153 151 $panel->setHeader($view['title']); 154 152 $panel->appendChild($view['view']); ··· 459 457 'title' => pht('Action Required'), 460 458 'view' => $view, 461 459 ); 462 - 463 - // Flags are sort of private, so only show the flag panel if you're 464 - // looking at your own requests. 465 - if (in_array($user->getPHID(), $user_phids)) { 466 - $flags = id(new PhabricatorFlagQuery()) 467 - ->setViewer($user) 468 - ->withOwnerPHIDs(array($user->getPHID())) 469 - ->withTypes(array(PhabricatorPHIDConstants::PHID_TYPE_DREV)) 470 - ->needHandles(true) 471 - ->execute(); 472 - 473 - if ($flags) { 474 - $view = id(new PhabricatorFlagListView()) 475 - ->setFlags($flags) 476 - ->setUser($user); 477 - 478 - $views[] = array( 479 - 'title' => pht('Flagged Revisions'), 480 - 'view' => $view, 481 - 'special' => true, 482 - ); 483 - } 484 - } 485 460 486 461 $view = id(clone $template) 487 462 ->setRevisions($waiting)
+2 -2
src/applications/flag/controller/PhabricatorFlagEditController.php
··· 54 54 $form 55 55 ->appendChild(hsprintf( 56 56 "<p>%s</p><br />", 57 - pht('You can flag this %s if you want to remember to look ". 58 - "at it later.', 57 + pht('You can flag this %s if you want to remember to look '. 58 + 'at it later.', 59 59 $type_name))); 60 60 } 61 61
+44 -10
src/applications/flag/controller/PhabricatorFlagListController.php
··· 7 7 $user = $request->getUser(); 8 8 9 9 $nav = new AphrontSideNavFilterView(); 10 - $nav->setBaseURI(new PhutilURI('/flag/view/')); 11 - $nav->addLabel(pht('Flags')); 12 - $nav->addFilter('all', pht('Your Flags')); 13 - $nav->selectFilter('all', 'all'); 10 + 11 + $filter_form = new AphrontFormView(); 12 + $filter_form->setUser($user); 13 + $filter_form->appendChild( 14 + id(new AphrontFormToggleButtonsControl()) 15 + ->setName('o') 16 + ->setLabel(pht('Sort Order')) 17 + ->setBaseURI($request->getRequestURI(), 'o') 18 + ->setValue($request->getStr('o', 'n')) 19 + ->setButtons( 20 + array( 21 + 'n' => pht('Date'), 22 + 'c' => pht('Color'), 23 + 'o' => pht('Object Type'), 24 + 'r' => pht('Reason'), 25 + ))); 26 + 27 + $filter = new AphrontListFilterView(); 28 + $filter->appendChild($filter_form); 14 29 15 30 $query = new PhabricatorFlagQuery(); 16 31 $query->withOwnerPHIDs(array($user->getPHID())); 17 32 $query->setViewer($user); 18 33 $query->needHandles(true); 19 34 35 + switch ($request->getStr('o', 'n')) { 36 + case 'n': 37 + $order = PhabricatorFlagQuery::ORDER_ID; 38 + break; 39 + case 'c': 40 + $order = PhabricatorFlagQuery::ORDER_COLOR; 41 + break; 42 + case 'o': 43 + $order = PhabricatorFlagQuery::ORDER_OBJECT; 44 + break; 45 + case 'r': 46 + $order = PhabricatorFlagQuery::ORDER_REASON; 47 + break; 48 + default: 49 + throw new Exception("Unknown order!"); 50 + } 51 + $query->withOrder($order); 52 + 20 53 $flags = $query->execute(); 21 54 22 55 $view = new PhabricatorFlagListView(); 23 56 $view->setFlags($flags); 24 57 $view->setUser($user); 25 58 26 - $panel = new AphrontPanelView(); 27 - $panel->setHeader(pht('Flags')); 28 - $panel->appendChild($view); 29 - $panel->setNoBackground(); 59 + $header = new PhabricatorHeaderView(); 60 + $header->setHeader(pht('Flags')); 30 61 31 - $nav->appendChild($panel); 62 + $nav->appendChild($header); 63 + $nav->appendChild($filter); 64 + $nav->appendChild($view); 32 65 33 - return $this->buildStandardPageResponse( 66 + return $this->buildApplicationPage( 34 67 $nav, 35 68 array( 36 69 'title' => pht('Flags'), 70 + 'dust' => true, 37 71 )); 38 72 } 39 73
+34 -1
src/applications/flag/query/PhabricatorFlagQuery.php
··· 13 13 private $needObjects; 14 14 private $viewer; 15 15 16 + private $order = 'order-id'; 17 + const ORDER_ID = 'order-id'; 18 + const ORDER_COLOR = 'order-color'; 19 + const ORDER_OBJECT = 'order-object'; 20 + const ORDER_REASON = 'order-reason'; 21 + 16 22 public function setViewer($viewer) { 17 23 $this->viewer = $viewer; 18 24 return $this; ··· 30 36 31 37 public function withObjectPHIDs(array $object_phids) { 32 38 $this->objectPHIDs = $object_phids; 39 + return $this; 40 + } 41 + 42 + public function withOrder($order) { 43 + $this->order = $order; 33 44 return $this; 34 45 } 35 46 ··· 143 154 } 144 155 145 156 private function buildOrderClause($conn_r) { 146 - return 'ORDER BY id DESC'; 157 + return qsprintf($conn_r, 158 + 'ORDER BY %Q', 159 + $this->getOrderColumn($conn_r)); 160 + } 161 + 162 + private function getOrderColumn($conn_r) { 163 + switch ($this->order) { 164 + case self::ORDER_ID: 165 + return 'id DESC'; 166 + break; 167 + case self::ORDER_COLOR: 168 + return 'color DESC'; 169 + break; 170 + case self::ORDER_OBJECT: 171 + return 'type ASC'; 172 + break; 173 + case self::ORDER_REASON: 174 + return 'reasonPHID DESC'; 175 + break; 176 + default: 177 + throw new Exception("Unknown order {$this->order}!"); 178 + break; 179 + } 147 180 } 148 181 149 182 private function buildLimitClause($conn_r) {
+49 -59
src/applications/flag/view/PhabricatorFlagListView.php
··· 3 3 final class PhabricatorFlagListView extends AphrontView { 4 4 5 5 private $flags; 6 + private $flush = false; 6 7 7 8 public function setFlags(array $flags) { 8 9 assert_instances_of($flags, 'PhabricatorFlag'); ··· 10 11 return $this; 11 12 } 12 13 14 + public function setFlush($flush) { 15 + $this->flush = $flush; 16 + return $this; 17 + } 18 + 13 19 public function render() { 14 20 $user = $this->user; 15 21 16 22 require_celerity_resource('phabricator-flag-css'); 17 23 24 + $list = new PhabricatorObjectItemListView(); 25 + $list->setCards(true); 26 + $list->setNoDataString(pht('No flags.')); 27 + $list->setFlush($this->flush); 28 + 18 29 $rows = array(); 19 30 foreach ($this->flags as $flag) { 20 31 $class = PhabricatorFlagColor::getCSSClass($flag->getColor()); 21 32 22 - $rows[] = array( 23 - phutil_tag( 24 - 'div', 25 - array( 26 - 'class' => 'phabricator-flag-icon '.$class, 27 - ), 28 - ''), 29 - $flag->getHandle()->renderLink(), 30 - $flag->getNote(), 31 - phabricator_datetime($flag->getDateCreated(), $user), 32 - phabricator_form( 33 - $user, 34 - array( 35 - 'method' => 'POST', 36 - 'action' => '/flag/edit/'.$flag->getObjectPHID().'/', 37 - 'sigil' => 'workflow', 38 - ), 39 - phutil_tag( 40 - 'button', 41 - array( 42 - 'class' => 'small grey', 43 - ), 44 - pht('Edit Flag'))), 45 - phabricator_form( 46 - $user, 47 - array( 48 - 'method' => 'POST', 49 - 'action' => '/flag/delete/'.$flag->getID().'/', 50 - 'sigil' => 'workflow', 51 - ), 52 - phutil_tag( 53 - 'button', 54 - array( 55 - 'class' => 'small grey', 56 - ), 57 - pht('Remove Flag'))), 58 - ); 59 - } 33 + $flag_icon = phutil_tag( 34 + 'div', 35 + array( 36 + 'class' => 'phabricator-flag-icon '.$class, 37 + ), 38 + ''); 60 39 61 - $table = new AphrontTableView($rows); 62 - $table->setHeaders( 63 - array( 64 - '', 65 - pht('Flagged Object'), 66 - pht('Note'), 67 - pht('Flagged On'), 68 - '', 69 - '', 70 - )); 71 - $table->setColumnClasses( 72 - array( 73 - 'narrow', 74 - 'wrap pri', 75 - 'wrap', 76 - 'narrow', 77 - 'narrow action', 78 - 'narrow action', 79 - )); 80 - $table->setNoDataString(pht('No flags.')); 40 + $edit_link = javelin_tag( 41 + 'a', 42 + array( 43 + 'href' => '/flag/edit/'.$flag->getObjectPHID().'/', 44 + 'sigil' => 'workflow', 45 + ), 46 + pht('Edit')); 81 47 82 - return $table->render(); 48 + $remove_link = javelin_tag( 49 + 'a', 50 + array( 51 + 'href' => '/flag/delete/'.$flag->getID().'/', 52 + 'sigil' => 'workflow', 53 + ), 54 + pht('Remove')); 55 + 56 + $item = new PhabricatorObjectItemView(); 57 + $item->addIcon('edit', $edit_link); 58 + $item->addIcon('delete', $remove_link); 59 + 60 + $item->setHeader(hsprintf('%s %s', 61 + $flag_icon, $flag->getHandle()->renderLink())); 62 + 63 + $item->addAttribute(phabricator_datetime($flag->getDateCreated(), $user)); 64 + 65 + if ($flag->getNote()) { 66 + $item->addAttribute($flag->getNote()); 67 + } 68 + 69 + $list->addItem($item); 70 + } 71 + 72 + return $list; 83 73 } 84 74 }
+7
webroot/rsrc/css/application/flag/flag.css
··· 7 7 background: transparent 0 0 no-repeat; 8 8 } 9 9 10 + .phabricator-object-item .phabricator-flag-icon { 11 + float: left; 12 + margin: 2px; 13 + margin-right: 8px; 14 + margin-bottom: 0; 15 + } 16 + 10 17 .phabricator-flag-radio { 11 18 padding-left: 18px; 12 19 margin: 1px;