@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.

Moderize Pholio UI

Summary: Cleans up Pholio, moves to two column layout, fix some transaction inconsistencies. This moves "Image" to the MainColumn, which feels fine, but I think we'll likely want some sort of "fullscreen" option for Pholio V2 like we have on workboards perhaps.

Test Plan:
New Mock, Edit Mock, View Mock.

{F1200450}

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin

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

+115 -79
+14 -10
src/applications/pholio/controller/PholioMockEditController.php
··· 22 22 return new Aphront404Response(); 23 23 } 24 24 25 - $title = pht('Edit Mock'); 25 + $title = pht('Edit Mock: %s', $mock->getName()); 26 + $header_icon = 'fa-pencil'; 26 27 27 28 $is_new = false; 28 29 $mock_images = $mock->getImages(); ··· 32 33 $mock = PholioMock::initializeNewMock($viewer); 33 34 34 35 $title = pht('Create Mock'); 36 + $header_icon = 'fa-plus-square'; 35 37 36 38 $is_new = true; 37 39 $files = array(); ··· 350 352 ->appendChild($submit); 351 353 352 354 $form_box = id(new PHUIObjectBoxView()) 353 - ->setHeaderText($title) 355 + ->setHeaderText(pht('Mock')) 354 356 ->setFormErrors($errors) 357 + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 355 358 ->setForm($form); 356 359 357 360 $crumbs = $this->buildApplicationCrumbs(); ··· 359 362 $crumbs->addTextCrumb($mock->getMonogram(), '/'.$mock->getMonogram()); 360 363 } 361 364 $crumbs->addTextCrumb($title); 365 + $crumbs->setBorder(true); 362 366 363 - $content = array( 364 - $crumbs, 365 - $form_box, 366 - ); 367 + $header = id(new PHUIHeaderView()) 368 + ->setHeader($title) 369 + ->setHeaderIcon($header_icon); 370 + 371 + $view = id(new PHUITwoColumnView()) 372 + ->setHeader($header) 373 + ->setFooter($form_box); 367 374 368 375 return $this->newPage() 369 376 ->setTitle($title) 370 377 ->setCrumbs($crumbs) 371 378 ->addQuicksandConfig( 372 379 array('mockEditConfig' => true)) 373 - ->appendChild( 374 - array( 375 - $form_box, 376 - )); 380 + ->appendChild($view); 377 381 } 378 382 379 383 }
+63 -52
src/applications/pholio/controller/PholioMockViewController.php
··· 57 57 ->setHeader($title) 58 58 ->setUser($viewer) 59 59 ->setStatus($header_icon, $header_color, $header_name) 60 - ->setPolicyObject($mock); 60 + ->setPolicyObject($mock) 61 + ->setHeaderIcon('fa-camera-retro'); 61 62 62 63 $timeline = $this->buildTransactionTimeline( 63 64 $mock, ··· 65 66 $engine); 66 67 $timeline->setMock($mock); 67 68 68 - $actions = $this->buildActionView($mock); 69 - $properties = $this->buildPropertyView($mock, $engine, $actions); 69 + $curtain = $this->buildCurtainView($mock); 70 + $details = $this->buildDescriptionView($mock, $engine); 70 71 71 72 require_celerity_resource('pholio-css'); 72 73 require_celerity_resource('pholio-inline-comments-css'); ··· 80 81 ->setImageID($image_id); 81 82 82 83 $output = id(new PHUIObjectBoxView()) 83 - ->setHeaderText(pht('Image')) 84 + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 84 85 ->appendChild($mock_view); 85 86 86 87 $add_comment = $this->buildAddCommentView($mock, $comment_form_id); 87 88 88 89 $crumbs = $this->buildApplicationCrumbs(); 89 90 $crumbs->addTextCrumb('M'.$mock->getID(), '/M'.$mock->getID()); 90 - 91 - $object_box = id(new PHUIObjectBoxView()) 92 - ->setHeader($header) 93 - ->addPropertyList($properties); 91 + $crumbs->setBorder(true); 94 92 95 93 $thumb_grid = id(new PholioMockThumbGridView()) 96 94 ->setUser($viewer) 97 95 ->setMock($mock); 98 96 97 + $view = id(new PHUITwoColumnView()) 98 + ->setHeader($header) 99 + ->setCurtain($curtain) 100 + ->setMainColumn(array( 101 + $output, 102 + $thumb_grid, 103 + $details, 104 + $timeline, 105 + $add_comment, 106 + )); 107 + 99 108 return $this->newPage() 100 109 ->setTitle('M'.$mock->getID().' '.$title) 101 110 ->setCrumbs($crumbs) 102 111 ->setPageObjectPHIDs(array($mock->getPHID())) 103 112 ->addQuicksandConfig( 104 113 array('mockViewConfig' => $mock_view->getBehaviorConfig())) 105 - ->appendChild( 106 - array( 107 - $object_box, 108 - $output, 109 - $thumb_grid, 110 - $timeline, 111 - $add_comment, 112 - )); 114 + ->appendChild($view); 113 115 } 114 116 115 - private function buildActionView(PholioMock $mock) { 117 + private function buildCurtainView(PholioMock $mock) { 116 118 $viewer = $this->getViewer(); 117 119 118 - $actions = id(new PhabricatorActionListView()) 119 - ->setUser($viewer) 120 - ->setObject($mock); 120 + $curtain = $this->newCurtainView($mock); 121 121 122 122 $can_edit = PhabricatorPolicyFilter::hasCapability( 123 123 $viewer, 124 124 $mock, 125 125 PhabricatorPolicyCapability::CAN_EDIT); 126 126 127 - $actions->addAction( 127 + $curtain->addAction( 128 128 id(new PhabricatorActionView()) 129 129 ->setIcon('fa-pencil') 130 130 ->setName(pht('Edit Mock')) ··· 133 133 ->setWorkflow(!$can_edit)); 134 134 135 135 if ($mock->isClosed()) { 136 - $actions->addAction( 136 + $curtain->addAction( 137 137 id(new PhabricatorActionView()) 138 138 ->setIcon('fa-check') 139 139 ->setName(pht('Open Mock')) ··· 141 141 ->setDisabled(!$can_edit) 142 142 ->setWorkflow(true)); 143 143 } else { 144 - $actions->addAction( 144 + $curtain->addAction( 145 145 id(new PhabricatorActionView()) 146 146 ->setIcon('fa-ban') 147 147 ->setName(pht('Close Mock')) ··· 150 150 ->setWorkflow(true)); 151 151 } 152 152 153 - $actions->addAction( 153 + $curtain->addAction( 154 154 id(new PhabricatorActionView()) 155 155 ->setIcon('fa-anchor') 156 156 ->setName(pht('Edit Maniphest Tasks')) ··· 158 158 ->setDisabled(!$viewer->isLoggedIn()) 159 159 ->setWorkflow(true)); 160 160 161 - return $actions; 161 + if ($this->getManiphestTaskPHIDs()) { 162 + $curtain->newPanel() 163 + ->setHeaderText(pht('Maniphest Tasks')) 164 + ->appendChild( 165 + $viewer->renderHandleList($this->getManiphestTaskPHIDs())); 166 + } 167 + 168 + $curtain->newPanel() 169 + ->setHeaderText(pht('Authored By')) 170 + ->appendChild($this->buildAuthorPanel($mock)); 171 + 172 + return $curtain; 162 173 } 163 174 164 - private function buildPropertyView( 165 - PholioMock $mock, 166 - PhabricatorMarkupEngine $engine, 167 - PhabricatorActionListView $actions) { 175 + private function buildDescriptionView(PholioMock $mock) { 168 176 169 177 $viewer = $this->getViewer(); 170 - 171 178 $properties = id(new PHUIPropertyListView()) 172 - ->setUser($viewer) 173 - ->setObject($mock) 174 - ->setActionList($actions); 179 + ->setUser($viewer); 180 + $description = $mock->getDescription(); 175 181 176 - $properties->addProperty( 177 - pht('Author'), 178 - $viewer->renderHandle($mock->getAuthorPHID())); 182 + if (strlen($description)) { 183 + $properties->addImageContent($description); 184 + return id(new PHUIObjectBoxView()) 185 + ->setHeaderText(pht('Mock Description')) 186 + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 187 + ->appendChild($properties); 188 + } 179 189 180 - $properties->addProperty( 181 - pht('Created'), 182 - phabricator_datetime($mock->getDateCreated(), $viewer)); 190 + return null; 191 + } 183 192 184 - if ($this->getManiphestTaskPHIDs()) { 185 - $properties->addProperty( 186 - pht('Maniphest Tasks'), 187 - $viewer->renderHandleList($this->getManiphestTaskPHIDs())); 188 - } 189 - 190 - $properties->invokeWillRenderEvent(); 193 + private function buildAuthorPanel(PholioMock $mock) { 194 + $viewer = $this->getViewer(); 195 + $author_phid = $mock->getAuthorPHID(); 196 + $handles = $viewer->loadHandles(array($author_phid)); 191 197 192 - $properties->addSectionHeader( 193 - pht('Description'), 194 - PHUIPropertyListView::ICON_SUMMARY); 198 + $author_uri = $handles[$author_phid]->getImageURI(); 199 + $author_href = $handles[$author_phid]->getURI(); 200 + $author = $viewer->renderHandle($author_phid)->render(); 195 201 196 - $properties->addImageContent( 197 - $engine->getOutput($mock, PholioMock::MARKUP_FIELD_DESCRIPTION)); 202 + $content = phutil_tag('strong', array(), $author); 203 + $date = phabricator_date($mock->getDateCreated(), $viewer); 204 + $content = pht('%s, %s', $content, $date); 205 + $authored_by = id(new PHUIHeadThingView()) 206 + ->setImage($author_uri) 207 + ->setImageHref($author_href) 208 + ->setContent($content); 198 209 199 - return $properties; 210 + return $authored_by; 200 211 } 201 212 202 213 private function buildAddCommentView(PholioMock $mock, $comment_form_id) {
+2 -4
src/applications/pholio/storage/PholioMock.php
··· 227 227 228 228 public function getMarkupText($field) { 229 229 if ($this->getDescription()) { 230 - $description = $this->getDescription(); 231 - } else { 232 - $description = pht('No Description Given'); 230 + return $this->getDescription(); 233 231 } 234 232 235 - return $description; 233 + return null; 236 234 } 237 235 238 236 public function didMarkupText($field, $output, PhutilMarkupEngine $engine) {
+35 -13
src/applications/pholio/storage/PholioTransaction.php
··· 81 81 } 82 82 83 83 public function getIcon() { 84 + 85 + $new = $this->getNewValue(); 86 + $old = $this->getOldValue(); 87 + 84 88 switch ($this->getTransactionType()) { 85 89 case self::TYPE_INLINE: 86 90 return 'fa-comment'; 87 91 case self::TYPE_NAME: 88 92 case self::TYPE_DESCRIPTION: 89 93 case self::TYPE_STATUS: 94 + if ($new == PholioMock::STATUS_CLOSED) { 95 + return 'fa-ban'; 96 + } else { 97 + return 'fa-check'; 98 + } 90 99 case self::TYPE_IMAGE_NAME: 91 100 case self::TYPE_IMAGE_DESCRIPTION: 92 101 case self::TYPE_IMAGE_SEQUENCE: ··· 153 162 $this->renderHandleLink($author_phid)); 154 163 break; 155 164 case self::TYPE_STATUS: 156 - return pht( 157 - "%s updated the mock's status.", 158 - $this->renderHandleLink($author_phid)); 165 + if ($new == PholioMock::STATUS_CLOSED) { 166 + return pht( 167 + '%s closed this mock.', 168 + $this->renderHandleLink($author_phid)); 169 + } else { 170 + return pht( 171 + '%s opened this mock.', 172 + $this->renderHandleLink($author_phid)); 173 + } 159 174 break; 160 175 case self::TYPE_INLINE: 161 176 $count = 1; ··· 260 275 $this->renderHandleLink($object_phid)); 261 276 break; 262 277 case self::TYPE_STATUS: 263 - return pht( 264 - '%s updated the status for %s.', 265 - $this->renderHandleLink($author_phid), 266 - $this->renderHandleLink($object_phid)); 278 + if ($new == PholioMock::STATUS_CLOSED) { 279 + return pht( 280 + '%s closed a mock %s.', 281 + $this->renderHandleLink($author_phid), 282 + $this->renderHandleLink($object_phid)); 283 + } else { 284 + return pht( 285 + '%s opened a mock %s.', 286 + $this->renderHandleLink($author_phid), 287 + $this->renderHandleLink($object_phid)); 288 + } 267 289 break; 268 290 case self::TYPE_INLINE: 269 291 return pht( ··· 347 369 $new = $this->getNewValue(); 348 370 349 371 switch ($this->getTransactionType()) { 372 + case self::TYPE_STATUS: 373 + if ($new == PholioMock::STATUS_CLOSED) { 374 + return PhabricatorTransactions::COLOR_INDIGO; 375 + } else { 376 + return PhabricatorTransactions::COLOR_GREEN; 377 + } 350 378 case self::TYPE_NAME: 351 379 if ($old === null) { 352 380 return PhabricatorTransactions::COLOR_GREEN; 353 381 } 354 - case self::TYPE_DESCRIPTION: 355 - case self::TYPE_STATUS: 356 - case self::TYPE_IMAGE_NAME: 357 - case self::TYPE_IMAGE_DESCRIPTION: 358 - case self::TYPE_IMAGE_SEQUENCE: 359 - return PhabricatorTransactions::COLOR_BLUE; 360 382 case self::TYPE_IMAGE_REPLACE: 361 383 return PhabricatorTransactions::COLOR_YELLOW; 362 384 case self::TYPE_IMAGE_FILE:
+1
src/applications/pholio/view/PholioMockThumbGridView.php
··· 107 107 108 108 return id(new PHUIObjectBoxView()) 109 109 ->setHeaderText(pht('Mock History')) 110 + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 110 111 ->appendChild($grid); 111 112 } 112 113