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

Clean up watchers and members project page

Summary: Various little fixes, mostly moves information from the "Details" section either into the curtain or into the specific watchers or members list based on user viewership. I think this page is both cleaner and more informative.

Test Plan:
Lock, Unlock, Watch, Join, various projects with multiple users.

{F4959101}

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin

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

+115 -115
+3 -3
resources/celerity/map.php
··· 9 9 'names' => array( 10 10 'conpherence.pkg.css' => 'ff161f2d', 11 11 'conpherence.pkg.js' => 'b5b51108', 12 - 'core.pkg.css' => '24ffbe93', 12 + 'core.pkg.css' => 'd1bf3405', 13 13 'core.pkg.js' => '2ff7879f', 14 14 'darkconsole.pkg.js' => '1f9a31bc', 15 15 'differential.pkg.css' => '90b30783', ··· 160 160 'rsrc/css/phui/phui-icon.css' => '12b387a1', 161 161 'rsrc/css/phui/phui-image-mask.css' => 'a8498f9c', 162 162 'rsrc/css/phui/phui-info-panel.css' => '27ea50a1', 163 - 'rsrc/css/phui/phui-info-view.css' => 'ec92802a', 163 + 'rsrc/css/phui/phui-info-view.css' => '6e217679', 164 164 'rsrc/css/phui/phui-invisible-character-view.css' => '6993d9f0', 165 165 'rsrc/css/phui/phui-lightbox.css' => '0a035e40', 166 166 'rsrc/css/phui/phui-list.css' => '12eb8ce6', ··· 867 867 'phui-icon-view-css' => '12b387a1', 868 868 'phui-image-mask-css' => 'a8498f9c', 869 869 'phui-info-panel-css' => '27ea50a1', 870 - 'phui-info-view-css' => 'ec92802a', 870 + 'phui-info-view-css' => '6e217679', 871 871 'phui-inline-comment-view-css' => 'be663c95', 872 872 'phui-invisible-character-view-css' => '6993d9f0', 873 873 'phui-lightbox-css' => '0a035e40',
+40 -108
src/applications/project/controller/PhabricatorProjectMembersViewController.php
··· 20 20 21 21 $this->setProject($project); 22 22 $title = pht('Members and Watchers'); 23 - 24 - $properties = $this->buildProperties($project); 25 23 $curtain = $this->buildCurtainView($project); 26 - 27 - $object_box = id(new PHUIObjectBoxView()) 28 - ->setHeaderText(pht('Details')) 29 - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 30 - ->addPropertyList($properties); 31 24 32 25 $member_list = id(new PhabricatorProjectMemberListView()) 33 26 ->setUser($viewer) ··· 52 45 ->setHeader($title) 53 46 ->setHeaderIcon('fa-group'); 54 47 48 + require_celerity_resource('project-view-css'); 49 + 55 50 $view = id(new PHUITwoColumnView()) 56 51 ->setHeader($header) 57 52 ->setCurtain($curtain) 53 + ->addClass('project-view-home') 54 + ->addClass('project-view-people-home') 58 55 ->setMainColumn(array( 59 - $object_box, 60 56 $member_list, 61 57 $watcher_list, 62 58 )); 63 - 64 59 65 60 return $this->newPage() 66 61 ->setNavigation($nav) ··· 69 64 ->appendChild($view); 70 65 } 71 66 72 - private function buildProperties(PhabricatorProject $project) { 73 - $viewer = $this->getViewer(); 74 - 75 - $view = id(new PHUIPropertyListView()) 76 - ->setUser($viewer) 77 - ->setObject($project); 78 - 79 - if ($project->isMilestone()) { 80 - $icon_key = PhabricatorProjectIconSet::getMilestoneIconKey(); 81 - $icon = PhabricatorProjectIconSet::getIconIcon($icon_key); 82 - $target = PhabricatorProjectIconSet::getIconName($icon_key); 83 - $note = pht( 84 - 'Members of the parent project are members of this project.'); 85 - $show_join = false; 86 - } else if ($project->getHasSubprojects()) { 87 - $icon = 'fa-sitemap'; 88 - $target = pht('Parent Project'); 89 - $note = pht( 90 - 'Members of all subprojects are members of this project.'); 91 - $show_join = false; 92 - } else if ($project->getIsMembershipLocked()) { 93 - $icon = 'fa-lock'; 94 - $target = pht('Locked Project'); 95 - $note = pht( 96 - 'Users with access may join this project, but may not leave.'); 97 - $show_join = true; 98 - } else { 99 - $icon = 'fa-briefcase'; 100 - $target = pht('Normal Project'); 101 - $note = pht('Users with access may join and leave this project.'); 102 - $show_join = true; 103 - } 104 - 105 - $item = id(new PHUIStatusItemView()) 106 - ->setIcon($icon) 107 - ->setTarget(phutil_tag('strong', array(), $target)) 108 - ->setNote($note); 109 - 110 - $status = id(new PHUIStatusListView()) 111 - ->addItem($item); 112 - 113 - $view->addProperty(pht('Membership'), $status); 114 - 115 - if ($show_join) { 116 - $descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions( 117 - $viewer, 118 - $project); 119 - 120 - $view->addProperty( 121 - pht('Joinable By'), 122 - $descriptions[PhabricatorPolicyCapability::CAN_JOIN]); 123 - } 124 - 125 - $viewer_phid = $viewer->getPHID(); 126 - 127 - if ($project->isUserWatcher($viewer_phid)) { 128 - $watch_item = id(new PHUIStatusItemView()) 129 - ->setIcon('fa-eye green') 130 - ->setTarget(phutil_tag('strong', array(), pht('Watching'))) 131 - ->setNote( 132 - pht( 133 - 'You will receive mail about changes made to any related '. 134 - 'object.')); 135 - 136 - $watch_status = id(new PHUIStatusListView()) 137 - ->addItem($watch_item); 138 - 139 - $view->addProperty(pht('Watching'), $watch_status); 140 - } 141 - 142 - if ($project->isUserMember($viewer_phid)) { 143 - $is_silenced = $this->isProjectSilenced($project); 144 - if ($is_silenced) { 145 - $mail_icon = 'fa-envelope-o grey'; 146 - $mail_target = pht('Disabled'); 147 - $mail_note = pht( 148 - 'When mail is sent to project members, you will not receive '. 149 - 'a copy.'); 150 - } else { 151 - $mail_icon = 'fa-envelope-o green'; 152 - $mail_target = pht('Enabled'); 153 - $mail_note = pht( 154 - 'You will receive mail that is sent to project members.'); 155 - } 156 - 157 - $mail_item = id(new PHUIStatusItemView()) 158 - ->setIcon($mail_icon) 159 - ->setTarget(phutil_tag('strong', array(), $mail_target)) 160 - ->setNote($mail_note); 161 - 162 - $mail_status = id(new PHUIStatusListView()) 163 - ->addItem($mail_item); 164 - 165 - $view->addProperty(pht('Mail to Members'), $mail_status); 166 - } 167 - 168 - return $view; 169 - } 170 - 171 67 private function buildCurtainView(PhabricatorProject $project) { 172 68 $viewer = $this->getViewer(); 173 69 $id = $project->getID(); ··· 271 167 ->setHref($this->getApplicationURI("lock/{$id}/")) 272 168 ->setDisabled(!$can_lock) 273 169 ->setWorkflow(true)); 170 + 171 + if ($project->isMilestone()) { 172 + $icon_key = PhabricatorProjectIconSet::getMilestoneIconKey(); 173 + $header = PhabricatorProjectIconSet::getIconName($icon_key); 174 + $note = pht( 175 + 'Members of the parent project are members of this project.'); 176 + $show_join = false; 177 + } else if ($project->getHasSubprojects()) { 178 + $header = pht('Parent Project'); 179 + $note = pht( 180 + 'Members of all subprojects are members of this project.'); 181 + $show_join = false; 182 + } else if ($project->getIsMembershipLocked()) { 183 + $header = pht('Locked Project'); 184 + $note = pht( 185 + 'Users with access may join this project, but may not leave.'); 186 + $show_join = true; 187 + } else { 188 + $header = pht('Normal Project'); 189 + $note = pht('Users with access may join and leave this project.'); 190 + $show_join = true; 191 + } 192 + 193 + $curtain->newPanel() 194 + ->setHeaderText($header) 195 + ->appendChild($note); 196 + 197 + if ($show_join) { 198 + $descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions( 199 + $viewer, 200 + $project); 201 + 202 + $curtain->newPanel() 203 + ->setHeaderText(pht('Joinable By')) 204 + ->appendChild($descriptions[PhabricatorPolicyCapability::CAN_JOIN]); 205 + } 274 206 275 207 return $curtain; 276 208 }
+32 -1
src/applications/project/view/PhabricatorProjectMemberListView.php
··· 4 4 extends PhabricatorProjectUserListView { 5 5 6 6 protected function canEditList() { 7 - $viewer = $this->getUser(); 7 + $viewer = $this->getViewer(); 8 8 $project = $this->getProject(); 9 9 10 10 if (!$project->supportsEditMembers()) { ··· 29 29 30 30 protected function getHeaderText() { 31 31 return pht('Members'); 32 + } 33 + 34 + protected function getMembershipNote() { 35 + $viewer = $this->getViewer(); 36 + $viewer_phid = $viewer->getPHID(); 37 + $project = $this->getProject(); 38 + 39 + if (!$viewer_phid) { 40 + return null; 41 + } 42 + 43 + $note = null; 44 + if ($project->isUserMember($viewer_phid)) { 45 + $edge_type = PhabricatorProjectSilencedEdgeType::EDGECONST; 46 + $silenced = PhabricatorEdgeQuery::loadDestinationPHIDs( 47 + $project->getPHID(), 48 + $edge_type); 49 + $silenced = array_fuse($silenced); 50 + $is_silenced = isset($silenced[$viewer_phid]); 51 + if ($is_silenced) { 52 + $note = pht( 53 + 'You have disabled mail. When mail is sent to project members, '. 54 + 'you will not receive a copy.'); 55 + } else { 56 + $note = pht( 57 + 'You are a member and you will receive mail that is sent to all '. 58 + 'project members.'); 59 + } 60 + } 61 + 62 + return $note; 32 63 } 33 64 34 65 }
+8
src/applications/project/view/PhabricatorProjectUserListView.php
··· 43 43 abstract protected function getNoDataString(); 44 44 abstract protected function getRemoveURI($phid); 45 45 abstract protected function getHeaderText(); 46 + abstract protected function getMembershipNote(); 46 47 47 48 public function render() { 48 49 $viewer = $this->getViewer(); ··· 134 135 $box = id(new PHUIObjectBoxView()) 135 136 ->setHeader($header) 136 137 ->setObjectList($list); 138 + 139 + if ($this->getMembershipNote()) { 140 + $info = id(new PHUIInfoView()) 141 + ->setSeverity(PHUIInfoView::SEVERITY_PLAIN) 142 + ->appendChild($this->getMembershipNote()); 143 + $box->setInfoView($info); 144 + } 137 145 138 146 if ($this->background) { 139 147 $box->setBackground($this->background);
+14 -1
src/applications/project/view/PhabricatorProjectWatcherListView.php
··· 4 4 extends PhabricatorProjectUserListView { 5 5 6 6 protected function canEditList() { 7 - $viewer = $this->getUser(); 7 + $viewer = $this->getViewer(); 8 8 $project = $this->getProject(); 9 9 10 10 return PhabricatorPolicyFilter::hasCapability( ··· 25 25 26 26 protected function getHeaderText() { 27 27 return pht('Watchers'); 28 + } 29 + 30 + protected function getMembershipNote() { 31 + $viewer = $this->getViewer(); 32 + $viewer_phid = $viewer->getPHID(); 33 + $project = $this->getProject(); 34 + 35 + $note = null; 36 + if ($project->isUserWatcher($viewer_phid)) { 37 + $note = pht('You are watching this project and will receive mail about '. 38 + 'changes made to any related object.'); 39 + } 40 + return $note; 28 41 } 29 42 30 43 }
+10 -2
src/view/form/PHUIInfoView.php
··· 7 7 const SEVERITY_NOTICE = 'notice'; 8 8 const SEVERITY_NODATA = 'nodata'; 9 9 const SEVERITY_SUCCESS = 'success'; 10 + const SEVERITY_PLAIN = 'plain'; 10 11 11 12 private $title; 12 13 private $errors; ··· 52 53 return $this; 53 54 } 54 55 55 - public function setIcon(PHUIIconView $icon) { 56 - $this->icon = $icon; 56 + public function setIcon($icon) { 57 + if ($icon instanceof PHUIIconView) { 58 + $this->icon = $icon; 59 + } else { 60 + $icon = id(new PHUIIconView()) 61 + ->setIcon($icon); 62 + } 63 + 57 64 return $this; 58 65 } 59 66 ··· 72 79 case self::SEVERITY_NOTICE: 73 80 $icon = 'fa-info-circle'; 74 81 break; 82 + case self::SEVERITY_PLAIN: 75 83 case self::SEVERITY_NODATA: 76 84 return null; 77 85 break;
+8
webroot/rsrc/css/phui/phui-info-view.css
··· 11 11 border-radius: 3px; 12 12 } 13 13 14 + div.phui-info-view.phui-info-severity-plain { 15 + background: {$lightgreybackground}; 16 + color: {$bluetext}; 17 + border: none; 18 + padding: 8px 12px; 19 + margin-bottom: 4px !important; 20 + } 21 + 14 22 .phui-info-view.phui-info-view-flush { 15 23 margin: 0 0 20px 0; 16 24 }