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

Configure Feed

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

Workboards

Summary: Adds Workboards and workpanels. This is a preliminary diff, I'm still working on mobile and tablet and a few missing features (header actions)

Test Plan: FF, Chrome, iOS, iPad, iPhone, IE

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin

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

+470
+25
src/__celerity_resource_map__.php
··· 595 595 'disk' => '/rsrc/image/texture/grip.png', 596 596 'type' => 'png', 597 597 ), 598 + '/rsrc/image/texture/panel-header-gradient.png' => 599 + array( 600 + 'hash' => 'ad9204dd3ef5b12b645d80677d8ccead', 601 + 'uri' => '/res/ad9204dd/rsrc/image/texture/panel-header-gradient.png', 602 + 'disk' => '/rsrc/image/texture/panel-header-gradient.png', 603 + 'type' => 'png', 604 + ), 598 605 '/rsrc/image/texture/pholio-background.gif' => 599 606 array( 600 607 'hash' => 'cf4561af116edf393dc583e5119fb412', ··· 3377 3384 4 => 'javelin-reactor-dom', 3378 3385 ), 3379 3386 'disk' => '/rsrc/js/application/uiexample/ReactorSendPropertiesExample.js', 3387 + ), 3388 + 'phabricator-workboard-view-css' => 3389 + array( 3390 + 'uri' => '/res/98971c26/rsrc/css/layout/phabricator-workboard-view.css', 3391 + 'type' => 'css', 3392 + 'requires' => 3393 + array( 3394 + ), 3395 + 'disk' => '/rsrc/css/layout/phabricator-workboard-view.css', 3396 + ), 3397 + 'phabricator-workpanel-view-css' => 3398 + array( 3399 + 'uri' => '/res/96a4b5cd/rsrc/css/layout/phabricator-workpanel-view.css', 3400 + 'type' => 'css', 3401 + 'requires' => 3402 + array( 3403 + ), 3404 + 'disk' => '/rsrc/css/layout/phabricator-workpanel-view.css', 3380 3405 ), 3381 3406 'phabricator-zindex-css' => 3382 3407 array(
+6
src/__phutil_library_map__.php
··· 1433 1433 'PhabricatorUserStatusInvalidEpochException' => 'applications/people/exception/PhabricatorUserStatusInvalidEpochException.php', 1434 1434 'PhabricatorUserStatusOverlapException' => 'applications/people/exception/PhabricatorUserStatusOverlapException.php', 1435 1435 'PhabricatorUserTestCase' => 'applications/people/storage/__tests__/PhabricatorUserTestCase.php', 1436 + 'PhabricatorWorkboardExample' => 'applications/uiexample/examples/PhabricatorWorkboardExample.php', 1437 + 'PhabricatorWorkboardView' => 'view/layout/PhabricatorWorkboardView.php', 1436 1438 'PhabricatorWorker' => 'infrastructure/daemon/workers/PhabricatorWorker.php', 1437 1439 'PhabricatorWorkerActiveTask' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerActiveTask.php', 1438 1440 'PhabricatorWorkerArchiveTask' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerArchiveTask.php', ··· 1444 1446 'PhabricatorWorkerTaskDetailController' => 'applications/daemon/controller/PhabricatorWorkerTaskDetailController.php', 1445 1447 'PhabricatorWorkerTaskUpdateController' => 'applications/daemon/controller/PhabricatorWorkerTaskUpdateController.php', 1446 1448 'PhabricatorWorkerTestCase' => 'infrastructure/daemon/workers/__tests__/PhabricatorWorkerTestCase.php', 1449 + 'PhabricatorWorkpanelView' => 'view/layout/PhabricatorWorkpanelView.php', 1447 1450 'PhabricatorXHPASTViewController' => 'applications/phpast/controller/PhabricatorXHPASTViewController.php', 1448 1451 'PhabricatorXHPASTViewDAO' => 'applications/phpast/storage/PhabricatorXHPASTViewDAO.php', 1449 1452 'PhabricatorXHPASTViewFrameController' => 'applications/phpast/controller/PhabricatorXHPASTViewFrameController.php', ··· 3077 3080 'PhabricatorUserStatusInvalidEpochException' => 'Exception', 3078 3081 'PhabricatorUserStatusOverlapException' => 'Exception', 3079 3082 'PhabricatorUserTestCase' => 'PhabricatorTestCase', 3083 + 'PhabricatorWorkboardExample' => 'PhabricatorUIExample', 3084 + 'PhabricatorWorkboardView' => 'AphrontView', 3080 3085 'PhabricatorWorkerActiveTask' => 'PhabricatorWorkerTask', 3081 3086 'PhabricatorWorkerArchiveTask' => 'PhabricatorWorkerTask', 3082 3087 'PhabricatorWorkerDAO' => 'PhabricatorLiskDAO', ··· 3087 3092 'PhabricatorWorkerTaskDetailController' => 'PhabricatorDaemonController', 3088 3093 'PhabricatorWorkerTaskUpdateController' => 'PhabricatorDaemonController', 3089 3094 'PhabricatorWorkerTestCase' => 'PhabricatorTestCase', 3095 + 'PhabricatorWorkpanelView' => 'AphrontView', 3090 3096 'PhabricatorXHPASTViewController' => 'PhabricatorController', 3091 3097 'PhabricatorXHPASTViewDAO' => 'PhabricatorLiskDAO', 3092 3098 'PhabricatorXHPASTViewFrameController' => 'PhabricatorXHPASTViewController',
+160
src/applications/uiexample/examples/PhabricatorWorkboardExample.php
··· 1 + <?php 2 + 3 + final class PhabricatorWorkboardExample extends PhabricatorUIExample { 4 + 5 + public function getName() { 6 + return 'Workboard'; 7 + } 8 + 9 + public function getDescription() { 10 + return 'A board for visualizing work. Fixed and Fluid layouts.'; 11 + } 12 + 13 + public function renderExample() { 14 + 15 + /* List 1 */ 16 + 17 + $list = new PhabricatorObjectItemListView(); 18 + $list->setCards(true); 19 + $list->setFlush(true); 20 + 21 + $list->addItem( 22 + id(new PhabricatorObjectItemView()) 23 + ->setHeader(pht('Business Card')) 24 + ->setBarColor('red')); 25 + $list->addItem( 26 + id(new PhabricatorObjectItemView()) 27 + ->setHeader(pht('Playing Card')) 28 + ->setBarColor('orange')); 29 + $list->addItem( 30 + id(new PhabricatorObjectItemView()) 31 + ->setHeader(pht('House of Cards')) 32 + ->setBarColor('yellow')); 33 + $list->addItem( 34 + id(new PhabricatorObjectItemView()) 35 + ->setHeader(pht('Cardigan')) 36 + ->setBarColor('green')); 37 + $list->addItem( 38 + id(new PhabricatorObjectItemView()) 39 + ->setHeader(pht('Cardamom')) 40 + ->addFootIcon('highlight-white', 'Spice') 41 + ->setBarColor('blue')); 42 + 43 + /* List 2 */ 44 + 45 + $list2 = new PhabricatorObjectItemListView(); 46 + $list2->setCards(true); 47 + $list2->setFlush(true); 48 + 49 + $list2->addItem( 50 + id(new PhabricatorObjectItemView()) 51 + ->setHeader(pht('Business Card')) 52 + ->setBarColor('red')); 53 + $list2->addItem( 54 + id(new PhabricatorObjectItemView()) 55 + ->setHeader(pht('Playing Card')) 56 + ->setBarColor('orange')); 57 + 58 + /* List 3 */ 59 + 60 + $list3 = new PhabricatorObjectItemListView(); 61 + $list3->setCards(true); 62 + $list3->setFlush(true); 63 + 64 + $list3->addItem( 65 + id(new PhabricatorObjectItemView()) 66 + ->setHeader(pht('Business Card')) 67 + ->setBarColor('red')); 68 + $list3->addItem( 69 + id(new PhabricatorObjectItemView()) 70 + ->setHeader(pht('Playing Card')) 71 + ->setBarColor('orange')); 72 + $list3->addItem( 73 + id(new PhabricatorObjectItemView()) 74 + ->setHeader(pht('House of Cards')) 75 + ->setBarColor('yellow')); 76 + $list3->addItem( 77 + id(new PhabricatorObjectItemView()) 78 + ->setHeader(pht('Cardigan')) 79 + ->setBarColor('green')); 80 + $list3->addItem( 81 + id(new PhabricatorObjectItemView()) 82 + ->setHeader(pht('Cardamom')) 83 + ->addFootIcon('highlight-white', 'Spice') 84 + ->setBarColor('blue')); 85 + $list3->addItem( 86 + id(new PhabricatorObjectItemView()) 87 + ->setHeader(pht('Business Card')) 88 + ->setBarColor('red')); 89 + $list3->addItem( 90 + id(new PhabricatorObjectItemView()) 91 + ->setHeader(pht('Playing Card')) 92 + ->setBarColor('orange')); 93 + $list3->addItem( 94 + id(new PhabricatorObjectItemView()) 95 + ->setHeader(pht('Business Card')) 96 + ->setBarColor('red')); 97 + $list3->addItem( 98 + id(new PhabricatorObjectItemView()) 99 + ->setHeader(pht('Playing Card')) 100 + ->setBarColor('orange')); 101 + 102 + $panel = id(new PhabricatorWorkpanelView) 103 + ->setCards($list) 104 + ->setHeader('Business Stuff'); 105 + 106 + $panel2 = id(new PhabricatorWorkpanelView) 107 + ->setCards($list2) 108 + ->setHeader('Under Duress'); 109 + 110 + $panel3 = id(new PhabricatorWorkpanelView) 111 + ->setCards($list3) 112 + ->setHeader('Spicy Thai Chicken'); 113 + 114 + $board = id(new PhabricatorWorkboardView) 115 + ->addPanel($panel) 116 + ->addPanel($panel2) 117 + ->addPanel($panel2) 118 + ->addPanel($panel3); 119 + 120 + $board2 = id(new PhabricatorWorkboardView) 121 + ->setFlexLayout(true) 122 + ->addPanel($panel) 123 + ->addPanel($panel2) 124 + ->addPanel($panel2) 125 + ->addPanel($panel2) 126 + ->addPanel($panel2) 127 + ->addPanel($panel3); 128 + 129 + $head1 = id(new PhabricatorHeaderView()) 130 + ->setHeader(pht('Fixed Panel')); 131 + 132 + $head2 = id(new PhabricatorHeaderView()) 133 + ->setHeader(pht('Fluid Panel')); 134 + 135 + 136 + $wrap1 = phutil_tag( 137 + 'div', 138 + array( 139 + 'class' => 'ml' 140 + ), 141 + $board); 142 + 143 + $wrap2 = phutil_tag( 144 + 'div', 145 + array( 146 + 'class' => 'ml' 147 + ), 148 + $board2); 149 + 150 + return phutil_tag( 151 + 'div', 152 + array(), 153 + array( 154 + $head1, 155 + $wrap1, 156 + $head2, 157 + $wrap2 158 + )); 159 + } 160 + }
+54
src/view/layout/PhabricatorWorkboardView.php
··· 1 + <?php 2 + 3 + final class PhabricatorWorkboardView extends AphrontView { 4 + 5 + private $panels = array(); 6 + private $flexLayout = false; 7 + 8 + public function addPanel(PhabricatorWorkpanelView $panel) { 9 + $this->panels[] = $panel; 10 + return $this; 11 + } 12 + 13 + public function setFlexLayout($layout) { 14 + $this->flexLayout = $layout; 15 + return $this; 16 + } 17 + 18 + public function render() { 19 + require_celerity_resource('phabricator-workboard-view-css'); 20 + 21 + $classes = array(); 22 + $classes[] = 'phabricator-workboard-view-inner'; 23 + 24 + if (count($this->panels) > 6) { 25 + throw new Exception("No more than 6 panels per workboard."); 26 + } 27 + 28 + $classes[] = 'workboard-'.count($this->panels).'-up'; 29 + 30 + $view = phutil_tag( 31 + 'div', 32 + array( 33 + 'class' => implode(' ', $classes), 34 + ), 35 + array( 36 + $this->panels, 37 + )); 38 + 39 + $classes = array(); 40 + $classes[] = 'phabricator-workboard-view-outer'; 41 + if ($this->flexLayout) { 42 + $classes[] = 'phabricator-workboard-flex'; 43 + } else { 44 + $classes[] = 'phabricator-workboard-fixed'; 45 + } 46 + 47 + return phutil_tag( 48 + 'div', 49 + array( 50 + 'class' => implode(' ', $classes) 51 + ), 52 + $view); 53 + } 54 + }
+78
src/view/layout/PhabricatorWorkpanelView.php
··· 1 + <?php 2 + 3 + final class PhabricatorWorkpanelView extends AphrontView { 4 + 5 + private $cards = array(); 6 + private $header; 7 + private $headerAction; 8 + private $footerAction; 9 + 10 + public function setCards(PhabricatorObjectItemListView $cards) { 11 + $this->cards[] = $cards; 12 + return $this; 13 + } 14 + 15 + public function setHeader($header) { 16 + $this->header = $header; 17 + return $this; 18 + } 19 + 20 + public function setHeaderAction($header_action) { 21 + $this->headerAction = $header_action; 22 + return $this; 23 + } 24 + 25 + public function setFooterAction($footer_action) { 26 + $this->footerAction = $footer_action; 27 + return $this; 28 + } 29 + 30 + public function render() { 31 + require_celerity_resource('phabricator-workpanel-view-css'); 32 + 33 + $footer = ''; 34 + if ($this->footerAction) { 35 + $action = $this->footerAction; 36 + $footer = javelin_tag( 37 + 'a', 38 + array( 39 + 'href' => $action->getHref(), 40 + 'class' => 'phabricator-workpanel-footer-action', 41 + 'sigil' => $action->getWorkflow() ? 'workflow' : null, 42 + ), 43 + $action->getName()); 44 + } 45 + 46 + $header = phutil_tag( 47 + 'div', 48 + array( 49 + 'class' => 'phabricator-workpanel-header' 50 + ), 51 + $this->header); 52 + 53 + $body = phutil_tag( 54 + 'div', 55 + array( 56 + 'class' => 'phabricator-workpanel-body' 57 + ), 58 + $this->cards); 59 + 60 + $view = phutil_tag( 61 + 'div', 62 + array( 63 + 'class' => 'phabricator-workpanel-view-inner', 64 + ), 65 + array( 66 + $header, 67 + $body, 68 + $footer, 69 + )); 70 + 71 + return phutil_tag( 72 + 'div', 73 + array( 74 + 'class' => 'phabricator-workpanel-view' 75 + ), 76 + $view); 77 + } 78 + }
+54
webroot/rsrc/css/layout/phabricator-workboard-view.css
··· 1 + /** 2 + * @provides phabricator-workboard-view-css 3 + */ 4 + 5 + .phabricator-workboard-view-outer { 6 + padding: 8px; 7 + overflow-x: scroll; 8 + border-radius: 5px; 9 + background: rgba(150,150,150,.1); 10 + box-shadow: inset 0 0 5px rgba(0,0,0,.5); 11 + } 12 + 13 + .device-phone .phabricator-workboard-view-outer { 14 + background: none; 15 + box-shadow: none; 16 + padding: 0; 17 + margin: 0 auto; 18 + width: 100%; 19 + } 20 + 21 + /* math here is based on panel width and margins */ 22 + .phabricator-workboard-fixed 23 + .phabricator-workboard-view-inner.workboard-1-up { 24 + width: 310px; 25 + } 26 + 27 + .phabricator-workboard-fixed 28 + .phabricator-workboard-view-inner.workboard-2-up { 29 + width: 620px; 30 + } 31 + 32 + .phabricator-workboard-fixed 33 + .phabricator-workboard-view-inner.workboard-3-up { 34 + width: 930px; 35 + } 36 + 37 + .phabricator-workboard-fixed 38 + .phabricator-workboard-view-inner.workboard-4-up { 39 + width: 1008px; 40 + } 41 + 42 + .phabricator-workboard-fixed 43 + .phabricator-workboard-view-inner.workboard-5-up { 44 + width: 1250px; 45 + } 46 + 47 + .phabricator-workboard-fixed 48 + .phabricator-workboard-view-inner.workboard-6-up { 49 + width: 1500px; 50 + } 51 + 52 + .device-phone .phabricator-workboard-fixed .phabricator-workboard-view-inner { 53 + width: 100%; 54 + }
+93
webroot/rsrc/css/layout/phabricator-workpanel-view.css
··· 1 + /** 2 + * @provides phabricator-workpanel-view-css 3 + */ 4 + 5 + .phabricator-workpanel-view { 6 + float: left; 7 + } 8 + 9 + .phabricator-workpanel-view-inner { 10 + margin: 0 10px 0 0; 11 + } 12 + 13 + .device-phone .phabricator-workpanel-view-inner { 14 + margin: 0; 15 + } 16 + 17 + .phabricator-workboard-flex .phabricator-workpanel-view:last-child 18 + .phabricator-workpanel-view-inner { 19 + margin: 0; 20 + } 21 + 22 + /* Panels require a fixed width to overflow well. */ 23 + .phabricator-workboard-fixed .workboard-1-up .phabricator-workpanel-view, 24 + .phabricator-workboard-fixed .workboard-2-up .phabricator-workpanel-view, 25 + .phabricator-workboard-fixed .workboard-3-up .phabricator-workpanel-view { 26 + width: 300px; 27 + } 28 + 29 + .phabricator-workboard-fixed .workboard-4-up .phabricator-workpanel-view, 30 + .phabricator-workboard-fixed .workboard-5-up .phabricator-workpanel-view, 31 + .phabricator-workboard-fixed .workboard-6-up .phabricator-workpanel-view { 32 + width: 240px; 33 + } 34 + 35 + .device-phone .phabricator-workboard-view-outer div.phabricator-workpanel-view { 36 + width: 100%; 37 + margin-bottom: 20px; 38 + } 39 + 40 + .phabricator-workpanel-view .phabricator-workpanel-header { 41 + font-size: 14px; 42 + font-weight: bold; 43 + color: #333; 44 + border: 1px solid #b3b5b6; 45 + border-top-left-radius: 5px; 46 + border-top-right-radius: 5px; 47 + padding: 8px 10px; 48 + background: #f0f0f0 url(/rsrc/image/texture/panel-header-gradient.png) repeat-x; 49 + text-shadow: 0 1px 1px #fff; 50 + } 51 + 52 + .phabricator-workpanel-view .phabricator-workpanel-header-action { 53 + float: right; 54 + width: 24px; 55 + border-left: 1px solid #b3b5b6; 56 + } 57 + 58 + .phabricator-workpanel-view .phabricator-workpanel-body { 59 + background: #c4cde0; 60 + padding: 5px 5px 1px 5px; 61 + border-bottom-left-radius: 5px; 62 + border-bottom-right-radius: 5px; 63 + box-shadow: inset 0 0px 5px rgba(0,0,0,.4); 64 + } 65 + 66 + .phabricator-workpanel-view .phabricator-workpanel-footer { 67 + padding: 8px 5px; 68 + } 69 + 70 + /* fluid/flex styles */ 71 + .phabricator-workboard-flex .workboard-1-up .phabricator-workpanel-view { 72 + width: 100%; 73 + } 74 + 75 + .phabricator-workboard-flex .workboard-2-up .phabricator-workpanel-view { 76 + width: 50%; 77 + } 78 + 79 + .phabricator-workboard-flex .workboard-3-up .phabricator-workpanel-view { 80 + width: 33.3333%; 81 + } 82 + 83 + .phabricator-workboard-flex .workboard-4-up .phabricator-workpanel-view { 84 + width: 25%; 85 + } 86 + 87 + .phabricator-workboard-flex .workboard-5-up .phabricator-workpanel-view { 88 + width: 20%; 89 + } 90 + 91 + .phabricator-workboard-flex .workboard-6-up .phabricator-workpanel-view { 92 + width: 16.6666%; 93 + }
webroot/rsrc/image/texture/panel-header-gradient.png

This is a binary file and will not be displayed.