From 2538f6717836779b866041213e79115ef390f555 Mon Sep 17 00:00:00 2001 From: Chad Little Date: Sun, 30 Jul 2017 11:36:24 -0700 Subject: [PATCH 01/16] Add some more builtin project images Summary: Moves over some of the icons we build for SAAS that can be useful for projects to. Also make builtin list dynamic. Test Plan: Edit a project image, select a cool sword. Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D18297 --- resources/builtin/projects/v3/contact.png | Bin 0 -> 6819 bytes resources/builtin/projects/v3/gears.png | Bin 0 -> 15975 bytes resources/builtin/projects/v3/gold.png | Bin 0 -> 7077 bytes resources/builtin/projects/v3/home.png | Bin 0 -> 8787 bytes resources/builtin/projects/v3/manage.png | Bin 0 -> 6277 bytes resources/builtin/projects/v3/silver.png | Bin 0 -> 6059 bytes resources/builtin/projects/v3/support.png | Bin 0 -> 4726 bytes resources/builtin/projects/v3/sword.png | Bin 0 -> 6791 bytes ...habricatorProjectEditPictureController.php | 38 ++++-------------- 9 files changed, 8 insertions(+), 30 deletions(-) create mode 100644 resources/builtin/projects/v3/contact.png create mode 100644 resources/builtin/projects/v3/gears.png create mode 100644 resources/builtin/projects/v3/gold.png create mode 100644 resources/builtin/projects/v3/home.png create mode 100644 resources/builtin/projects/v3/manage.png create mode 100644 resources/builtin/projects/v3/silver.png create mode 100644 resources/builtin/projects/v3/support.png create mode 100644 resources/builtin/projects/v3/sword.png diff --git a/resources/builtin/projects/v3/contact.png b/resources/builtin/projects/v3/contact.png new file mode 100644 index 0000000000000000000000000000000000000000..6b3095dc3d4245ed9fbddcf1d87a4b1626ab4a09 GIT binary patch literal 6819 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�le4rDn&S3CSN`cOH*Ebs64kVbGM% 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Ν&aA~i5hbuH>_F$Fa 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 literal 0 HcmV?d00001 diff --git a/resources/builtin/projects/v3/home.png b/resources/builtin/projects/v3/home.png new file mode 100644 index 0000000000000000000000000000000000000000..808d639f0dbfc39113f669fe24cf0b65c7307c85 GIT binary patch literal 8787 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 H82LW{G(Z)v literal 0 HcmV?d00001 diff --git a/resources/builtin/projects/v3/manage.png b/resources/builtin/projects/v3/manage.png new file mode 100644 index 0000000000000000000000000000000000000000..7804360a29456b72bb1f0b4bcc7ab4c91ea5c75f GIT binary patch literal 6277 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 literal 0 HcmV?d00001 diff --git a/resources/builtin/projects/v3/support.png b/resources/builtin/projects/v3/support.png new file mode 100644 index 0000000000000000000000000000000000000000..88a97467089a421956f723901c9fa7159698e10d GIT binary patch literal 4726 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 literal 0 HcmV?d00001 diff --git a/resources/builtin/projects/v3/sword.png b/resources/builtin/projects/v3/sword.png new file mode 100644 index 0000000000000000000000000000000000000000..30040633fd4b9674c92041184f0949e79352b118 GIT binary patch literal 6791 zcmZvBdpy&B^uOyAlS}4)3#kmbmn4@)E{QH?#%4Aml9KBrmql|Ym##{ri*2^aT~qFt zN~yM?B%g>(R2qf&zSi&Z`2F$QKP3Q_<)x zOip^D9zycGcJ;d8)!(0S{U!1iS@7BUuygA5Z@~xDzI3hIHf~tBp7v!|rOtm{{qOO$ z7w>*qua90i(-QfjP5A)SE*0h_Bzjh89isdFxL5o4jtxgdwAGWXZPJa7s&$=P;?)ty zRSW|eiX<`?LchGbgDops&rn$xm$!e4XDB)%e4h1ATxF=b;l$R3UXd>K>5-fe)9r~9 zt7j#G9QMqmKCoB+&jFIX^Jm$X$P9W1zd*>tL|P`Tsq4;|mZ8o*ajf{AjB$H~6VLXp ziRYzWQhlnYSJBw6Q6Ta6tk7-oA1RV?V%g+U$1UW`v=GLv{LszCsqr5oRSc(fvqaCe z&fJXBiwR~b^srqbj!>eJ{C*cM`Ipr)udOFU#V|y-1=eMBW!|{>iA421gG$%YftKL% z7#AyOWP!%p$5HX)n$}Uch3vU&Hwy=Q&Wv%BrAbbc{&s1V+DGJ)58V!ODslI9BU!*= zTmnd*`WLpEHJ(CmnHvdqa=8hkJo;gJ${>QBurQ6=1-2c&Bi-w{fj`q<_{)3yG4%j= zOhUvP%-h|SW0kcrQIF@w+76mKuP|#*oV1*|^=;EmNOoVsN74Kgv4aCYb^7ybN@uAj zPtj)z?=A(7SkxYk9emM0@i!4F5~K-t4|J>_Y?e?l)R|5&T9fWN(NXs2N>V`jiF;OV z=UpHC+9T69`Rv~5_xp7(FU@oE-8bQb`%!+?i_KZehB_h5VoRi%+O}xkqs9LCg=;Sk zM-(R6#AWPufiOkjjD2@vwu9)^L)!IQnPwYXi_Gzs2h1u~6OspUa@L)XUW-=1B?5ka z8?S%PX4d|0xzKXw4`D(^QO+p!m@MWL#VzR7(zlxYk}6i4`||k!&2^mIQ7E|v0X1)o zEQ?8?uBm3#TcJGDBqJH*8GTvIxyI@KUz3VHU18G=zHk?*>b{5EKXZv4YKA&1+tlmL zXKtz9igKdHp6VI6qUHB!@lR`~5)eW6i≶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 A&j0`b literal 0 HcmV?d00001 diff --git a/src/applications/project/controller/PhabricatorProjectEditPictureController.php b/src/applications/project/controller/PhabricatorProjectEditPictureController.php index 97b7fe1792..e601d744c0 100644 --- a/src/applications/project/controller/PhabricatorProjectEditPictureController.php +++ b/src/applications/project/controller/PhabricatorProjectEditPictureController.php @@ -124,38 +124,16 @@ final class PhabricatorProjectEditPictureController } } - $builtins = array( - 'projects/v3/book.png', - 'projects/v3/bug.png', - 'projects/v3/calendar.png', - 'projects/v3/clipboard.png', - 'projects/v3/cloud.png', - 'projects/v3/creditcard.png', - 'projects/v3/database.png', - 'projects/v3/desktop.png', - 'projects/v3/experimental.png', - 'projects/v3/flag.png', - 'projects/v3/folder.png', - 'projects/v3/lightbulb.png', - 'projects/v3/lock.png', - 'projects/v3/mail.png', - 'projects/v3/marker.png', - 'projects/v3/mobile.png', - 'projects/v3/organization.png', - 'projects/v3/people.png', - 'projects/v3/piechart.png', - 'projects/v3/robot.png', - 'projects/v3/rocket.png', - 'projects/v3/servers.png', - 'projects/v3/sitemap.png', - 'projects/v3/tag.png', - 'projects/v3/trash.png', - 'projects/v3/truck.png', - 'projects/v3/umbrella.png', - ); + $root = dirname(phutil_get_library_root('phabricator')); + $root = $root.'/resources/builtin/projects/v3/'; + + $builtins = id(new FileFinder($root)) + ->withType('f') + ->withFollowSymlinks(true) + ->find(); foreach ($builtins as $builtin) { - $file = PhabricatorFile::loadBuiltin($viewer, $builtin); + $file = PhabricatorFile::loadBuiltin($viewer, 'projects/v3/'.$builtin); $images[$file->getPHID()] = array( 'uri' => $file->getBestURI(), 'tip' => pht('Builtin Image'), From 1ad369b3065c9aa47cbf43fac42972c8269b9c4e Mon Sep 17 00:00:00 2001 From: Chad Little Date: Sun, 30 Jul 2017 11:56:27 -0700 Subject: [PATCH 02/16] Remove PHUIInfoPanelView Summary: We've never used this, and no current plans to. Test Plan: grep for use cases. Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D18298 --- resources/celerity/map.php | 2 - src/__phutil_library_map__.php | 4 - .../examples/PHUIInfoPanelExample.php | 138 ------------------ src/view/phui/PHUIInfoPanelView.php | 120 --------------- webroot/rsrc/css/phui/phui-info-panel.css | 50 ------- 5 files changed, 314 deletions(-) delete mode 100644 src/applications/uiexample/examples/PHUIInfoPanelExample.php delete mode 100644 src/view/phui/PHUIInfoPanelView.php delete mode 100644 webroot/rsrc/css/phui/phui-info-panel.css diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 86c6567f0e..88f2db1eec 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -163,7 +163,6 @@ return array( 'rsrc/css/phui/phui-icon-set-selector.css' => '87db8fee', 'rsrc/css/phui/phui-icon.css' => '5c4a5de6', 'rsrc/css/phui/phui-image-mask.css' => 'a8498f9c', - 'rsrc/css/phui/phui-info-panel.css' => '27ea50a1', 'rsrc/css/phui/phui-info-view.css' => 'e1b4ec37', 'rsrc/css/phui/phui-invisible-character-view.css' => '6993d9f0', 'rsrc/css/phui/phui-left-right.css' => 'f60c67e7', @@ -852,7 +851,6 @@ return array( 'phui-icon-set-selector-css' => '87db8fee', 'phui-icon-view-css' => '5c4a5de6', 'phui-image-mask-css' => 'a8498f9c', - 'phui-info-panel-css' => '27ea50a1', 'phui-info-view-css' => 'e1b4ec37', 'phui-inline-comment-view-css' => '65ae3bc2', 'phui-invisible-character-view-css' => '6993d9f0', diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 1527091575..4488bacd9a 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1770,8 +1770,6 @@ phutil_register_library_map(array( 'PHUIImageMaskExample' => 'applications/uiexample/examples/PHUIImageMaskExample.php', 'PHUIImageMaskView' => 'view/phui/PHUIImageMaskView.php', 'PHUIInfoExample' => 'applications/uiexample/examples/PHUIInfoExample.php', - 'PHUIInfoPanelExample' => 'applications/uiexample/examples/PHUIInfoPanelExample.php', - 'PHUIInfoPanelView' => 'view/phui/PHUIInfoPanelView.php', 'PHUIInfoView' => 'view/form/PHUIInfoView.php', 'PHUIInvisibleCharacterTestCase' => 'view/phui/__tests__/PHUIInvisibleCharacterTestCase.php', 'PHUIInvisibleCharacterView' => 'view/phui/PHUIInvisibleCharacterView.php', @@ -6928,8 +6926,6 @@ phutil_register_library_map(array( 'PHUIImageMaskExample' => 'PhabricatorUIExample', 'PHUIImageMaskView' => 'AphrontTagView', 'PHUIInfoExample' => 'PhabricatorUIExample', - 'PHUIInfoPanelExample' => 'PhabricatorUIExample', - 'PHUIInfoPanelView' => 'AphrontView', 'PHUIInfoView' => 'AphrontTagView', 'PHUIInvisibleCharacterTestCase' => 'PhabricatorTestCase', 'PHUIInvisibleCharacterView' => 'AphrontView', diff --git a/src/applications/uiexample/examples/PHUIInfoPanelExample.php b/src/applications/uiexample/examples/PHUIInfoPanelExample.php deleted file mode 100644 index 74ed18f37c..0000000000 --- a/src/applications/uiexample/examples/PHUIInfoPanelExample.php +++ /dev/null @@ -1,138 +0,0 @@ -setHeader(pht('Conpherence')); - - $header2 = id(new PHUIHeaderView()) - ->setHeader(pht('Diffusion')); - - $header3 = id(new PHUIHeaderView()) - ->setHeader(pht('Backend Ops Projects')); - - $header4 = id(new PHUIHeaderView()) - ->setHeader(pht('Revamp Liberty')) - ->setSubHeader(pht('For great justice')) - ->setImage( - celerity_get_resource_uri('/rsrc/image/people/washington.png')); - - $header5 = id(new PHUIHeaderView()) - ->setHeader(pht('Phacility Redesign')) - ->setSubHeader(pht('Move them pixels')) - ->setImage( - celerity_get_resource_uri('/rsrc/image/people/harding.png')); - - $header6 = id(new PHUIHeaderView()) - ->setHeader(pht('Python Phlux')) - ->setSubHeader(pht('No. Sleep. Till Brooklyn.')) - ->setImage( - celerity_get_resource_uri('/rsrc/image/people/taft.png')); - - $column1 = id(new PHUIInfoPanelView()) - ->setHeader($header1) - ->setColumns(3) - ->addInfoBlock(3, pht('Needs Triage')) - ->addInfoBlock(5, pht('Unbreak Now')) - ->addInfoBlock(0, pht('High')) - ->addInfoBlock(0, pht('Normal')) - ->addInfoBlock(12, pht('Low')) - ->addInfoBlock(123, pht('Wishlist')); - - $column2 = id(new PHUIInfoPanelView()) - ->setHeader($header2) - ->setColumns(3) - ->addInfoBlock(3, pht('Needs Triage')) - ->addInfoBlock(5, pht('Unbreak Now')) - ->addInfoBlock(0, pht('High')) - ->addInfoBlock(0, pht('Normal')) - ->addInfoBlock(12, pht('Low')) - ->addInfoBlock(123, pht('Wishlist')); - - $column3 = id(new PHUIInfoPanelView()) - ->setHeader($header3) - ->setColumns(3) - ->addInfoBlock(3, pht('Needs Triage')) - ->addInfoBlock(5, pht('Unbreak Now')) - ->addInfoBlock(0, pht('High')) - ->addInfoBlock(0, pht('Normal')) - ->addInfoBlock(12, pht('Low')) - ->addInfoBlock(123, pht('Wishlist')); - - $column4 = id(new PHUIInfoPanelView()) - ->setHeader($header4) - ->setColumns(3) - ->setProgress(90) - ->addInfoBlock(3, pht('Needs Triage')) - ->addInfoBlock(5, pht('Unbreak Now')) - ->addInfoBlock(0, pht('High')) - ->addInfoBlock(0, pht('Normal')) - ->addInfoBlock(0, pht('Wishlist')); - - $column5 = id(new PHUIInfoPanelView()) - ->setHeader($header5) - ->setColumns(2) - ->setProgress(25) - ->addInfoBlock(3, pht('Needs Triage')) - ->addInfoBlock(5, pht('Unbreak Now')) - ->addInfoBlock(0, pht('High')) - ->addInfoBlock(0, pht('Normal')); - - $column6 = id(new PHUIInfoPanelView()) - ->setHeader($header6) - ->setColumns(2) - ->setProgress(50) - ->addInfoBlock(3, pht('Needs Triage')) - ->addInfoBlock(5, pht('Unbreak Now')) - ->addInfoBlock(0, pht('High')) - ->addInfoBlock(0, pht('Normal')); - - $layout1 = id(new AphrontMultiColumnView()) - ->addColumn($column1) - ->addColumn($column2) - ->addColumn($column3) - ->setFluidLayout(true); - - $layout2 = id(new AphrontMultiColumnView()) - ->addColumn($column4) - ->addColumn($column5) - ->addColumn($column6) - ->setFluidLayout(true); - - - $head1 = id(new PHUIHeaderView()) - ->setHeader(pht('Flagged')); - - $head2 = id(new PHUIHeaderView()) - ->setHeader(pht('Sprints')); - - - $wrap1 = id(new PHUIBoxView()) - ->appendChild($layout1) - ->addMargin(PHUI::MARGIN_LARGE_BOTTOM); - - $wrap2 = id(new PHUIBoxView()) - ->appendChild($layout2) - ->addMargin(PHUI::MARGIN_LARGE_BOTTOM); - - - return phutil_tag( - 'div', - array(), - array( - $head1, - $wrap1, - $head2, - $wrap2, - )); - } -} diff --git a/src/view/phui/PHUIInfoPanelView.php b/src/view/phui/PHUIInfoPanelView.php deleted file mode 100644 index 91f9d2b8e4..0000000000 --- a/src/view/phui/PHUIInfoPanelView.php +++ /dev/null @@ -1,120 +0,0 @@ -header = $header; - return $this; - } - - public function setProgress($progress) { - $this->progress = $progress; - return $this; - } - - public function setColumns($columns) { - $this->columns = $columns; - return $this; - } - - public function addInfoblock($num, $text) { - $this->infoblock[] = array($num, $text); - return $this; - } - - public function render() { - require_celerity_resource('phui-info-panel-css'); - - $trs = array(); - $rows = ceil(count($this->infoblock) / $this->columns); - for ($i = 0; $i < $rows; $i++) { - $tds = array(); - $ii = 1; - foreach ($this->infoblock as $key => $cell) { - $tds[] = $this->renderCell($cell); - unset($this->infoblock[$key]); - $ii++; - if ($ii > $this->columns) { - break; - } - } - $trs[] = phutil_tag( - 'tr', - array( - 'class' => 'phui-info-panel-table-row', - ), - $tds); - } - - $table = phutil_tag( - 'table', - array( - 'class' => 'phui-info-panel-table', - ), - $trs); - - $table = id(new PHUIBoxView()) - ->addPadding(PHUI::PADDING_MEDIUM) - ->appendChild($table); - - $progress = null; - if ($this->progress) { - $progress = phutil_tag( - 'div', - array( - 'class' => 'phui-info-panel-progress', - 'style' => 'width: '.(int)$this->progress.'%;', - ), - null); - } - - $box = id(new PHUIObjectBoxView()) - ->setHeader($this->header) - ->appendChild($table) - ->appendChild($progress); - - return phutil_tag( - 'div', - array( - 'class' => 'phui-info-panel', - ), - $box); - } - - private function renderCell($cell) { - $number = phutil_tag( - 'div', - array( - 'class' => 'phui-info-panel-number', - ), - $cell[0]); - - $text = phutil_tag( - 'div', - array( - 'class' => 'phui-info-panel-text', - ), - $cell[1]); - - return phutil_tag( - 'td', - array( - 'class' => 'phui-info-panel-table-cell', - 'align' => 'center', - 'width' => floor(100 / $this->columns).'%', - ), - array( - $number, - $text, - )); - } -} diff --git a/webroot/rsrc/css/phui/phui-info-panel.css b/webroot/rsrc/css/phui/phui-info-panel.css deleted file mode 100644 index a182292a89..0000000000 --- a/webroot/rsrc/css/phui/phui-info-panel.css +++ /dev/null @@ -1,50 +0,0 @@ -/** - * @provides phui-info-panel-css - */ - -.phui-info-panel .phui-object-box .phui-header-has-image { - padding: 2px 0 0 2px; -} - -.phui-info-panel .phui-object-box .phui-header-image { - margin: 0 8px 0 0; -} - -.phui-info-panel-table { - border-collapse: collapse; - border-style: hidden; - width: 100%; -} - -.phui-info-panel-table td, -.phui-info-panel-table th { - border: 1px solid {$thinblueborder}; -} - -.phui-info-panel-table-cell { - padding: 8px; -} - -.phui-info-panel-number, -.phui-info-panel-number a { - font-size: 30px; - font-weight: bold; - color: {$lightgreytext}; - -webkit-font-smoothing: antialiased; -} - -.phui-info-panel-text, -.phui-info-panel-text a { - color: {$lightgreytext}; -} - -.phui-info-panel-number a:hover, -.phui-info-panel-text a:hover { - color: {$greytext}; - text-decoration: none; -} - -.phui-info-panel-progress { - background: {$green}; - height: 6px; -} From ddd7cbb698cf63602c8a74f1fc1e5450e8a7d0c3 Mon Sep 17 00:00:00 2001 From: Chad Little Date: Sun, 30 Jul 2017 12:21:36 -0700 Subject: [PATCH 03/16] Add setImage to PHUIActionPanelView Summary: Additonal option to use newly made images in these views. Test Plan: Built an example in UIExamples. {F5071682} Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D18299 --- resources/celerity/map.php | 4 ++-- .../examples/PHUIActionPanelExample.php | 7 ++++++- src/view/phui/PHUIActionPanelView.php | 21 +++++++++++++++++++ webroot/rsrc/css/phui/phui-action-panel.css | 6 ++++++ 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 88f2db1eec..2437a1e4c2 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -139,7 +139,7 @@ return array( 'rsrc/css/phui/object-item/phui-oi-list-view.css' => 'bf094950', 'rsrc/css/phui/object-item/phui-oi-simple-ui.css' => 'a8beebea', 'rsrc/css/phui/phui-action-list.css' => '6ee16164', - 'rsrc/css/phui/phui-action-panel.css' => '91c7b835', + 'rsrc/css/phui/phui-action-panel.css' => 'b4798122', 'rsrc/css/phui/phui-badge.css' => '22c0cf4f', 'rsrc/css/phui/phui-basic-nav-view.css' => 'a0705f53', 'rsrc/css/phui/phui-big-info-view.css' => 'd13afcde', @@ -818,7 +818,7 @@ return array( 'phortune-invoice-css' => '476055e2', 'phrequent-css' => 'ffc185ad', 'phriction-document-css' => '4282e4ad', - 'phui-action-panel-css' => '91c7b835', + 'phui-action-panel-css' => 'b4798122', 'phui-badge-view-css' => '22c0cf4f', 'phui-basic-nav-view-css' => 'a0705f53', 'phui-big-info-view-css' => 'd13afcde', diff --git a/src/applications/uiexample/examples/PHUIActionPanelExample.php b/src/applications/uiexample/examples/PHUIActionPanelExample.php index 9294dcbea6..e71f2ce846 100644 --- a/src/applications/uiexample/examples/PHUIActionPanelExample.php +++ b/src/applications/uiexample/examples/PHUIActionPanelExample.php @@ -11,10 +11,15 @@ final class PHUIActionPanelExample extends PhabricatorUIExample { } public function renderExample() { + $viewer = $this->getRequest()->getUser(); $view = id(new AphrontMultiColumnView()) ->setFluidLayout(true); + $credit = PhabricatorFile::loadBuiltin( + $viewer, 'projects/v3/creditcard.png'); + $image = $credit->getBestURI(); + /* Action Panels */ $panel1 = id(new PHUIActionPanelView()) ->setIcon('fa-book') @@ -53,7 +58,7 @@ final class PHUIActionPanelExample extends PhabricatorUIExample { /* Action Panels */ $panel1 = id(new PHUIActionPanelView()) - ->setIcon('fa-credit-card') + ->setImage($image) ->setHeader(pht('Account Balance')) ->setHref('#') ->setSubHeader(pht('You were last billed $2,245.12 on Dec 12, 2014.')) diff --git a/src/view/phui/PHUIActionPanelView.php b/src/view/phui/PHUIActionPanelView.php index f5f74b2807..8ced0a642b 100644 --- a/src/view/phui/PHUIActionPanelView.php +++ b/src/view/phui/PHUIActionPanelView.php @@ -4,6 +4,7 @@ final class PHUIActionPanelView extends AphrontTagView { private $href; private $fontIcon; + private $image; private $header; private $subHeader; private $bigText; @@ -29,6 +30,11 @@ final class PHUIActionPanelView extends AphrontTagView { return $this; } + public function setImage($image) { + $this->image = $image; + return $this; + } + public function setBigText($text) { $this->bigText = $text; return $this; @@ -89,6 +95,21 @@ final class PHUIActionPanelView extends AphrontTagView { $fonticon); } + if ($this->image) { + $image = phutil_tag( + 'img', + array( + 'class' => 'phui-action-panel-image', + 'src' => $this->image, + )); + $icon = phutil_tag( + 'span', + array( + 'class' => 'phui-action-panel-icon', + ), + $image); + } + $header = null; if ($this->header) { $header = phutil_tag( diff --git a/webroot/rsrc/css/phui/phui-action-panel.css b/webroot/rsrc/css/phui/phui-action-panel.css index d52a1cbaae..63bd351807 100644 --- a/webroot/rsrc/css/phui/phui-action-panel.css +++ b/webroot/rsrc/css/phui/phui-action-panel.css @@ -47,6 +47,12 @@ display: table-cell; } +.phui-action-panel-image { + width: 48px; + height: 48px; + margin: 0 auto; +} + .phui-action-panel-icon a { display: block; } From 1b63a1bd437c2365c5183e11197fca6c9edb4bca Mon Sep 17 00:00:00 2001 From: Chad Little Date: Sun, 30 Jul 2017 16:49:04 -0700 Subject: [PATCH 04/16] Some more project images Summary: Felt like tinkering with Illustrator. Test Plan: Edit Picture, pick new image. Reviewers: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D18301 --- resources/builtin/projects/v3/basic-book.png | Bin 0 -> 3221 bytes resources/builtin/projects/v3/one-server.png | Bin 0 -> 4128 bytes resources/builtin/projects/v3/three-servers.png | Bin 0 -> 6623 bytes resources/builtin/projects/v3/two-servers.png | Bin 0 -> 5460 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 resources/builtin/projects/v3/basic-book.png create mode 100644 resources/builtin/projects/v3/one-server.png create mode 100644 resources/builtin/projects/v3/three-servers.png create mode 100644 resources/builtin/projects/v3/two-servers.png diff --git a/resources/builtin/projects/v3/basic-book.png b/resources/builtin/projects/v3/basic-book.png new file mode 100644 index 0000000000000000000000000000000000000000..b2a6d99415ed219817485e281eca4efcbd837898 GIT binary patch literal 3221 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 Ld#lG5UN`;)BiG

3R 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 M(J)j;s6u1@3yO#=d;kCd literal 0 HcmV?d00001 diff --git a/resources/builtin/projects/v3/two-servers.png b/resources/builtin/projects/v3/two-servers.png new file mode 100644 index 0000000000000000000000000000000000000000..d5d408d9ad6d3cf8741c15bbb5882870c482d5e9 GIT binary patch literal 5460 zcmbW5c{r5s*TBa<44Nz>`%K8vBN34`Q`WI>joqMCBr#-(WQ#&#WD=F^6T=W?C+k?U z4MX;&EZLaY#BK1(=nw0A$y5r-y~i}BLyZEA!H{7fE$;{4#U0LAC7>tJb0B84|JJH z+I$0ekdsgc1#3I4YZz+tX{FE_+v67g$$3%xCQ5xuZyIZ3J}HFiIM!jiPDIp8S27*> zY=05+hc})?Tz+Guy8oxn$lQ8CR)#C)6w(DbDIydR=WSug4Yd^#+yFvV^-TJ&mRN$i0#js*FJGi{wTw zdgUo8x%yE@v?;|Qh5de6kV0Cd1Y^7*WJ%^L%}&Bt65ThEf={Lf^WWyJ6a}oO%=DS| zANWl*GAW%qmz9&7J2)`FgMct`Hb|&2RZO06cyw=PPRt<%NAZH;ssbWs?-l<1b5e&X zr)ftj-|Q?ne_(djy&A!|($El;%;ykEYV4r~GC{~1$>6908OxWeQU$;7&+Yt9GIT&r zihqsBdW}>&?Jby0Bz|pR5oge-7QfW|R$l-0$!GcsC=^&Ivd|m0Vu)H|00^`582s_} zv!fk*1LcKRtl?1aN3?xgt3dp-BbCC9h{U8+(HPE{q8`gD#SRV4Cd#ZRaC&5wH`>ll z%LOALY1-%TjQ#lPC|h(>5f2Vpsn#ctkR_aMV}_jmJ&fRYq13V|@x^_#MI$HAI^b{= zPMD3)x<%K7MC*zD=i2F^cS(eZdQ2stF~8>T9ub+MJ`0J;k+HyA`C=)|7}kemZvih< z+jWct%PP098#?{rjyu%{o(!#I&z<^ERyN++Xt*yQg=i<*83tLOJyB*rTS)OM4n~10 zG&LFuP2kuUXGhd|s{-0}Y1T%)9qjBTu3;piByY@%UlQ;VZGCCvnVbTx! zobIt{4^!B|%{Z=|htOgbz0}t?($N?zC)c}gtdO22Ux%NM#JVbb3l*UtOLy9!kkb!l z^_eZPMdp!6gd7+Jc8K2W>+8T^nxp*&CtEQA!_gonLOhawVcZ#Qh@8Uw6!frWqyqcId8s z%UT-M>B!#%c74d{sM{sPPLj4l*w$FK%<>P&j|ezJTXndfGnih~es^a=>s_eL-r|2TrW_NdOl@*oYQQ^SBvWOct} zXSeEt(fH-YK9%e`w)QonN--m|I~RXjg?u!8V&_2d*8H77Dt6l|@yxu46d2BggN zysB)0xHIrSD>~$bQ5pjXr(~$J<1Lu1VglSqeNOSWaJhQT!#5S6CMUR9UwKxW2xMvA zR+2hd=9sO!I{ejYoZtV#%MP_CDL)!?Zn9TP)ayL*Pt>(}=TYp2X{YNM+Se)lm=$uZ zm|;p4S>5~@uUi|3uo?rsM?*I5SA{aO=o8v?p9p2RXq!5RxV640`e8*ik zuyd-e?IdLBVS>D`ew1zI#MH2`ci#@~vvEh6hJg6f_Si| zvnysyEur_a_{(8ywXmoD=?}*-gATp!LB4W~G2cZ-rxOhP zTre9(syk-vc}fz8(U^IseV1U^n$1pI60yvtl(^DyPcby<_PEQ=iO6%b;z%MA4 z6ICA<} zX*9dxjnW#TrmSiUQ607A<+lk%CTh5wq3tq1loLg=*B@(=Kb6Hzi_^r~7|icPPeF*s zGk1n=FKJrg@|=1G4QD?Y*Vt$0ZjaHh+zjeP^nMaiQc%aafDvtPiNps9Pe!fKtxB;_ zSJ_riX~GqcgRX~Mu1amcJZ?)7>^Pr8P0f~mHtwoK>&N8&s%N1Oc`5K{-I!c{Ulc~ecz2O)dGBhh>IWJ7S0jli zuz^LQx%>7h=c^iB9Fg0C?R>u8=JYmqva7J65YtI}pH~+M7L|Vh83&-Q> z3@4FbZER%rw${&;>8iUx+)RL6^nxgUj1ZNUc0D#N4UvCVO`fGwii){LjO*|0WcT;& zQS_(wY>WGEEl*67YFZak_dM;Nbuh>?n^fzA z6JStvlY~Qmpk<_sxjaXZIwKfH1gZJLq?`O+4f+B?;7sLwcznxNqr~)+I#$wWK}Wt`|+sv*5nHb z5{uZ3`YN|+@a0$hVy^f5Nv))F1A&!0O;n|qRr$piFuglLC($1mpf^nU_G{*@fA8$1 zFk~@Z-%*k@?#eikE*-#~JM)Cs`DL^Vl@%0fbb2?)zN$<5PXu!vIiFiSs8w{v-8pD) zz4k4MG;^^SqJz@I&&z@6uoW#C&%>BA*h82MpWDj#epuskpro|!`ntSDcP;-86$TGmuU|9IJw|I9+NlT8SZ%|-M!K2wduU|#i zYU9%Q-aH9A6g<{^N-C8sh6dw2A2nA1-nW6x>qZd>S0S)xKnS*H^%*<4)eA;$B`Po&6krA8-Yr~AbQ-z$tH^bGYn`Ns*LSt0 zYv4i>fmYEauk+=-9%?`NI0obP;`?qTaHH73I7UXYtF2@1{ZP?$Pqt&udD(j1LtifO z6@S^raXyf=F-I|jZHxwKg|q?M_ry$XFxANCQ>Vr&y+0I7h%2eR8i*hX^X~y>)ughHtvd#OtPwa|1F-R*7Gy=dJIhwtN2AYJL=C$!huA8lL*`I8C>Ul zLR6PtwdfuT%UE!3tpsUiipRNdcg^u+UDoFLNd2L6DIx$PP_Vq9vRwpfN|Ut1w9f4v5U`M>bDg%%E3 zgKbQ#9M@mffLz?Fo8F>J(%Bk(Vje(i1(j#xqyx-o2;4gm-ag668@_#yA%#o!`VY|h zJv08XZWcyRb=JCBtpA4rbV+6*lprUNaSjTydjGAGNro{_xcMQSRe9D|dh77*t4)to z6vGO(;K~=XT}tiFEMEx$DNbHvTjl0;iBBvTQ z(9f2t4mEO>{jIVG*+}9i)Z@X=lTQMpnL*W6*}8@HkuGyOTKb)@tas{ZVW>=YnX?8{ z1f$+g_*9ja6|7LXR4O!|%h(J~NudyU|RbYBCrG8Wx~6 z0~&Jv8N!SKxuU+s4Z921Hvgu^qws>A9r{gh?ersBM%=^Q2FfOOrdB;hdz}OfOzjkC z7|!`Q6OuX1dN4MnLFayt=5elx-270E7JPLPK%P_;%R?i|1Rnl_DpK-?%2vn(@@|3uLEzl zJXTdT%zVG;CUK|m&?*Q%rVKdLntK}F`Wb-LRZ*J~POhb#!vDAvBZkIuQ0xw5n&-XD z$iv2}sWm#1Tcf@=*I<6}6Yn~w{Q$|Ytf2t+nM{!rDF-T2c;OqSHR2?xkl$u{S8(37!-9Bip$CtU{y2q;RgbofAsiM#D&^ z)3@(0C@O)ZVDeEeB3*R8dC{=G-nv$!=rN_&6nt_3&Tr+Ojc!rhvsjv6rL(u? z7Co74Oh#zUQG9-~9j(P7=Qz`bjy>$VvEjEq)&Xv1?q|{c!F%MGVJF$4j?2CyEy!_& zjJfRQ79)B|o9GVzZ>ldCnBpYRtRY_pmTqay{iXWv|C{Rnw1wjYuB}^HxYosg`NnRD3`|w^r>x+tl*NbR)hoYkJ{4f&Mb6) zL%I2>-?EQy^6+@Aj+rG6gn-H^97bG#3;Qq+6?q&1B#R zaJ3*^s-C$)c!a4Pu{qnR&o#-e8!v0;yUd& zJ^`E0OB8$fG)%-pjN`P%7jaQ+4HnEGIGRRqT3h(9feNEZu3%OF2j8~KER$7_`wfi8 z9?^rwG2>Uw3FB4>^pMUV?^odZ9Zn24JByQd@IwtP~0W zSa3AhjF)r0yHEu9Ddx~mpNBTBshiocG9(UHu%|LssOK?&0#fB_>PC0+_<@pQ{sWga z0WY=;jk05)fXzRzwrlH}ocF5t*6Xl~iL_sjVHmSRO2RrTBX2+i6CAjR1~t+{VQ>J1 zp#wvpurMMhf(Z=yD<1i0cBDyDIMSpk{HNxBKEH_mYw3SofVn`mvE%h=o5Q0&p$0l8 Kmy3`t;r{}kg#=yz literal 0 HcmV?d00001 From a546b029b0bc84678fc9ffc2a276281cc156fa4b Mon Sep 17 00:00:00 2001 From: epriestley Date: Mon, 31 Jul 2017 09:40:29 -0700 Subject: [PATCH 05/16] Censor credentials possibly present in Git remote URIs when pulls fail because of a URI mismatch Summary: Fixes T12945. Test Plan: Mostly faked this, got a censored error: ``` $ ./bin/repository update R38 [2017-07-31 19:40:13] EXCEPTION: (Exception) Working copy at "/Users/epriestley/dev/core/repo/local/38/" has a mismatched origin URI, "https://********@example.com/". The expected origin URI is "https://github.com/phacility/libphutil.git". Fix your configuration, or set the remote URI correctly. To avoid breaking anything, Phabricator will not automatically fix this. at [/src/applications/repository/engine/PhabricatorRepositoryEngine.php:186] ``` Reviewers: chad Reviewed By: chad Maniphest Tasks: T12945 Differential Revision: https://secure.phabricator.com/D18304 --- .../repository/engine/PhabricatorRepositoryEngine.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/applications/repository/engine/PhabricatorRepositoryEngine.php b/src/applications/repository/engine/PhabricatorRepositoryEngine.php index 445357e783..244ed0cd45 100644 --- a/src/applications/repository/engine/PhabricatorRepositoryEngine.php +++ b/src/applications/repository/engine/PhabricatorRepositoryEngine.php @@ -135,6 +135,11 @@ abstract class PhabricatorRepositoryEngine extends Phobject { $exists = true; } + // These URIs may have plaintext HTTP credentials. If they do, censor + // them for display. See T12945. + $display_remote = phutil_censor_credentials($remote_uri); + $display_expect = phutil_censor_credentials($expect_remote); + if (!$valid) { if (!$exists) { // If there's no "origin" remote, just create it regardless of how @@ -172,8 +177,8 @@ abstract class PhabricatorRepositoryEngine extends Phobject { 'set the remote URI correctly. To avoid breaking anything, '. 'Phabricator will not automatically fix this.', $repository->getLocalPath(), - $remote_uri, - $expect_remote); + $display_remote, + $display_expect); throw new Exception($message); } } From f48f2dae9f39bccd61ea4868c6d5d95dc0ec68e0 Mon Sep 17 00:00:00 2001 From: epriestley Date: Mon, 31 Jul 2017 12:20:58 -0700 Subject: [PATCH 06/16] Move Phabricator to use PhutilBinaryAnalyzer and show binary versions Summary: Fixes T12942. - Adds binary version and path information to {nav Config > Version Information}. - Replaces old code all over the place with new consolidated code. Test Plan: {F5073531} Also faked some cases of missing binaries, bad versions, etc. Reviewers: chad Reviewed By: chad Maniphest Tasks: T12942 Differential Revision: https://secure.phabricator.com/D18306 --- src/__phutil_library_map__.php | 4 -- .../check/PhabricatorBinariesSetupCheck.php | 9 ++--- .../PhabricatorConfigVersionController.php | 23 +++++++++++ .../DiffusionLowLevelMercurialPathsQuery.php | 9 +++-- ...fusionLowLevelMercurialPathsQueryTests.php | 31 -------------- .../PhabricatorRepositoryVersion.php | 40 ------------------- .../PhabricatorRepositoryPullEngine.php | 6 +-- 7 files changed, 34 insertions(+), 88 deletions(-) delete mode 100644 src/applications/diffusion/query/lowlevel/__tests__/DiffusionLowLevelMercurialPathsQueryTests.php delete mode 100644 src/applications/repository/constants/PhabricatorRepositoryVersion.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 4488bacd9a..6427e95432 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -747,7 +747,6 @@ phutil_register_library_map(array( 'DiffusionLowLevelGitRefQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelGitRefQuery.php', 'DiffusionLowLevelMercurialBranchesQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelMercurialBranchesQuery.php', 'DiffusionLowLevelMercurialPathsQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelMercurialPathsQuery.php', - 'DiffusionLowLevelMercurialPathsQueryTests' => 'applications/diffusion/query/lowlevel/__tests__/DiffusionLowLevelMercurialPathsQueryTests.php', 'DiffusionLowLevelParentsQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelParentsQuery.php', 'DiffusionLowLevelQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelQuery.php', 'DiffusionLowLevelResolveRefsQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelResolveRefsQuery.php', @@ -3857,7 +3856,6 @@ phutil_register_library_map(array( 'PhabricatorRepositoryURITransaction' => 'applications/repository/storage/PhabricatorRepositoryURITransaction.php', 'PhabricatorRepositoryURITransactionQuery' => 'applications/repository/query/PhabricatorRepositoryURITransactionQuery.php', 'PhabricatorRepositoryVCSPassword' => 'applications/repository/storage/PhabricatorRepositoryVCSPassword.php', - 'PhabricatorRepositoryVersion' => 'applications/repository/constants/PhabricatorRepositoryVersion.php', 'PhabricatorRepositoryWorkingCopyVersion' => 'applications/repository/storage/PhabricatorRepositoryWorkingCopyVersion.php', 'PhabricatorRequestExceptionHandler' => 'aphront/handler/PhabricatorRequestExceptionHandler.php', 'PhabricatorResourceSite' => 'aphront/site/PhabricatorResourceSite.php', @@ -5741,7 +5739,6 @@ phutil_register_library_map(array( 'DiffusionLowLevelGitRefQuery' => 'DiffusionLowLevelQuery', 'DiffusionLowLevelMercurialBranchesQuery' => 'DiffusionLowLevelQuery', 'DiffusionLowLevelMercurialPathsQuery' => 'DiffusionLowLevelQuery', - 'DiffusionLowLevelMercurialPathsQueryTests' => 'PhabricatorTestCase', 'DiffusionLowLevelParentsQuery' => 'DiffusionLowLevelQuery', 'DiffusionLowLevelQuery' => 'Phobject', 'DiffusionLowLevelResolveRefsQuery' => 'DiffusionLowLevelQuery', @@ -9387,7 +9384,6 @@ phutil_register_library_map(array( 'PhabricatorRepositoryURITransaction' => 'PhabricatorApplicationTransaction', 'PhabricatorRepositoryURITransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhabricatorRepositoryVCSPassword' => 'PhabricatorRepositoryDAO', - 'PhabricatorRepositoryVersion' => 'Phobject', 'PhabricatorRepositoryWorkingCopyVersion' => 'PhabricatorRepositoryDAO', 'PhabricatorRequestExceptionHandler' => 'AphrontRequestExceptionHandler', 'PhabricatorResourceSite' => 'PhabricatorSite', diff --git a/src/applications/config/check/PhabricatorBinariesSetupCheck.php b/src/applications/config/check/PhabricatorBinariesSetupCheck.php index 0d577b5297..cf3c87f480 100644 --- a/src/applications/config/check/PhabricatorBinariesSetupCheck.php +++ b/src/applications/config/check/PhabricatorBinariesSetupCheck.php @@ -99,12 +99,12 @@ final class PhabricatorBinariesSetupCheck extends PhabricatorSetupCheck { continue; } - $version = null; + $version = PhutilBinaryAnalyzer::getForBinary($binary) + ->getBinaryVersion(); + switch ($vcs['versionControlSystem']) { case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: $bad_versions = array(); - list($err, $stdout, $stderr) = exec_manual('git --version'); - $version = trim(substr($stdout, strlen('git version '))); break; case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: $bad_versions = array( @@ -117,8 +117,6 @@ final class PhabricatorBinariesSetupCheck extends PhabricatorSetupCheck { 'for files added in rN (Subversion issue #2873), fixed in 1.7.2.', 'svn diff -c N'), ); - list($err, $stdout, $stderr) = exec_manual('svn --version --quiet'); - $version = trim($stdout); break; case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: $bad_versions = array( @@ -134,7 +132,6 @@ final class PhabricatorBinariesSetupCheck extends PhabricatorSetupCheck { 'in 2.2.1. Pushing fails with this version as well; see %s.', 'T3046#54922'), ); - $version = PhabricatorRepositoryVersion::getMercurialVersion(); break; } diff --git a/src/applications/config/controller/PhabricatorConfigVersionController.php b/src/applications/config/controller/PhabricatorConfigVersionController.php index 8f43192b3b..ca638051e4 100644 --- a/src/applications/config/controller/PhabricatorConfigVersionController.php +++ b/src/applications/config/controller/PhabricatorConfigVersionController.php @@ -64,6 +64,29 @@ final class PhabricatorConfigVersionController $version_from_file); } + $binaries = PhutilBinaryAnalyzer::getAllBinaries(); + foreach ($binaries as $binary) { + if (!$binary->isBinaryAvailable()) { + $binary_info = pht('Not Available'); + } else { + $version = $binary->getBinaryVersion(); + $path = $binary->getBinaryPath(); + if ($path === null && $version === null) { + $binary_info = pht('-'); + } else if ($path === null) { + $binary_info = $version; + } else if ($version === null) { + $binary_info = pht('- at %s', $path); + } else { + $binary_info = pht('%s at %s', $version, $path); + } + } + + $version_property_list->addProperty( + $binary->getBinaryName(), + $binary_info); + } + return $version_property_list; } diff --git a/src/applications/diffusion/query/lowlevel/DiffusionLowLevelMercurialPathsQuery.php b/src/applications/diffusion/query/lowlevel/DiffusionLowLevelMercurialPathsQuery.php index 12b9e661d7..f4e27db670 100644 --- a/src/applications/diffusion/query/lowlevel/DiffusionLowLevelMercurialPathsQuery.php +++ b/src/applications/diffusion/query/lowlevel/DiffusionLowLevelMercurialPathsQuery.php @@ -24,11 +24,12 @@ final class DiffusionLowLevelMercurialPathsQuery $path = $this->path; $commit = $this->commit; - $hg_paths_command = 'locate --print0 --rev %s -I %s'; - $hg_version = PhabricatorRepositoryVersion::getMercurialVersion(); - if (PhabricatorRepositoryVersion::isMercurialFilesCommandAvailable( - $hg_version)) { + $has_files = PhutilBinaryAnalyzer::getForBinary('hg') + ->isMercurialFilesCommandAvailable(); + if ($has_files) { $hg_paths_command = 'files --print0 --rev %s -I %s'; + } else { + $hg_paths_command = 'locate --print0 --rev %s -I %s'; } $match_against = trim($path, '/'); diff --git a/src/applications/diffusion/query/lowlevel/__tests__/DiffusionLowLevelMercurialPathsQueryTests.php b/src/applications/diffusion/query/lowlevel/__tests__/DiffusionLowLevelMercurialPathsQueryTests.php deleted file mode 100644 index 075ca2f1a5..0000000000 --- a/src/applications/diffusion/query/lowlevel/__tests__/DiffusionLowLevelMercurialPathsQueryTests.php +++ /dev/null @@ -1,31 +0,0 @@ - pht('Versions which should not use `files`'), - 'versions' => array('2.6.2', '2.9', '3.1'), - 'match' => false, - ), - - array( - 'name' => pht('Versions which should use `files`'), - 'versions' => array('3.2', '3.3', '3.5.2'), - 'match' => true, - ), - ); - - foreach ($cases as $case) { - foreach ($case['versions'] as $version) { - $actual = PhabricatorRepositoryVersion - ::isMercurialFilesCommandAvailable($version); - $expect = $case['match']; - $this->assertEqual($expect, $actual, $case['name']); - } - } - } - -} diff --git a/src/applications/repository/constants/PhabricatorRepositoryVersion.php b/src/applications/repository/constants/PhabricatorRepositoryVersion.php deleted file mode 100644 index 5f722fa40a..0000000000 --- a/src/applications/repository/constants/PhabricatorRepositoryVersion.php +++ /dev/null @@ -1,40 +0,0 @@ -='); - } - -} diff --git a/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php b/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php index b144ecfd96..32e99e619d 100644 --- a/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php +++ b/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php @@ -485,8 +485,8 @@ final class PhabricatorRepositoryPullEngine // On vulnerable versions of Mercurial, we refuse to clone remotes which // contain characters which may be interpreted by the shell. - $hg_version = PhabricatorRepositoryVersion::getMercurialVersion(); - $is_vulnerable = version_compare($hg_version, '3.2.4', '<'); + $hg_binary = PhutilBinaryAnalyzer::getForBinary('hg'); + $is_vulnerable = $hg_binary->isMercurialVulnerableToInjection(); if ($is_vulnerable) { $cleartext = $remote->openEnvelope(); // The use of "%R" here is an attempt to limit collateral damage @@ -501,7 +501,7 @@ final class PhabricatorRepositoryPullEngine 'command injection security vulnerability. The remote URI for '. 'this repository (%s) is potentially unsafe. Upgrade Mercurial '. 'to at least 3.2.4 to clone it.', - $hg_version, + $hg_binary->getBinaryVersion(), $repository->getMonogram())); } } From 3f158aa71b14d6d33515e75188b257437ac93eac Mon Sep 17 00:00:00 2001 From: Chad Little Date: Tue, 1 Aug 2017 07:54:18 -0700 Subject: [PATCH 07/16] More project v3 images Summary: These seem reasonably re-usable in the upstream. Test Plan: Edit Project Image Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D18312 --- resources/builtin/projects/v3/archive.png | Bin 0 -> 4491 bytes resources/builtin/projects/v3/discussion.png | Bin 0 -> 10059 bytes resources/builtin/projects/v3/download.png | Bin 0 -> 9392 bytes resources/builtin/projects/v3/library.png | Bin 0 -> 5783 bytes resources/builtin/projects/v3/police-badge.png | Bin 0 -> 12753 bytes .../builtin/projects/v3/purchase-order.png | Bin 0 -> 5189 bytes .../projects/v3/server-documentation.png | Bin 0 -> 5590 bytes resources/builtin/projects/v3/shield.png | Bin 0 -> 9232 bytes resources/builtin/projects/v3/upload.png | Bin 0 -> 9463 bytes resources/builtin/projects/v3/wand.png | Bin 0 -> 8717 bytes 10 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 resources/builtin/projects/v3/archive.png create mode 100644 resources/builtin/projects/v3/discussion.png create mode 100644 resources/builtin/projects/v3/download.png create mode 100644 resources/builtin/projects/v3/library.png create mode 100644 resources/builtin/projects/v3/police-badge.png create mode 100644 resources/builtin/projects/v3/purchase-order.png create mode 100644 resources/builtin/projects/v3/server-documentation.png create mode 100644 resources/builtin/projects/v3/shield.png create mode 100644 resources/builtin/projects/v3/upload.png create mode 100644 resources/builtin/projects/v3/wand.png diff --git a/resources/builtin/projects/v3/archive.png b/resources/builtin/projects/v3/archive.png new file mode 100644 index 0000000000000000000000000000000000000000..77ff79e555d1a4a842bec214719e568dca944988 GIT binary patch literal 4491 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 literal 0 HcmV?d00001 diff --git a/resources/builtin/projects/v3/download.png b/resources/builtin/projects/v3/download.png new file mode 100644 index 0000000000000000000000000000000000000000..f086222212e4fc0a043df574b32c93d6f4dead23 GIT binary patch literal 9392 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 ofd8k@!v8`CdLrusXU4q+KJpPQ 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 F`d`DLO*sGn literal 0 HcmV?d00001 diff --git a/resources/builtin/projects/v3/police-badge.png b/resources/builtin/projects/v3/police-badge.png new file mode 100644 index 0000000000000000000000000000000000000000..8b729bc35a63be9a369442ba34eae50894e38f50 GIT binary patch literal 12753 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 literal 0 HcmV?d00001 diff --git a/resources/builtin/projects/v3/purchase-order.png b/resources/builtin/projects/v3/purchase-order.png new file mode 100644 index 0000000000000000000000000000000000000000..906d72a5297c4a209d088c745f0d82ce190703d8 GIT binary patch literal 5189 zcmb7IdpOiv_eX<4Vk%QECrz%MnL#2Ue*lu9#CNYEHkDzhN{sqwTgW!j7os<>h z_FzE+6K%)6vpX+t`nJe`^k8>&DpmwR@Lde?rgwxpIQ>h0im-k!dTJDD+k5X?f9DCgT+0 zbEq=6=dhLG0$UL}Yh_XU#P$*~m)PLT39J?rw;>{S`b7jMO3?zw3-odK&^_)wnP zB%aU=NjI4Y525(htIE9U+9$nT;&*h}*$MTH&Ti9#2bWdSrqm#aeQPH@1d^z<*`}*6 z=zVmQ!SU+nWo`3k%UNIr9V*;lLnUhHiy)?4(X? z&PaMK1S*pV8u*>1S{N6(Xnh?!EgV1B?X~)a#1R@9&b!=tY9p=lL)MU5s(B|tY5utf zIJejG%I6k^QgheBRGM1rOOEu~sXmB>=^dgOJ`TM#c|;Rx(olI*eCf=WQ^IB6dzfj% zW9s-m6;uxP$WE;YvVO5#0!0(X2}F*lH^wV|6cJ|?{6trjTh(UOQGzwBRy3(0H4b%4AC4YZ? z|IE9}y4^ccu49vF@^?xmI~x=kOwniv;w&o!5yQ%hh|$I~#jqas{w?Kr{B+>ZpCt1V z*iZ1C{Ym0a{BK|a@csquJ>WmaWoWyJjcQ|`_=!5uIniJy^ZwE;1AFbPD=&o%hc_%I zzv8MNR#R?b>*uRRkEd&PSFQ%g8REg_3|0fDfyVG6dx4X<-_uvJFdU)RBTO9%yoM@C znE9~#Xb7&JGdC3n&Wg``^6M|ZC^A%qm)wJQ3E^D=98i*eHJT=uE@>&KLY|-5#;IK# zs#c5&ZBEDq)~$2ork(+3HW*Av=}vz8V#fE>X2V(p2AoZw1d4m>A>R8oA+M8Cu zO+XBAUXK&F8dtASa)EZTT*?p?xVgU8U{Oq<8PF;1*{coUNg z+s*yBHv_$n04sZJM<&H8mFJ874X*C*JUlgQ2agRzuFhCV7Fp{_#VZvTzm)PAqM&Y6 zgtrC=vTg$uP^K`)P@N9Aa&XwIDnEhsGjyym@rIiJA9Da8Wx4+k^L~czEUH81KX{1T ztNf#>=SSB-EJfy({|jA!RASWah_wLwzN+wbt!k_vMjW*$f)XgNTiK5_s&bUWZ3!MSQvZCgfpV~yH&7>|KJzpgfR%}~!A z&P1VCO`2M)nsr3z{A-qqvY`!W2dty=Jcjr5Uq-q&);~U!kDTV|tdMr|cnocn#U75x zLx;m%lx|hrtd&!gJ&d;gkoI@7t*`A|H~2bt=7hL2Fa~wbzT4(`WfZt+B6eo0TLwTC z#PvWS6m!*e&cJ!EVfHQIE)kdy2F^o&&l>%p074{_Hxd2t&+4T=?OXv zJWzH5pMz8|maR>`u2@@EaoiYx6_1`wPPUaTZ0)g(7Bb{3WoH3(seuQVi+pJakMw*W z=H0c6cADx1LY|&E3c4B-X}E;2XIyhn^D9R*@h!S|w(@-FCK2xySUlb;^O;r}y@tKy zArmp>VlPixJw_r3(asq{-zyAuY&W%V40@x}{2Yq|tQb4yap=%kH0@I&5FykCzI76E zsHuS)G#U@6OAu5cTAF`$vf-x2GmT&Mjl!k%0yt&qgZm zt`yU|G=6zv-WT7lvFf?yNraHUA1efR?u^oFN`tH~&3`f~IVRuUWag;dxOiUzHE|Z@ z7N!Kwj92k0pP^tO7P0ae{DrFPPs#WHfZ&XGzR}4~w&;S${i-~|aVVu#6F-5yuXmTM zF^}r7w_9Y)>eJRRK^uBBCnd(@o#TjNa{pOmz3(N9mm>F`!vT*F(we^&oOsKRTkno} z@yRM&M@aaP`8A7cvE#(cpX=6eh#xwNVDoI%%r(+tL|(5Ie63<|?ns}okK5z>c%J#X zH%7tkHx@u%N;cm_Q9Td@FXDsWxVtopT@c{RIh0-sWU%X%0AQ#^8!uyle>Wi!M_dJ_ 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 literal 0 HcmV?d00001 diff --git a/resources/builtin/projects/v3/shield.png b/resources/builtin/projects/v3/shield.png new file mode 100644 index 0000000000000000000000000000000000000000..fd938307fd65a1c4eaa66f3bd6c894960466a1ad GIT binary patch literal 9232 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 S?|b{UlBSxTYK^jO#Qy^6uDKHc literal 0 HcmV?d00001 diff --git a/resources/builtin/projects/v3/wand.png b/resources/builtin/projects/v3/wand.png new file mode 100644 index 0000000000000000000000000000000000000000..6de1cb55ab2f71a4cd7b3b43a8d5f45c3e8dd1ab GIT binary patch literal 8717 zcmaJ{c|4R~)R%4S#?EAotYa%%_BFdA#@L7X$zBoJ3uE6STe4&;W-w!mtYe#yM8=Zr zM2JRNLV6#)f4}d1KJ$F;bC+|@J?Gqe&-vab>9&O-BOQc}jEs!Y*ht@sjO-Hh;!i^j z)PzQ+2a%BpO&aU#SchEN!AApiWaOpGAQwceq~pcQ|M?5tnGX)Mp6=WvNqfIrcYZOL z9R9>&Z(x0y{Z*^%M&;9B+s~$rCDNbN%7iCbXpGCpQ}q@3{_CM;C~G~ssW>n{$z8}@ z2xjO$a#}rTdWJgm%($C=H}LBb!9)7X-J266+l`&Zv4vomb9~w{xPCcLPN&M6aJE## z<{Yc=kj^D)NW{boYb{_zFNtW#+KRuwbcHc@SivTfbH~slA5+#9J1q!?YTGixL~j@Q z)42KbnZYb?>8hVs;fE==#4=U9T^r(0u2oQF_+YO^C+n`L#MH^z>6pjB9n0`0Vnn_@ zU3-5vGuZ8LAY&FnJUhch|28e%>F<4!+Kt8OT{&Db0-xsuH!kxpHo#2uBx`hu^FKh@<7=a{Cf1(%0A^2t-Weq6oc}G-}ZuL@@Snw~X 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 literal 0 HcmV?d00001 From 03423c632c5acb9a41042eadfe5bdb3ade3306ea Mon Sep 17 00:00:00 2001 From: epriestley Date: Mon, 31 Jul 2017 13:21:58 -0700 Subject: [PATCH 08/16] Treat commit hook execution in observed repositories as a no-op, not an error Summary: See PHI24. If you create a hosted Mercurial repository and switch it to observed, you can end up with a hook installed that runs on pulls and complains. Instead, just bail out if we're running on a pull. The corresponding Git hook doesn't run on pulls, so there's no issue in Git. Test Plan: Executed the hook in an observed Mercurial repository, got a clean exit. Reviewers: chad Reviewed By: chad Differential Revision: https://secure.phabricator.com/D18307 --- scripts/repository/commit_hook.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/scripts/repository/commit_hook.php b/scripts/repository/commit_hook.php index 44c772225c..51abcb6c89 100755 --- a/scripts/repository/commit_hook.php +++ b/scripts/repository/commit_hook.php @@ -48,8 +48,13 @@ if (!$repository) { } if (!$repository->isHosted()) { - // This should be redundant, but double check just in case. - throw new Exception(pht('Repository "%s" is not hosted!', $argv[1])); + // In Mercurial, the "pretxnchangegroup" hook fires for both pulls and + // pushes. Normally we only install the hook for hosted repositories, but + // if a hosted repository is later converted into an observed repository we + // can end up with an observed repository that has the hook installed. + // If we're running hooks from an observed repository, just exit without + // taking action. For more discussion, see PHI24. + return 0; } $engine->setRepository($repository); From ab018e1b49d52025c69aa359061fd3f34f417eda Mon Sep 17 00:00:00 2001 From: epriestley Date: Tue, 1 Aug 2017 08:48:39 -0700 Subject: [PATCH 09/16] When destorying a repository, print a notification about removing the working copy Summary: Fixes T12946. `bin/remove destroy` does not remove working copies: it's more dangerous than usual, and we can't do it in the general (clustered) case. Print a notification message after destroying a repository. Test Plan: - Destroyed a repository, got a hint about the working copy. - Destroyed a task, things worked normally. Reviewers: chad Reviewed By: chad Maniphest Tasks: T12946 Differential Revision: https://secure.phabricator.com/D18313 --- src/__phutil_library_map__.php | 6 ++ ...PhabricatorRepositoryDestructibleCodex.php | 23 +++++++ .../storage/PhabricatorRepository.php | 9 +++ .../codex/PhabricatorDestructibleCodex.php | 66 +++++++++++++++++++ .../engine/PhabricatorDestructionEngine.php | 23 +++++++ .../PhabricatorDestructibleCodexInterface.php | 18 +++++ ...PhabricatorSystemRemoveDestroyWorkflow.php | 17 ++++- 7 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 src/applications/repository/codex/PhabricatorRepositoryDestructibleCodex.php create mode 100644 src/applications/system/codex/PhabricatorDestructibleCodex.php create mode 100644 src/applications/system/interface/PhabricatorDestructibleCodexInterface.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 6427e95432..afaccaacf9 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -2642,6 +2642,8 @@ phutil_register_library_map(array( 'PhabricatorDefaultSyntaxStyle' => 'infrastructure/syntax/PhabricatorDefaultSyntaxStyle.php', 'PhabricatorDesktopNotificationsSetting' => 'applications/settings/setting/PhabricatorDesktopNotificationsSetting.php', 'PhabricatorDesktopNotificationsSettingsPanel' => 'applications/settings/panel/PhabricatorDesktopNotificationsSettingsPanel.php', + 'PhabricatorDestructibleCodex' => 'applications/system/codex/PhabricatorDestructibleCodex.php', + 'PhabricatorDestructibleCodexInterface' => 'applications/system/interface/PhabricatorDestructibleCodexInterface.php', 'PhabricatorDestructibleInterface' => 'applications/system/interface/PhabricatorDestructibleInterface.php', 'PhabricatorDestructionEngine' => 'applications/system/engine/PhabricatorDestructionEngine.php', 'PhabricatorDestructionEngineExtension' => 'applications/system/engine/PhabricatorDestructionEngineExtension.php', @@ -3780,6 +3782,7 @@ phutil_register_library_map(array( 'PhabricatorRepositoryCommitTestCase' => 'applications/repository/storage/__tests__/PhabricatorRepositoryCommitTestCase.php', 'PhabricatorRepositoryConfigOptions' => 'applications/repository/config/PhabricatorRepositoryConfigOptions.php', 'PhabricatorRepositoryDAO' => 'applications/repository/storage/PhabricatorRepositoryDAO.php', + 'PhabricatorRepositoryDestructibleCodex' => 'applications/repository/codex/PhabricatorRepositoryDestructibleCodex.php', 'PhabricatorRepositoryDiscoveryEngine' => 'applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php', 'PhabricatorRepositoryEditor' => 'applications/repository/editor/PhabricatorRepositoryEditor.php', 'PhabricatorRepositoryEngine' => 'applications/repository/engine/PhabricatorRepositoryEngine.php', @@ -7937,6 +7940,7 @@ phutil_register_library_map(array( 'PhabricatorDefaultSyntaxStyle' => 'PhabricatorSyntaxStyle', 'PhabricatorDesktopNotificationsSetting' => 'PhabricatorInternalSetting', 'PhabricatorDesktopNotificationsSettingsPanel' => 'PhabricatorSettingsPanel', + 'PhabricatorDestructibleCodex' => 'Phobject', 'PhabricatorDestructionEngine' => 'Phobject', 'PhabricatorDestructionEngineExtension' => 'Phobject', 'PhabricatorDestructionEngineExtensionModule' => 'PhabricatorConfigModule', @@ -9241,6 +9245,7 @@ phutil_register_library_map(array( 'PhabricatorFlaggableInterface', 'PhabricatorMarkupInterface', 'PhabricatorDestructibleInterface', + 'PhabricatorDestructibleCodexInterface', 'PhabricatorProjectInterface', 'PhabricatorSpacesInterface', 'PhabricatorConduitResultInterface', @@ -9283,6 +9288,7 @@ phutil_register_library_map(array( 'PhabricatorRepositoryCommitTestCase' => 'PhabricatorTestCase', 'PhabricatorRepositoryConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorRepositoryDAO' => 'PhabricatorLiskDAO', + 'PhabricatorRepositoryDestructibleCodex' => 'PhabricatorDestructibleCodex', 'PhabricatorRepositoryDiscoveryEngine' => 'PhabricatorRepositoryEngine', 'PhabricatorRepositoryEditor' => 'PhabricatorApplicationTransactionEditor', 'PhabricatorRepositoryEngine' => 'Phobject', diff --git a/src/applications/repository/codex/PhabricatorRepositoryDestructibleCodex.php b/src/applications/repository/codex/PhabricatorRepositoryDestructibleCodex.php new file mode 100644 index 0000000000..eaa5cf4a77 --- /dev/null +++ b/src/applications/repository/codex/PhabricatorRepositoryDestructibleCodex.php @@ -0,0 +1,23 @@ +getObject(); + + $notes = array(); + + if ($repository->hasLocalWorkingCopy()) { + $notes[] = pht( + 'Database records for repository "%s" were destroyed, but this '. + 'script does not remove working copies on disk. If you also want to '. + 'destroy the repository working copy, manually remove "%s".', + $repository->getDisplayName(), + $repository->getLocalPath()); + } + + return $notes; + } + +} diff --git a/src/applications/repository/storage/PhabricatorRepository.php b/src/applications/repository/storage/PhabricatorRepository.php index eb6608eb57..b660ff9aa7 100644 --- a/src/applications/repository/storage/PhabricatorRepository.php +++ b/src/applications/repository/storage/PhabricatorRepository.php @@ -12,6 +12,7 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO PhabricatorFlaggableInterface, PhabricatorMarkupInterface, PhabricatorDestructibleInterface, + PhabricatorDestructibleCodexInterface, PhabricatorProjectInterface, PhabricatorSpacesInterface, PhabricatorConduitResultInterface, @@ -2557,6 +2558,14 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO } +/* -( PhabricatorDestructibleCodexInterface )------------------------------ */ + + + public function newDestructibleCodex() { + return new PhabricatorRepositoryDestructibleCodex(); + } + + /* -( PhabricatorSpacesInterface )----------------------------------------- */ diff --git a/src/applications/system/codex/PhabricatorDestructibleCodex.php b/src/applications/system/codex/PhabricatorDestructibleCodex.php new file mode 100644 index 0000000000..1c37907c34 --- /dev/null +++ b/src/applications/system/codex/PhabricatorDestructibleCodex.php @@ -0,0 +1,66 @@ +viewer = $viewer; + return $this; + } + + final public function getViewer() { + return $this->viewer; + } + + final public function setObject( + PhabricatorDestructibleCodexInterface $object) { + $this->object = $object; + return $this; + } + + final public function getObject() { + return $this->object; + } + + final public static function newFromObject( + PhabricatorDestructibleCodexInterface $object, + PhabricatorUser $viewer) { + + if (!($object instanceof PhabricatorDestructibleInterface)) { + throw new Exception( + pht( + 'Object (of class "%s") implements interface "%s", but must also '. + 'implement interface "%s".', + get_class($object), + 'PhabricatorDestructibleCodexInterface', + 'PhabricatorDestructibleInterface')); + } + + $codex = $object->newDestructibleCodex(); + if (!($codex instanceof PhabricatorDestructibleCodex)) { + throw new Exception( + pht( + 'Object (of class "%s") implements interface "%s", but defines '. + 'method "%s" incorrectly: this method must return an object of '. + 'class "%s".', + get_class($object), + 'PhabricatorDestructibleCodexInterface', + 'newDestructibleCodex()', + __CLASS__)); + } + + $codex + ->setObject($object) + ->setViewer($viewer); + + return $codex; + } + +} diff --git a/src/applications/system/engine/PhabricatorDestructionEngine.php b/src/applications/system/engine/PhabricatorDestructionEngine.php index f8e5be2ccc..336df57756 100644 --- a/src/applications/system/engine/PhabricatorDestructionEngine.php +++ b/src/applications/system/engine/PhabricatorDestructionEngine.php @@ -3,6 +3,17 @@ final class PhabricatorDestructionEngine extends Phobject { private $rootLogID; + private $collectNotes; + private $notes = array(); + + public function setCollectNotes($collect_notes) { + $this->collectNotes = $collect_notes; + return $this; + } + + public function getNotes() { + return $this->notes; + } public function getViewer() { return PhabricatorUser::getOmnipotentUser(); @@ -36,6 +47,18 @@ final class PhabricatorDestructionEngine extends Phobject { $this->rootLogID = $log->getID(); } + if ($this->collectNotes) { + if ($object instanceof PhabricatorDestructibleCodexInterface) { + $codex = PhabricatorDestructibleCodex::newFromObject( + $object, + $this->getViewer()); + + foreach ($codex->getDestructionNotes() as $note) { + $this->notes[] = $note; + } + } + } + $object->destroyObjectPermanently($this); if ($object_phid) { diff --git a/src/applications/system/interface/PhabricatorDestructibleCodexInterface.php b/src/applications/system/interface/PhabricatorDestructibleCodexInterface.php new file mode 100644 index 0000000000..3725990ee6 --- /dev/null +++ b/src/applications/system/interface/PhabricatorDestructibleCodexInterface.php @@ -0,0 +1,18 @@ +>DestructibleCodex(); + } + +*/ diff --git a/src/applications/system/management/PhabricatorSystemRemoveDestroyWorkflow.php b/src/applications/system/management/PhabricatorSystemRemoveDestroyWorkflow.php index 4e9d745540..bd6b4e361a 100644 --- a/src/applications/system/management/PhabricatorSystemRemoveDestroyWorkflow.php +++ b/src/applications/system/management/PhabricatorSystemRemoveDestroyWorkflow.php @@ -145,6 +145,7 @@ EOBANNER; $console->writeOut("%s\n", pht('Destroying objects...')); + $notes = array(); foreach ($named_objects as $object_name => $object) { $console->writeOut( pht( @@ -152,8 +153,14 @@ EOBANNER; get_class($object), $object_name)); - id(new PhabricatorDestructionEngine()) - ->destroyObject($object); + $engine = id(new PhabricatorDestructionEngine()) + ->setCollectNotes(true); + + $engine->destroyObject($object); + + foreach ($engine->getNotes() as $note) { + $notes[] = $note; + } } $console->writeOut( @@ -162,6 +169,12 @@ EOBANNER; 'Permanently destroyed %s object(s).', phutil_count($named_objects))); + if ($notes) { + id(new PhutilConsoleList()) + ->addItems($notes) + ->draw(); + } + return 0; } From ba4b936dffce095f884f56588fb6841ceebd9cd8 Mon Sep 17 00:00:00 2001 From: Chad Little Date: Wed, 2 Aug 2017 12:26:40 -0700 Subject: [PATCH 10/16] Use Log In vs. Login when it's a verb Summary: Cursory research indicates that "login" is a noun, referring to a form, and "log in" is a verb, referring to the action of logging in. I went though every instances of 'login' I could find and tried to clarify all this language. Also, we have "Phabricator" on the registration for like 4-5 times, which is a bit verbose, so I tried to simplify that language as well. Test Plan: Tested logging in and logging out. Pages feel simpler. Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D18322 --- .../PhabricatorAuthFinishController.php | 2 +- .../PhabricatorAuthLoginController.php | 15 +++++++-------- .../PhabricatorAuthOneTimeLoginController.php | 6 +++--- .../PhabricatorAuthRegisterController.php | 8 ++++---- .../PhabricatorAuthStartController.php | 6 +++--- .../PhabricatorAuthUnlinkController.php | 2 +- .../PhabricatorEmailLoginController.php | 2 +- .../controller/PhabricatorLogoutController.php | 4 ++-- .../PhabricatorMustVerifyEmailController.php | 2 +- .../auth/provider/PhabricatorAuthProvider.php | 6 +++--- .../provider/PhabricatorLDAPAuthProvider.php | 18 +++++++++--------- .../PhabricatorPasswordAuthProvider.php | 6 +++--- .../controller/ConpherenceViewController.php | 2 +- .../PhabricatorFileLightboxController.php | 2 +- .../PhabricatorOAuthServerApplication.php | 2 +- .../ponder/view/PonderAddAnswerView.php | 2 +- ...icatorApplicationTransactionCommentView.php | 2 +- .../uiexample/examples/PHUIButtonExample.php | 2 +- 18 files changed, 44 insertions(+), 45 deletions(-) diff --git a/src/applications/auth/controller/PhabricatorAuthFinishController.php b/src/applications/auth/controller/PhabricatorAuthFinishController.php index 387679b44e..4b775a2e4b 100644 --- a/src/applications/auth/controller/PhabricatorAuthFinishController.php +++ b/src/applications/auth/controller/PhabricatorAuthFinishController.php @@ -54,7 +54,7 @@ final class PhabricatorAuthFinishController ->addHiddenInput(AphrontRequest::TYPE_HISEC, true) ->appendParagraph( pht( - 'Welcome, %s. To complete the login process, provide your '. + 'Welcome, %s. To complete the process of logging in, provide your '. 'multi-factor credentials.', phutil_tag('strong', array(), $viewer->getUsername()))) ->appendChild($form->buildLayoutView()) diff --git a/src/applications/auth/controller/PhabricatorAuthLoginController.php b/src/applications/auth/controller/PhabricatorAuthLoginController.php index 3264e61216..39b6318481 100644 --- a/src/applications/auth/controller/PhabricatorAuthLoginController.php +++ b/src/applications/auth/controller/PhabricatorAuthLoginController.php @@ -92,8 +92,8 @@ final class PhabricatorAuthLoginController } else { return $this->renderError( pht( - 'The external account ("%s") you just used to login is already '. - 'associated with another Phabricator user account. Login to the '. + 'The external account ("%s") you just used to log in is already '. + 'associated with another Phabricator user account. Log in to the '. 'other Phabricator account and unlink the external account before '. 'linking it to a new Phabricator account.', $provider->getProviderName())); @@ -214,7 +214,7 @@ final class PhabricatorAuthLoginController if (!$provider) { return $this->renderError( pht( - 'The account you are attempting to login with uses a nonexistent '. + 'The account you are attempting to log in with uses a nonexistent '. 'or disabled authentication provider (with key "%s"). An '. 'administrator may have recently disabled this provider.', $this->providerKey)); @@ -240,14 +240,14 @@ final class PhabricatorAuthLoginController if ($this->getRequest()->getUser()->isLoggedIn()) { $crumbs->addTextCrumb(pht('Link Account'), $provider->getSettingsURI()); } else { - $crumbs->addTextCrumb(pht('Login'), $this->getApplicationURI('start/')); + $crumbs->addTextCrumb(pht('Log In'), $this->getApplicationURI('start/')); } $crumbs->addTextCrumb($provider->getProviderName()); $crumbs->setBorder(true); return $this->newPage() - ->setTitle(pht('Login')) + ->setTitle(pht('Log In')) ->setCrumbs($crumbs) ->appendChild($content); } @@ -257,9 +257,8 @@ final class PhabricatorAuthLoginController $message) { $message = pht( - 'Authentication provider ("%s") encountered an error during login. %s', - $provider->getProviderName(), - $message); + 'Authentication provider ("%s") encountered an error while attempting '. + 'to log in. %s', $provider->getProviderName(), $message); return $this->renderError($message); } diff --git a/src/applications/auth/controller/PhabricatorAuthOneTimeLoginController.php b/src/applications/auth/controller/PhabricatorAuthOneTimeLoginController.php index ebfd07e7ac..534bda3f35 100644 --- a/src/applications/auth/controller/PhabricatorAuthOneTimeLoginController.php +++ b/src/applications/auth/controller/PhabricatorAuthOneTimeLoginController.php @@ -68,7 +68,7 @@ final class PhabricatorAuthOneTimeLoginController if (!$token) { return $this->newDialog() - ->setTitle(pht('Unable to Login')) + ->setTitle(pht('Unable to Log In')) ->setShortTitle(pht('Login Failure')) ->appendParagraph( pht( @@ -170,7 +170,7 @@ final class PhabricatorAuthOneTimeLoginController case PhabricatorAuthSessionEngine::ONETIME_USERNAME: case PhabricatorAuthSessionEngine::ONETIME_RESET: default: - $title = pht('Login to Phabricator'); + $title = pht('Log in to Phabricator'); break; } @@ -193,7 +193,7 @@ final class PhabricatorAuthOneTimeLoginController $dialog = $this->newDialog() ->setTitle($title) - ->addSubmitButton(pht('Login (%s)', $target_user->getUsername())) + ->addSubmitButton(pht('Log In (%s)', $target_user->getUsername())) ->addCancelButton('/'); foreach ($body as $paragraph) { diff --git a/src/applications/auth/controller/PhabricatorAuthRegisterController.php b/src/applications/auth/controller/PhabricatorAuthRegisterController.php index cdb7980a16..a68e12c801 100644 --- a/src/applications/auth/controller/PhabricatorAuthRegisterController.php +++ b/src/applications/auth/controller/PhabricatorAuthRegisterController.php @@ -483,14 +483,14 @@ final class PhabricatorAuthRegisterController if ($can_edit_username) { $form->appendChild( id(new AphrontFormTextControl()) - ->setLabel(pht('Phabricator Username')) + ->setLabel(pht('Username')) ->setName('username') ->setValue($value_username) ->setError($e_username)); } else { $form->appendChild( id(new AphrontFormMarkupControl()) - ->setLabel(pht('Phabricator Username')) + ->setLabel(pht('Username')) ->setValue($value_username) ->setError($e_username)); } @@ -546,7 +546,7 @@ final class PhabricatorAuthRegisterController } else { $submit ->addCancelButton($this->getApplicationURI('start/')) - ->setValue(pht('Register Phabricator Account')); + ->setValue(pht('Register Account')); } @@ -560,7 +560,7 @@ final class PhabricatorAuthRegisterController } else { $crumbs->addTextCrumb(pht('Register')); $crumbs->addTextCrumb($provider->getProviderName()); - $title = pht('Phabricator Registration'); + $title = pht('Create a New Account'); } $crumbs->setBorder(true); diff --git a/src/applications/auth/controller/PhabricatorAuthStartController.php b/src/applications/auth/controller/PhabricatorAuthStartController.php index 5cfcb9b9ef..9af8f25bc7 100644 --- a/src/applications/auth/controller/PhabricatorAuthStartController.php +++ b/src/applications/auth/controller/PhabricatorAuthStartController.php @@ -198,7 +198,7 @@ final class PhabricatorAuthStartController $crumbs->addTextCrumb(pht('Login')); $crumbs->setBorder(true); - $title = pht('Login to Phabricator'); + $title = pht('Login'); $view = array( $header, $invite_message, @@ -239,8 +239,8 @@ final class PhabricatorAuthStartController return $this->newDialog() ->setTitle(pht('Login Required')) - ->appendParagraph(pht('You must login to take this action.')) - ->addSubmitButton(pht('Login')) + ->appendParagraph(pht('You must log in to take this action.')) + ->addSubmitButton(pht('Log In')) ->addCancelButton('/'); } diff --git a/src/applications/auth/controller/PhabricatorAuthUnlinkController.php b/src/applications/auth/controller/PhabricatorAuthUnlinkController.php index 2c21f63407..6211e78110 100644 --- a/src/applications/auth/controller/PhabricatorAuthUnlinkController.php +++ b/src/applications/auth/controller/PhabricatorAuthUnlinkController.php @@ -104,7 +104,7 @@ final class PhabricatorAuthUnlinkController pht( 'You can not unlink this account because you have no other '. 'valid login accounts. If you removed it, you would be unable '. - 'to login. Add another authentication method before removing '. + 'to log in. Add another authentication method before removing '. 'this one.')) ->addCancelButton($this->getDoneURI()); diff --git a/src/applications/auth/controller/PhabricatorEmailLoginController.php b/src/applications/auth/controller/PhabricatorEmailLoginController.php index e9cf693514..92accc7494 100644 --- a/src/applications/auth/controller/PhabricatorEmailLoginController.php +++ b/src/applications/auth/controller/PhabricatorEmailLoginController.php @@ -114,7 +114,7 @@ final class PhabricatorEmailLoginController ->setTitle(pht('Check Your Email')) ->setShortTitle(pht('Email Sent')) ->appendParagraph( - pht('An email has been sent with a link you can use to login.')) + pht('An email has been sent with a link you can use to log in.')) ->addCancelButton('/', pht('Done')); } } diff --git a/src/applications/auth/controller/PhabricatorLogoutController.php b/src/applications/auth/controller/PhabricatorLogoutController.php index f4b61f88a3..47592e0a2d 100644 --- a/src/applications/auth/controller/PhabricatorLogoutController.php +++ b/src/applications/auth/controller/PhabricatorLogoutController.php @@ -52,9 +52,9 @@ final class PhabricatorLogoutController if ($viewer->getPHID()) { return $this->newDialog() - ->setTitle(pht('Log out of Phabricator?')) + ->setTitle(pht('Log Out?')) ->appendChild(pht('Are you sure you want to log out?')) - ->addSubmitButton(pht('Logout')) + ->addSubmitButton(pht('Log Out')) ->addCancelButton('/'); } diff --git a/src/applications/auth/controller/PhabricatorMustVerifyEmailController.php b/src/applications/auth/controller/PhabricatorMustVerifyEmailController.php index 670a95f977..bf3410139d 100644 --- a/src/applications/auth/controller/PhabricatorMustVerifyEmailController.php +++ b/src/applications/auth/controller/PhabricatorMustVerifyEmailController.php @@ -33,7 +33,7 @@ final class PhabricatorMustVerifyEmailController } $must_verify = pht( - 'You must verify your email address to login. You should have a '. + 'You must verify your email address to log in. You should have a '. 'new email message from Phabricator with verification instructions '. 'in your inbox (%s).', phutil_tag('strong', array(), $email_address)); diff --git a/src/applications/auth/provider/PhabricatorAuthProvider.php b/src/applications/auth/provider/PhabricatorAuthProvider.php index 4dd7f4da1b..d655efd790 100644 --- a/src/applications/auth/provider/PhabricatorAuthProvider.php +++ b/src/applications/auth/provider/PhabricatorAuthProvider.php @@ -389,7 +389,7 @@ abstract class PhabricatorAuthProvider extends Phobject { * @param AphrontRequest HTTP request. * @param string Request mode string. * @param map Additional parameters, see above. - * @return wild Login button. + * @return wild Log in button. */ protected function renderStandardLoginButton( AphrontRequest $request, @@ -414,9 +414,9 @@ abstract class PhabricatorAuthProvider extends Phobject { } else if ($mode == 'invite') { $button_text = pht('Register Account'); } else if ($this->shouldAllowRegistration()) { - $button_text = pht('Login or Register'); + $button_text = pht('Log In or Register'); } else { - $button_text = pht('Login'); + $button_text = pht('Log In'); } $icon = id(new PHUIIconView()) diff --git a/src/applications/auth/provider/PhabricatorLDAPAuthProvider.php b/src/applications/auth/provider/PhabricatorLDAPAuthProvider.php index 013cd21736..7c2bf38618 100644 --- a/src/applications/auth/provider/PhabricatorLDAPAuthProvider.php +++ b/src/applications/auth/provider/PhabricatorLDAPAuthProvider.php @@ -80,11 +80,11 @@ final class PhabricatorLDAPAuthProvider extends PhabricatorAuthProvider { $dialog->addCancelButton($this->getSettingsURI()); } else { if ($this->shouldAllowRegistration()) { - $dialog->setTitle(pht('Login or Register with LDAP')); - $dialog->addSubmitButton(pht('Login or Register')); + $dialog->setTitle(pht('Log In or Register with LDAP')); + $dialog->addSubmitButton(pht('Log In or Register')); } else { - $dialog->setTitle(pht('Login with LDAP')); - $dialog->addSubmitButton(pht('Login')); + $dialog->setTitle(pht('Log In with LDAP')); + $dialog->addSubmitButton(pht('Log In')); } if ($mode == 'login') { $dialog->addCancelButton($this->getStartURI()); @@ -315,7 +315,7 @@ final class PhabricatorLDAPAuthProvider extends PhabricatorAuthProvider { "credentials (which is more complicated, but more powerful).\n\n". "For many installs, direct binding is sufficient. However, you may ". "want to search first if:\n\n". - " - You want users to be able to login with either their username ". + " - You want users to be able to log in with either their username ". " or their email address.\n". " - The login/username is not part of the distinguished name in ". " your LDAP records.\n". @@ -344,16 +344,16 @@ final class PhabricatorLDAPAuthProvider extends PhabricatorAuthProvider { "`sn`, which will work the same way direct binding works:\n\n". " lang=text,name=Simple Example\n". " sn\n\n". - "A slightly more complex configuration might let the user login with ". + "A slightly more complex configuration might let the user log in with ". "either their login name or email address:\n\n". " lang=text,name=Match Several Attributes\n". " mail\n". " sn\n\n". "If your LDAP directory is more complex, or you want to perform ". "sophisticated filtering, you can use more complex queries. Depending ". - "on your directory structure, this example might allow users to login ". - "with either their email address or username, but only if they're in ". - "specific departments:\n\n". + "on your directory structure, this example might allow users to log ". + "in with either their email address or username, but only if they're ". + "in specific departments:\n\n". " lang=text,name=Complex Example\n". " (&(mail=\${login})(|(departmentNumber=1)(departmentNumber=2)))\n". " (&(sn=\${login})(|(departmentNumber=1)(departmentNumber=2)))\n\n". diff --git a/src/applications/auth/provider/PhabricatorPasswordAuthProvider.php b/src/applications/auth/provider/PhabricatorPasswordAuthProvider.php index 68dbf1e879..206eba4578 100644 --- a/src/applications/auth/provider/PhabricatorPasswordAuthProvider.php +++ b/src/applications/auth/provider/PhabricatorPasswordAuthProvider.php @@ -100,7 +100,7 @@ final class PhabricatorPasswordAuthProvider extends PhabricatorAuthProvider { public function getDescriptionForCreate() { return pht( - 'Allow users to login or register using a username and password.'); + 'Allow users to log in or register using a username and password.'); } public function getAdapter() { @@ -174,8 +174,8 @@ final class PhabricatorPasswordAuthProvider extends PhabricatorAuthProvider { $dialog = id(new AphrontDialogView()) ->setSubmitURI($this->getLoginURI()) ->setUser($viewer) - ->setTitle(pht('Login to Phabricator')) - ->addSubmitButton(pht('Login')); + ->setTitle(pht('Log In')) + ->addSubmitButton(pht('Log In')); if ($this->shouldAllowRegistration()) { $dialog->addCancelButton( diff --git a/src/applications/conpherence/controller/ConpherenceViewController.php b/src/applications/conpherence/controller/ConpherenceViewController.php index 792a7f8182..996417a307 100644 --- a/src/applications/conpherence/controller/ConpherenceViewController.php +++ b/src/applications/conpherence/controller/ConpherenceViewController.php @@ -195,7 +195,7 @@ final class ConpherenceViewController extends ->appendChild( id(new PHUIButtonView()) ->setTag('a') - ->setText(pht('Login to Participate')) + ->setText(pht('Log In to Participate')) ->setHref((string)$login_href)); } } diff --git a/src/applications/files/controller/PhabricatorFileLightboxController.php b/src/applications/files/controller/PhabricatorFileLightboxController.php index 11d4b95bc1..1f679d621b 100644 --- a/src/applications/files/controller/PhabricatorFileLightboxController.php +++ b/src/applications/files/controller/PhabricatorFileLightboxController.php @@ -76,7 +76,7 @@ final class PhabricatorFileLightboxController ->appendChild( id(new PHUIButtonView()) ->setTag('a') - ->setText(pht('Login to Comment')) + ->setText(pht('Log In to Comment')) ->setHref((string)$login_href)); } diff --git a/src/applications/oauthserver/application/PhabricatorOAuthServerApplication.php b/src/applications/oauthserver/application/PhabricatorOAuthServerApplication.php index 024d9101dd..90e2d5a7dd 100644 --- a/src/applications/oauthserver/application/PhabricatorOAuthServerApplication.php +++ b/src/applications/oauthserver/application/PhabricatorOAuthServerApplication.php @@ -23,7 +23,7 @@ final class PhabricatorOAuthServerApplication extends PhabricatorApplication { } public function getFlavorText() { - return pht('Login with Phabricator'); + return pht('Log In with Phabricator'); } public function getApplicationGroup() { diff --git a/src/applications/ponder/view/PonderAddAnswerView.php b/src/applications/ponder/view/PonderAddAnswerView.php index d958e9843e..43bfd0d6ba 100644 --- a/src/applications/ponder/view/PonderAddAnswerView.php +++ b/src/applications/ponder/view/PonderAddAnswerView.php @@ -72,7 +72,7 @@ final class PonderAddAnswerView extends AphrontView { ->appendChild( id(new PHUIButtonView()) ->setTag('a') - ->setText(pht('Login to Answer')) + ->setText(pht('Log In to Answer')) ->setHref((string)$login_href)); } diff --git a/src/applications/transactions/view/PhabricatorApplicationTransactionCommentView.php b/src/applications/transactions/view/PhabricatorApplicationTransactionCommentView.php index 232420d4c2..a5dcfcb4ae 100644 --- a/src/applications/transactions/view/PhabricatorApplicationTransactionCommentView.php +++ b/src/applications/transactions/view/PhabricatorApplicationTransactionCommentView.php @@ -199,7 +199,7 @@ class PhabricatorApplicationTransactionCommentView extends AphrontView { 'class' => 'login-to-comment button', 'href' => $uri, ), - pht('Login to Comment'))); + pht('Log In to Comment'))); } $data = array(); diff --git a/src/applications/uiexample/examples/PHUIButtonExample.php b/src/applications/uiexample/examples/PHUIButtonExample.php index fe58123f03..a5ece198fd 100644 --- a/src/applications/uiexample/examples/PHUIButtonExample.php +++ b/src/applications/uiexample/examples/PHUIButtonExample.php @@ -158,7 +158,7 @@ final class PHUIButtonExample extends PhabricatorUIExample { ->setSize(PHUIButtonView::BIG) ->setColor(PHUIButtonView::GREY) ->setIcon($image) - ->setText(pht('Login or Register')) + ->setText(pht('Log In or Register')) ->setSubtext($icon) ->addClass(PHUI::MARGIN_MEDIUM_RIGHT); } From cfb86dddd2ef547d41278a1388226e0681a8a8bb Mon Sep 17 00:00:00 2001 From: epriestley Date: Wed, 2 Aug 2017 16:01:49 -0700 Subject: [PATCH 11/16] Warn users that compound terms separated by apostrophes don't work in the MySQL FULLTEXT index either Summary: Ref T12928. Like `v0.1`, terms in the form `yo's` (sequences of two or fewer characters separated by apostrophes) do not get indexed. Test Plan: {F5078192} Reviewers: chad Reviewed By: chad Maniphest Tasks: T12928 Differential Revision: https://secure.phabricator.com/D18324 --- .../PhabricatorMySQLFulltextStorageEngine.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/applications/search/fulltextstorage/PhabricatorMySQLFulltextStorageEngine.php b/src/applications/search/fulltextstorage/PhabricatorMySQLFulltextStorageEngine.php index 4ccc85f085..fe526a8133 100644 --- a/src/applications/search/fulltextstorage/PhabricatorMySQLFulltextStorageEngine.php +++ b/src/applications/search/fulltextstorage/PhabricatorMySQLFulltextStorageEngine.php @@ -554,9 +554,10 @@ final class PhabricatorMySQLFulltextStorageEngine // "ab.cd", where short substrings are separated by periods, do not produce // any queryable tokens. These terms are meaningful if at least one // substring is longer than the minimum length, like "example.py". See - // T12928. + // T12928. This also applies to words with intermediate apostrophes, like + // "to's". - $parts = preg_split('/[.]+/', $value); + $parts = preg_split('/[.\']+/', $value); foreach ($parts as $part) { if (phutil_utf8_strlen($part) >= $min_length) { From 020f3c729a0a05c86abe7e444e9f84b17c095f11 Mon Sep 17 00:00:00 2001 From: Chad Little Date: Thu, 3 Aug 2017 09:31:01 -0700 Subject: [PATCH 12/16] Fix username typeahead in Remarkup with German keyboard layout Summary: Ref T10252. The previous fix rPa8a9fddb0738 only works for macOS. Under Windows the @ symbol is composed of AltGr+q. For Chrome and Edge the "AltGr" keypressEvent is like pressing the Control key and the Alt key at the same time. This fix changes the condition in such a way, that this case (pressing Control and Alt at the same time) is not blocked. Test Plan: Testing for the issue: - Launch Windows 10, Select German Keyboard, Use latest Chrome (60) - Observe typing `@` does not trigger typeahead - Apply patch, retest, see typeahead. Regression tested: - Windows 10, Chrome, Firefox, Edge - Mac OS, Chrome, Firefox, Safari - Keyboard layouts, English, French, German, Spanish All tests passed Reviewers: benwick, epriestley Reviewed By: epriestley Subscribers: epriestley Maniphest Tasks: T10252 Differential Revision: https://secure.phabricator.com/D18269 --- resources/celerity/map.php | 16 ++++++++-------- webroot/rsrc/js/phuix/PHUIXAutocomplete.js | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 2437a1e4c2..fb3fd8d64a 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -528,7 +528,7 @@ return array( 'rsrc/js/phui/behavior-phui-tab-group.js' => '0a0b10e9', 'rsrc/js/phuix/PHUIXActionListView.js' => 'b5c256b8', 'rsrc/js/phuix/PHUIXActionView.js' => '442efd08', - 'rsrc/js/phuix/PHUIXAutocomplete.js' => 'f6699267', + 'rsrc/js/phuix/PHUIXAutocomplete.js' => '4b7430ab', 'rsrc/js/phuix/PHUIXButtonView.js' => 'a37126bd', 'rsrc/js/phuix/PHUIXDropdownMenu.js' => '8018ee50', 'rsrc/js/phuix/PHUIXExample.js' => '68af71ca', @@ -881,7 +881,7 @@ return array( 'phui-workpanel-view-css' => 'a3a63478', 'phuix-action-list-view' => 'b5c256b8', 'phuix-action-view' => '442efd08', - 'phuix-autocomplete' => 'f6699267', + 'phuix-autocomplete' => '4b7430ab', 'phuix-button-view' => 'a37126bd', 'phuix-dropdown-menu' => '8018ee50', 'phuix-form-control-view' => '83e03671', @@ -1237,6 +1237,12 @@ return array( 'javelin-util', 'phabricator-shaped-request', ), + '4b7430ab' => array( + 'javelin-install', + 'javelin-dom', + 'phuix-icon-view', + 'phabricator-prefab', + ), '4c193c96' => array( 'javelin-behavior', 'javelin-uri', @@ -2127,12 +2133,6 @@ return array( 'javelin-util', 'javelin-reactor', ), - 'f6699267' => array( - 'javelin-install', - 'javelin-dom', - 'phuix-icon-view', - 'phabricator-prefab', - ), 'f7fc67ec' => array( 'javelin-install', 'javelin-typeahead', diff --git a/webroot/rsrc/js/phuix/PHUIXAutocomplete.js b/webroot/rsrc/js/phuix/PHUIXAutocomplete.js index ac073a0e38..df4a031377 100644 --- a/webroot/rsrc/js/phuix/PHUIXAutocomplete.js +++ b/webroot/rsrc/js/phuix/PHUIXAutocomplete.js @@ -199,7 +199,7 @@ JX.install('PHUIXAutocomplete', { // to press Alt to type characters like "@" on a German keyboard layout. // The cost of misfiring autocompleters is very small since we do not // eat the keystroke. See T10252. - if (r.metaKey || r.ctrlKey) { + if (r.metaKey || (r.ctrlKey && !r.altKey)) { return; } From 7621376aab9778580c7013029644fae2159996fd Mon Sep 17 00:00:00 2001 From: Chad Little Date: Thu, 3 Aug 2017 17:18:30 -0700 Subject: [PATCH 13/16] Allow images to be used with PHUIBigInfoView Summary: Allows setting on an image here if wanted. Test Plan: Set a rocket to launch a new instance on rSAAS Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D18334 --- resources/celerity/map.php | 4 +- src/view/phui/PHUIBigInfoView.php | 41 +++++++++++++++----- webroot/rsrc/css/phui/phui-big-info-view.css | 7 ++++ 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index fb3fd8d64a..be593429cd 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -142,7 +142,7 @@ return array( 'rsrc/css/phui/phui-action-panel.css' => 'b4798122', 'rsrc/css/phui/phui-badge.css' => '22c0cf4f', 'rsrc/css/phui/phui-basic-nav-view.css' => 'a0705f53', - 'rsrc/css/phui/phui-big-info-view.css' => 'd13afcde', + 'rsrc/css/phui/phui-big-info-view.css' => 'acc3492c', 'rsrc/css/phui/phui-box.css' => '745e881d', 'rsrc/css/phui/phui-chart.css' => '6bf6f78e', 'rsrc/css/phui/phui-cms.css' => '504b4b23', @@ -821,7 +821,7 @@ return array( 'phui-action-panel-css' => 'b4798122', 'phui-badge-view-css' => '22c0cf4f', 'phui-basic-nav-view-css' => 'a0705f53', - 'phui-big-info-view-css' => 'd13afcde', + 'phui-big-info-view-css' => 'acc3492c', 'phui-box-css' => '745e881d', 'phui-button-bar-css' => 'f1ff5494', 'phui-button-css' => '3ca51caa', diff --git a/src/view/phui/PHUIBigInfoView.php b/src/view/phui/PHUIBigInfoView.php index 0f5bcecfbd..ad10a9fa4a 100644 --- a/src/view/phui/PHUIBigInfoView.php +++ b/src/view/phui/PHUIBigInfoView.php @@ -5,6 +5,7 @@ final class PHUIBigInfoView extends AphrontTagView { private $icon; private $title; private $description; + private $image; private $actions = array(); public function setIcon($icon) { @@ -22,6 +23,11 @@ final class PHUIBigInfoView extends AphrontTagView { return $this; } + public function setImage($image) { + $this->image = $image; + return $this; + } + public function addAction(PHUIButtonView $button) { $this->actions[] = $button; return $this; @@ -43,16 +49,33 @@ final class PHUIBigInfoView extends AphrontTagView { protected function getTagContent() { require_celerity_resource('phui-big-info-view-css'); - $icon = id(new PHUIIconView()) - ->setIcon($this->icon) - ->addClass('phui-big-info-icon'); + if ($this->icon) { + $icon = id(new PHUIIconView()) + ->setIcon($this->icon) + ->addClass('phui-big-info-icon'); - $icon = phutil_tag( - 'div', - array( - 'class' => 'phui-big-info-icon-container', - ), - $icon); + $icon = phutil_tag( + 'div', + array( + 'class' => 'phui-big-info-icon-container', + ), + $icon); + } + + if ($this->image) { + $image = phutil_tag( + 'img', + array( + 'class' => 'phui-big-info-image', + 'src' => $this->image, + )); + $icon = phutil_tag( + 'span', + array( + 'class' => 'phui-big-info-icon-container', + ), + $image); + } $title = phutil_tag( 'div', diff --git a/webroot/rsrc/css/phui/phui-big-info-view.css b/webroot/rsrc/css/phui/phui-big-info-view.css index 38951aa059..b8fbab55ce 100644 --- a/webroot/rsrc/css/phui/phui-big-info-view.css +++ b/webroot/rsrc/css/phui/phui-big-info-view.css @@ -35,3 +35,10 @@ .phui-big-info-button + .phui-big-info-button { margin-left: 12px; } + +.phui-big-info-view .phui-big-info-image { + height: 64px; + width: 64px; + margin: 0 auto; + padding-bottom: 12px; +} From fedf08743ffd9882444259481c0f21144c647fdb Mon Sep 17 00:00:00 2001 From: Chad Little Date: Thu, 3 Aug 2017 16:50:01 -0700 Subject: [PATCH 14/16] Allow setting of tabs at StandardPageView Summary: Rather than have tabs live in two column view, sometimes like `admin` we'll want a global set of tabs that work well with all layouts and crumbs. Test Plan: I tested this in an upcoming diff for instances. {F5080228} Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D18332 --- resources/celerity/map.php | 6 +++--- src/view/page/PhabricatorStandardPageView.php | 21 +++++++++++++++++++ .../application/base/standard-page-view.css | 11 ++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index be593429cd..f795cc096f 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -9,7 +9,7 @@ return array( 'names' => array( 'conpherence.pkg.css' => 'e68cf1fa', 'conpherence.pkg.js' => 'b5b51108', - 'core.pkg.css' => 'd9c9cfd0', + 'core.pkg.css' => '851ae625', 'core.pkg.js' => '5d80e0db', 'darkconsole.pkg.js' => '1f9a31bc', 'differential.pkg.css' => '45951e9e', @@ -42,7 +42,7 @@ return array( 'rsrc/css/application/base/main-menu-view.css' => '16053029', 'rsrc/css/application/base/notification-menu.css' => '73fefdfa', 'rsrc/css/application/base/phui-theme.css' => '9f261c6b', - 'rsrc/css/application/base/standard-page-view.css' => 'eb5b80c5', + 'rsrc/css/application/base/standard-page-view.css' => 'a0dae682', 'rsrc/css/application/chatlog/chatlog.css' => 'd295b020', 'rsrc/css/application/conduit/conduit-api.css' => '7bc725c4', 'rsrc/css/application/config/config-options.css' => 'd55ed093', @@ -802,7 +802,7 @@ return array( 'phabricator-shaped-request' => '7cbe244b', 'phabricator-slowvote-css' => 'a94b7230', 'phabricator-source-code-view-css' => 'aea41829', - 'phabricator-standard-page-view' => 'eb5b80c5', + 'phabricator-standard-page-view' => 'a0dae682', 'phabricator-textareautils' => '320810c8', 'phabricator-title' => '485aaa6c', 'phabricator-tooltip' => '358b8c04', diff --git a/src/view/page/PhabricatorStandardPageView.php b/src/view/page/PhabricatorStandardPageView.php index a138d077b5..d26cca945f 100644 --- a/src/view/page/PhabricatorStandardPageView.php +++ b/src/view/page/PhabricatorStandardPageView.php @@ -19,6 +19,7 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView private $showFooter = true; private $showDurableColumn = true; private $quicksandConfig = array(); + private $tabs; private $crumbs; private $navigation; @@ -159,6 +160,17 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView return $this->crumbs; } + public function setTabs(PHUIListView $tabs) { + $tabs->setType(PHUIListView::TABBAR_LIST); + $tabs->addClass('phabricator-standard-page-tabs'); + $this->tabs = $tabs; + return $this; + } + + public function getTabs() { + return $this->tabs; + } + public function setNavigation(AphrontSideNavFilterView $navigation) { $this->navigation = $navigation; return $this; @@ -528,6 +540,7 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView $footer = $this->renderFooter(); $nav = $this->getNavigation(); + $tabs = $this->getTabs(); if ($nav) { $crumbs = $this->getCrumbs(); if ($crumbs) { @@ -541,9 +554,17 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView $crumbs = $this->getCrumbs(); if ($crumbs) { + if ($this->getTabs()) { + $crumbs->setBorder(true); + } $content[] = $crumbs; } + $tabs = $this->getTabs(); + if ($tabs) { + $content[] = $tabs; + } + $content[] = $body; $content[] = $footer; diff --git a/webroot/rsrc/css/application/base/standard-page-view.css b/webroot/rsrc/css/application/base/standard-page-view.css index 89cbfdbd2e..f697b1f7a8 100644 --- a/webroot/rsrc/css/application/base/standard-page-view.css +++ b/webroot/rsrc/css/application/base/standard-page-view.css @@ -176,3 +176,14 @@ a.handle-status-closed:hover { position: absolute; left: -50px; } + +.phabricator-standard-page-tabs { + padding: 0 32px; + margin-bottom: 32px; + background: {$page.content}; + box-shadow: 0 0 3px 0 rgba(0,0,0,0.2); +} + +.phabricator-standard-page-tabs.phui-list-tabbar .phui-list-item-href { + padding: 12px 24px; +} From 68ab9b2642b8809388dea36e0fe3e86367086cc2 Mon Sep 17 00:00:00 2001 From: Chad Little Date: Thu, 3 Aug 2017 19:52:35 -0700 Subject: [PATCH 15/16] Switch fluid to fixed on PHUITwoColumnView Summary: We don't ever set fluid, since it already is fluid, also no CSS. Add an actual fixed version. Test Plan: For use in Instances. Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D18336 --- resources/celerity/map.php | 6 +++--- src/view/phui/PHUITwoColumnView.php | 10 +++++----- webroot/rsrc/css/phui/phui-two-column-view.css | 5 +++++ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index f795cc096f..d50a470c34 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -9,7 +9,7 @@ return array( 'names' => array( 'conpherence.pkg.css' => 'e68cf1fa', 'conpherence.pkg.js' => 'b5b51108', - 'core.pkg.css' => '851ae625', + 'core.pkg.css' => 'cc0772c6', 'core.pkg.js' => '5d80e0db', 'darkconsole.pkg.js' => '1f9a31bc', 'differential.pkg.css' => '45951e9e', @@ -178,7 +178,7 @@ return array( 'rsrc/css/phui/phui-status.css' => 'd5263e49', 'rsrc/css/phui/phui-tag-view.css' => 'b4719c50', 'rsrc/css/phui/phui-timeline-view.css' => 'f21db7ca', - 'rsrc/css/phui/phui-two-column-view.css' => '5b8cd553', + 'rsrc/css/phui/phui-two-column-view.css' => 'ae38a939', 'rsrc/css/phui/workboards/phui-workboard-color.css' => '783cdff5', 'rsrc/css/phui/workboards/phui-workboard.css' => '3bc85455', 'rsrc/css/phui/workboards/phui-workcard.css' => 'cca5fa92', @@ -874,7 +874,7 @@ return array( 'phui-tag-view-css' => 'b4719c50', 'phui-theme-css' => '9f261c6b', 'phui-timeline-view-css' => 'f21db7ca', - 'phui-two-column-view-css' => '5b8cd553', + 'phui-two-column-view-css' => 'ae38a939', 'phui-workboard-color-css' => '783cdff5', 'phui-workboard-view-css' => '3bc85455', 'phui-workcard-view-css' => 'cca5fa92', diff --git a/src/view/phui/PHUITwoColumnView.php b/src/view/phui/PHUITwoColumnView.php index d0443280b6..6e261ffeeb 100644 --- a/src/view/phui/PHUITwoColumnView.php +++ b/src/view/phui/PHUITwoColumnView.php @@ -6,7 +6,7 @@ final class PHUITwoColumnView extends AphrontTagView { private $sideColumn = null; private $navigation; private $display; - private $fluid; + private $fixed; private $header; private $subheader; private $footer; @@ -71,8 +71,8 @@ final class PHUITwoColumnView extends AphrontTagView { return $this->curtain; } - public function setFluid($fluid) { - $this->fluid = $fluid; + public function setFixed($fixed) { + $this->fixed = $fixed; return $this; } @@ -94,8 +94,8 @@ final class PHUITwoColumnView extends AphrontTagView { $classes[] = 'phui-two-column-view'; $classes[] = $this->getDisplay(); - if ($this->fluid) { - $classes[] = 'phui-two-column-fluid'; + if ($this->fixed) { + $classes[] = 'phui-two-column-fixed'; } if ($this->tabs) { diff --git a/webroot/rsrc/css/phui/phui-two-column-view.css b/webroot/rsrc/css/phui/phui-two-column-view.css index 75162619c4..2957528929 100644 --- a/webroot/rsrc/css/phui/phui-two-column-view.css +++ b/webroot/rsrc/css/phui/phui-two-column-view.css @@ -2,6 +2,11 @@ * @provides phui-two-column-view-css */ +.phui-two-column-fixed { + max-width: 1140px; + margin: 0 auto; +} + .phui-two-column-view .phui-two-column-header { background-color: {$page.content}; border-bottom: 1px solid rgba({$alphagrey}, .12); From 83f66ce55e1a7684cac963053bd62c823fe07baf Mon Sep 17 00:00:00 2001 From: Chad Little Date: Fri, 4 Aug 2017 10:16:18 -0700 Subject: [PATCH 16/16] Update Settings to use full side-navigation Summary: Moves Settings to use a normal side navigation vs. a two column side navigation. It also updates Edit Engine to do the same, but I don't think there are other callsites. Added a consistent header for better clarification if you were editng your settings, global settings, or a bot's settings. Test Plan: Test each page on a personal account, create global settings, test each page there, create a bot account, and test each page on the bot account. Anything else? Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D18342 --- .../PhabricatorConduitTokensSettingsPanel.php | 1 + ...OAuthServerAuthorizationsSettingsPanel.php | 1 + .../PhabricatorSettingsMainController.php | 16 +++++++- .../editor/PhabricatorSettingsEditEngine.php | 7 +++- .../PhabricatorActivitySettingsPanel.php | 1 + ...catorDesktopNotificationsSettingsPanel.php | 1 + .../PhabricatorEditEngineSettingsPanel.php | 1 - ...PhabricatorEmailAddressesSettingsPanel.php | 1 + ...abricatorEmailPreferencesSettingsPanel.php | 1 + ...abricatorExternalAccountsSettingsPanel.php | 2 + .../PhabricatorMultiFactorSettingsPanel.php | 1 + .../PhabricatorPasswordSettingsPanel.php | 1 + .../panel/PhabricatorSSHKeysSettingsPanel.php | 1 + .../PhabricatorSessionsSettingsPanel.php | 3 +- .../panel/PhabricatorTokensSettingsPanel.php | 1 + .../editengine/PhabricatorEditEngine.php | 41 ++++++------------- 16 files changed, 47 insertions(+), 33 deletions(-) diff --git a/src/applications/conduit/settings/PhabricatorConduitTokensSettingsPanel.php b/src/applications/conduit/settings/PhabricatorConduitTokensSettingsPanel.php index fc89d310e1..3da467e4f4 100644 --- a/src/applications/conduit/settings/PhabricatorConduitTokensSettingsPanel.php +++ b/src/applications/conduit/settings/PhabricatorConduitTokensSettingsPanel.php @@ -108,6 +108,7 @@ final class PhabricatorConduitTokensSettingsPanel $panel = id(new PHUIObjectBoxView()) ->setHeader($header) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setTable($table); return $panel; diff --git a/src/applications/oauthserver/panel/PhabricatorOAuthServerAuthorizationsSettingsPanel.php b/src/applications/oauthserver/panel/PhabricatorOAuthServerAuthorizationsSettingsPanel.php index 596f3decc9..cfc0bc91a8 100644 --- a/src/applications/oauthserver/panel/PhabricatorOAuthServerAuthorizationsSettingsPanel.php +++ b/src/applications/oauthserver/panel/PhabricatorOAuthServerAuthorizationsSettingsPanel.php @@ -134,6 +134,7 @@ final class PhabricatorOAuthServerAuthorizationsSettingsPanel $panel = id(new PHUIObjectBoxView()) ->setHeader($header) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setTable($table); return $panel; diff --git a/src/applications/settings/controller/PhabricatorSettingsMainController.php b/src/applications/settings/controller/PhabricatorSettingsMainController.php index 841529a051..4c1bfab6f1 100644 --- a/src/applications/settings/controller/PhabricatorSettingsMainController.php +++ b/src/applications/settings/controller/PhabricatorSettingsMainController.php @@ -112,15 +112,27 @@ final class PhabricatorSettingsMainController $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb($panel->getPanelName()); + $crumbs->setBorder(true); + + if ($this->user) { + $header_text = pht('Edit Settings (%s)', $user->getUserName()); + } else { + $header_text = pht('Edit Global Settings'); + } + + $header = id(new PHUIHeaderView()) + ->setHeader($header_text) + ->setHeaderIcon('fa-pencil'); $title = $panel->getPanelName(); $view = id(new PHUITwoColumnView()) - ->setNavigation($nav) - ->setMainColumn($response); + ->setHeader($header) + ->setFooter($response); return $this->newPage() ->setTitle($title) + ->setNavigation($nav) ->setCrumbs($crumbs) ->appendChild($view); diff --git a/src/applications/settings/editor/PhabricatorSettingsEditEngine.php b/src/applications/settings/editor/PhabricatorSettingsEditEngine.php index 4bcfa08d1d..e12654e1a4 100644 --- a/src/applications/settings/editor/PhabricatorSettingsEditEngine.php +++ b/src/applications/settings/editor/PhabricatorSettingsEditEngine.php @@ -63,7 +63,12 @@ final class PhabricatorSettingsEditEngine } protected function getObjectEditTitleText($object) { - return pht('Edit Settings'); + $user = $object->getUser(); + if ($user) { + return pht('Edit Settings (%s)', $user->getUserName()); + } else { + return pht('Edit Global Settings'); + } } protected function getObjectEditShortText($object) { diff --git a/src/applications/settings/panel/PhabricatorActivitySettingsPanel.php b/src/applications/settings/panel/PhabricatorActivitySettingsPanel.php index a16984c140..0b3533f287 100644 --- a/src/applications/settings/panel/PhabricatorActivitySettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorActivitySettingsPanel.php @@ -48,6 +48,7 @@ final class PhabricatorActivitySettingsPanel extends PhabricatorSettingsPanel { $panel = id(new PHUIObjectBoxView()) ->setHeaderText(pht('Account Activity Logs')) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setTable($table); $pager_box = id(new PHUIBoxView()) diff --git a/src/applications/settings/panel/PhabricatorDesktopNotificationsSettingsPanel.php b/src/applications/settings/panel/PhabricatorDesktopNotificationsSettingsPanel.php index c08a833f1b..f94de959cd 100644 --- a/src/applications/settings/panel/PhabricatorDesktopNotificationsSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorDesktopNotificationsSettingsPanel.php @@ -157,6 +157,7 @@ final class PhabricatorDesktopNotificationsSettingsPanel ->setHeader(pht('Desktop Notifications')) ->addActionLink($test_button)) ->setForm($form) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setInfoView($status_box) ->setFormSaved($request->getBool('saved')); diff --git a/src/applications/settings/panel/PhabricatorEditEngineSettingsPanel.php b/src/applications/settings/panel/PhabricatorEditEngineSettingsPanel.php index 27161218d1..5aad71785e 100644 --- a/src/applications/settings/panel/PhabricatorEditEngineSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorEditEngineSettingsPanel.php @@ -22,7 +22,6 @@ abstract class PhabricatorEditEngineSettingsPanel $engine = id(new PhabricatorSettingsEditEngine()) ->setController($this->getController()) ->setNavigation($this->getNavigation()) - ->setHideHeader(true) ->setIsSelfEdit($is_self) ->setProfileURI($profile_uri); diff --git a/src/applications/settings/panel/PhabricatorEmailAddressesSettingsPanel.php b/src/applications/settings/panel/PhabricatorEmailAddressesSettingsPanel.php index d628341dea..66fd0396ad 100644 --- a/src/applications/settings/panel/PhabricatorEmailAddressesSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorEmailAddressesSettingsPanel.php @@ -153,6 +153,7 @@ final class PhabricatorEmailAddressesSettingsPanel } $view->setHeader($header); $view->setTable($table); + $view->setBackground(PHUIObjectBoxView::BLUE_PROPERTY); return $view; } diff --git a/src/applications/settings/panel/PhabricatorEmailPreferencesSettingsPanel.php b/src/applications/settings/panel/PhabricatorEmailPreferencesSettingsPanel.php index 0c775c5a4d..77364e0aa0 100644 --- a/src/applications/settings/panel/PhabricatorEmailPreferencesSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorEmailPreferencesSettingsPanel.php @@ -136,6 +136,7 @@ final class PhabricatorEmailPreferencesSettingsPanel ->setHeaderText(pht('Email Preferences')) ->setFormSaved($request->getStr('saved')) ->setFormErrors($errors) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setForm($form); return $form_box; diff --git a/src/applications/settings/panel/PhabricatorExternalAccountsSettingsPanel.php b/src/applications/settings/panel/PhabricatorExternalAccountsSettingsPanel.php index 662d4e6cf6..068c58d549 100644 --- a/src/applications/settings/panel/PhabricatorExternalAccountsSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorExternalAccountsSettingsPanel.php @@ -131,10 +131,12 @@ final class PhabricatorExternalAccountsSettingsPanel $linked_box = id(new PHUIObjectBoxView()) ->setHeader($linked_head) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setObjectList($linked); $linkable_box = id(new PHUIObjectBoxView()) ->setHeader($linkable_head) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setObjectList($linkable); return array( diff --git a/src/applications/settings/panel/PhabricatorMultiFactorSettingsPanel.php b/src/applications/settings/panel/PhabricatorMultiFactorSettingsPanel.php index 8f1a5c643c..68d1812616 100644 --- a/src/applications/settings/panel/PhabricatorMultiFactorSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorMultiFactorSettingsPanel.php @@ -126,6 +126,7 @@ final class PhabricatorMultiFactorSettingsPanel $panel->setHeader($header); $panel->setTable($table); + $panel->setBackground(PHUIObjectBoxView::BLUE_PROPERTY); return $panel; } diff --git a/src/applications/settings/panel/PhabricatorPasswordSettingsPanel.php b/src/applications/settings/panel/PhabricatorPasswordSettingsPanel.php index 17b8cdde95..2a1b482c80 100644 --- a/src/applications/settings/panel/PhabricatorPasswordSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorPasswordSettingsPanel.php @@ -206,6 +206,7 @@ final class PhabricatorPasswordSettingsPanel extends PhabricatorSettingsPanel { ->setHeaderText(pht('Change Password')) ->setFormSaved($request->getStr('saved')) ->setFormErrors($errors) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setForm($form); return array( diff --git a/src/applications/settings/panel/PhabricatorSSHKeysSettingsPanel.php b/src/applications/settings/panel/PhabricatorSSHKeysSettingsPanel.php index 54a217300d..3e339e9145 100644 --- a/src/applications/settings/panel/PhabricatorSSHKeysSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorSSHKeysSettingsPanel.php @@ -50,6 +50,7 @@ final class PhabricatorSSHKeysSettingsPanel extends PhabricatorSettingsPanel { $panel->setHeader($header); $panel->setTable($table); + $panel->setBackground(PHUIObjectBoxView::BLUE_PROPERTY); return $panel; } diff --git a/src/applications/settings/panel/PhabricatorSessionsSettingsPanel.php b/src/applications/settings/panel/PhabricatorSessionsSettingsPanel.php index e643f2ee08..fb60e40d81 100644 --- a/src/applications/settings/panel/PhabricatorSessionsSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorSessionsSettingsPanel.php @@ -136,7 +136,8 @@ final class PhabricatorSessionsSettingsPanel extends PhabricatorSettingsPanel { $panel = id(new PHUIObjectBoxView()) ->setHeader($header) - ->setTable($table); + ->setTable($table) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY); return $panel; } diff --git a/src/applications/settings/panel/PhabricatorTokensSettingsPanel.php b/src/applications/settings/panel/PhabricatorTokensSettingsPanel.php index c2659d5226..d2cc0dedb6 100644 --- a/src/applications/settings/panel/PhabricatorTokensSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorTokensSettingsPanel.php @@ -84,6 +84,7 @@ final class PhabricatorTokensSettingsPanel extends PhabricatorSettingsPanel { $panel = id(new PHUIObjectBoxView()) ->setHeader($header) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setTable($table); return $panel; diff --git a/src/applications/transactions/editengine/PhabricatorEditEngine.php b/src/applications/transactions/editengine/PhabricatorEditEngine.php index 1b891cddee..c9d8a6887f 100644 --- a/src/applications/transactions/editengine/PhabricatorEditEngine.php +++ b/src/applications/transactions/editengine/PhabricatorEditEngine.php @@ -29,7 +29,6 @@ abstract class PhabricatorEditEngine private $page; private $pages; private $navigation; - private $hideHeader; final public function setViewer(PhabricatorUser $viewer) { $this->viewer = $viewer; @@ -127,15 +126,6 @@ abstract class PhabricatorEditEngine return $this->navigation; } - public function setHideHeader($hide_header) { - $this->hideHeader = $hide_header; - return $this; - } - - public function getHideHeader() { - return $this->hideHeader; - } - /* -( Managing Fields )---------------------------------------------------- */ @@ -1194,15 +1184,10 @@ abstract class PhabricatorEditEngine $crumbs = $this->buildCrumbs($object, $final = true); - if ($this->getHideHeader()) { - $header = null; - $crumbs->setBorder(false); - } else { - $header = id(new PHUIHeaderView()) - ->setHeader($header_text) - ->setHeaderIcon($header_icon); - $crumbs->setBorder(true); - } + $header = id(new PHUIHeaderView()) + ->setHeader($header_text) + ->setHeaderIcon($header_icon); + $crumbs->setBorder(true); if ($action_button) { $header->addActionLink($action_button); @@ -1231,19 +1216,19 @@ abstract class PhabricatorEditEngine $view->setHeader($header); } - $navigation = $this->getNavigation(); - if ($navigation) { - $view - ->setNavigation($navigation) - ->setMainColumn($content); - } else { - $view->setFooter($content); - } + $view->setFooter($content); - return $controller->newPage() + $page = $controller->newPage() ->setTitle($header_text) ->setCrumbs($crumbs) ->appendChild($view); + + $navigation = $this->getNavigation(); + if ($navigation) { + $page->setNavigation($navigation); + } + + return $page; } protected function newEditResponse(