Christopher Johnson (WMDE) has submitted this change and it was merged.

Change subject: updates to upstream D12603 28.04.2015
......................................................................


updates to upstream D12603 28.04.2015

adds SprintUIObjectBox and CSS to enable horizontal scrolling

Bug: T97470
Bug: T94203
Change-Id: I0e05acc938ba581720de7f2277459a0b7490eae4
---
M rsrc/behavior-c3-chart.js
M rsrc/behavior-sprint-boards.js
A rsrc/sprintui-object-box.css
M src/__phutil_library_map__.php
M src/celerity/CeleritySprintResources.php
M src/celerity/map.php
M src/controller/board/SprintBoardBatchEditController.php
M src/controller/board/SprintBoardViewController.php
A src/view/SprintUIObjectBoxView.php
M src/view/burndown/BoardDataPieView.php
M src/view/burndown/BurndownChartView.php
M src/view/reports/OpenTasksView.php
M src/view/reports/SprintReportOpenTasksView.php
M src/view/reports/UserOpenTasksView.php
14 files changed, 583 insertions(+), 116 deletions(-)

Approvals:
  Christopher Johnson (WMDE): Verified; Looks good to me, approved



diff --git a/rsrc/behavior-c3-chart.js b/rsrc/behavior-c3-chart.js
index a1daaee..0e6db1e 100644
--- a/rsrc/behavior-c3-chart.js
+++ b/rsrc/behavior-c3-chart.js
@@ -36,4 +36,3 @@
             }
         });
 });
-
diff --git a/rsrc/behavior-sprint-boards.js b/rsrc/behavior-sprint-boards.js
index aea998d..df13207 100644
--- a/rsrc/behavior-sprint-boards.js
+++ b/rsrc/behavior-sprint-boards.js
@@ -2,7 +2,7 @@
  * @provides javelin-behavior-sprint-boards
  */
 
-JX.behavior('sprint-boards', function(config) {
+JX.behavior('sprint-boards', function(config, statics) {
 
     function finditems(col) {
         return JX.DOM.scry(col, 'li', 'project-card');
@@ -44,8 +44,8 @@
             'project-panel-over-limit': over_limit
         };
         var panel = JX.DOM.findAbove(col, 'div', 'workpanel');
-        for (var k in panel_map) {
-            JX.DOM.alterClass(panel, k, !!panel_map[k]);
+        for (var p in panel_map) {
+            JX.DOM.alterClass(panel, p, !!panel_map[p]);
         }
 
         var color_map = {
@@ -53,8 +53,8 @@
             'phui-tag-shade-blue': (sum > 0 && !over_limit),
             'phui-tag-shade-red': (over_limit)
         };
-        for (var k in color_map) {
-            JX.DOM.alterClass(data.countTagNode, k, !!color_map[k]);
+        for (var c in color_map) {
+            JX.DOM.alterClass(data.countTagNode, c, !!color_map[c]);
         }
     }
 
@@ -65,7 +65,7 @@
     }
 
     function getcolumns() {
-        return JX.DOM.scry(JX.$(config.boardID), 'ul', 'project-column');
+        return JX.DOM.scry(JX.$(statics.boardID), 'ul', 'project-column');
     }
 
     function colsort(u, v) {
@@ -87,7 +87,7 @@
 
     function getcontainer() {
         return JX.DOM.find(
-            JX.$(config.boardID),
+            JX.$(statics.boardID),
             'div',
             'aphront-multi-column-view');
     }
@@ -160,9 +160,9 @@
             data.beforePHID = before_phid;
         }
 
-        data.order = config.order;
+        data.order = statics.order;
 
-        var workflow = new JX.Workflow(config.moveURI, data)
+        var workflow = new JX.Workflow(statics.moveURI, data)
             .setHandler(function(response) {
                 onresponse(response, item, list);
             });
@@ -170,36 +170,12 @@
         workflow.start();
     }
 
-    var lists = [];
-    var ii;
-    var cols = getcolumns();
-
-    for (ii = 0; ii < cols.length; ii++) {
-        var list = new JX.DraggableList('project-card', cols[ii])
-            .setFindItemsHandler(JX.bind(null, finditems, cols[ii]));
-
-        list.listen('didSend', JX.bind(list, onupdate, cols[ii]));
-        list.listen('didReceive', JX.bind(list, onupdate, cols[ii]));
-
-        list.listen('didDrop', JX.bind(null, ondrop, list));
-
-        list.listen('didBeginDrag', JX.bind(null, onbegindrag));
-        list.listen('didEndDrag', JX.bind(null, onenddrag));
-
-        lists.push(list);
-
-        onupdate(cols[ii]);
-    }
-
-    for (ii = 0; ii < lists.length; ii++) {
-        lists[ii].setGroup(lists);
-    }
-
-    var onedit = function(column, r) {
+    function onedit(column, r) {
         var new_card = JX.$H(r.tasks).getNode();
         var new_data = JX.Stratcom.getData(new_card);
         var items = finditems(column);
         var edited = false;
+        var remove_index = null;
 
         for (var ii = 0; ii < items.length; ii++) {
             var item = items[ii];
@@ -208,6 +184,9 @@
             var phid = data.objectPHID;
 
             if (phid == new_data.objectPHID) {
+                if (r.data.removeFromBoard) {
+                    remove_index = ii;
+                }
                 items[ii] = new_card;
                 data = new_data;
                 edited = true;
@@ -222,57 +201,147 @@
             new_data.sort = r.data.sortMap[new_data.objectPHID] || 
new_data.sort;
         }
 
+        if (remove_index !== null) {
+            items.splice(remove_index, 1);
+        }
+
         items.sort(colsort);
 
         JX.DOM.setContent(column, items);
 
         onupdate(column);
-    };
+    }
 
-    JX.Stratcom.listen(
-        'click',
-        ['edit-project-card'],
-        function(e) {
-            e.kill();
-            var column = e.getNode('project-column');
-            var request_data = {
-                responseType: 'card',
-                columnPHID: JX.Stratcom.getData(column).columnPHID,
-                order: config.order
-            };
-            new JX.Workflow(e.getNode('tag:a').href, request_data)
-                .setHandler(JX.bind(null, onedit, column))
-                .start();
-        });
+    function update_statics(update_config) {
+        statics.boardID = update_config.boardID;
+        statics.projectPHID = update_config.projectPHID;
+        statics.order = update_config.order;
+        statics.moveURI = update_config.moveURI;
+        statics.createURI = update_config.createURI;
+    }
 
-    JX.Stratcom.listen(
-        'click',
-        ['column-add-task'],
-        function (e) {
+    function init_board() {
+        var lists = [];
+        var ii;
+        var cols = getcolumns();
 
-            // We want the 'boards-dropdown-menu' behavior to see this event 
and
-            // close the dropdown, but don't want to follow the link.
-            e.prevent();
+        for (ii = 0; ii < cols.length; ii++) {
+            var list = new JX.DraggableList('project-card', cols[ii])
+                .setFindItemsHandler(JX.bind(null, finditems, cols[ii]));
 
-            var column_phid = e.getNodeData('column-add-task').columnPHID;
-            var request_data = {
-                responseType: 'card',
-                columnPHID: column_phid,
-                projects: config.projectPHID,
-                order: config.order
-            };
-            var cols = getcolumns();
-            var ii;
-            var column;
-            for (ii = 0; ii < cols.length; ii++) {
-                if (JX.Stratcom.getData(cols[ii]).columnPHID == column_phid) {
-                    column = cols[ii];
-                    break;
+            list.listen('didSend', JX.bind(list, onupdate, cols[ii]));
+            list.listen('didReceive', JX.bind(list, onupdate, cols[ii]));
+
+            list.listen('didDrop', JX.bind(null, ondrop, list));
+
+            list.listen('didBeginDrag', JX.bind(null, onbegindrag));
+            list.listen('didEndDrag', JX.bind(null, onenddrag));
+
+            lists.push(list);
+
+            onupdate(cols[ii]);
+        }
+
+        for (ii = 0; ii < lists.length; ii++) {
+            lists[ii].setGroup(lists);
+        }
+
+        JX.Stratcom.listen(
+            'click',
+            ['edit-project-card'],
+            function(e) {
+                e.kill();
+                var column = e.getNode('project-column');
+                var request_data = {
+                    responseType: 'card',
+                    columnPHID: JX.Stratcom.getData(column).columnPHID,
+                    order: statics.order
+                };
+                new JX.Workflow(e.getNode('tag:a').href, request_data)
+                    .setHandler(JX.bind(null, onedit, column))
+                    .start();
+            });
+
+        JX.Stratcom.listen(
+            'click',
+            ['column-add-task'],
+            function (e) {
+
+                // We want the 'boards-dropdown-menu' behavior to see this 
event and
+                // close the dropdown, but don't want to follow the link.
+                e.prevent();
+
+                var column_phid = e.getNodeData('column-add-task').columnPHID;
+                var request_data = {
+                    responseType: 'card',
+                    columnPHID: column_phid,
+                    projects: statics.projectPHID,
+                    order: statics.order
+                };
+                var cols = getcolumns();
+                var ii;
+                var column;
+                for (ii = 0; ii < cols.length; ii++) {
+                    if (JX.Stratcom.getData(cols[ii]).columnPHID == 
column_phid) {
+                        column = cols[ii];
+                        break;
+                    }
                 }
+                new JX.Workflow(statics.createURI, request_data)
+                    .setHandler(JX.bind(null, onedit, column))
+                    .start();
+            });
+
+        JX.Stratcom.listen('click', 'boards-dropdown-menu', function(e) {
+            var data = e.getNodeData('boards-dropdown-menu');
+            if (data.menu) {
+                return;
             }
-            new JX.Workflow(config.createURI, request_data)
-                .setHandler(JX.bind(null, onedit, column))
-                .start();
+
+            e.kill();
+
+            var list = JX.$H(data.items).getFragment().firstChild;
+
+            var button = e.getNode('boards-dropdown-menu');
+            data.menu = new JX.PHUIXDropdownMenu(button);
+            data.menu.setContent(list);
+            data.menu.open();
+
+            JX.DOM.listen(list, 'click', 'tag:a', function(e) {
+                if (!e.isNormalClick()) {
+                    return;
+                }
+                data.menu.close();
+            });
         });
 
+        JX.Stratcom.listen(
+            'quicksand-redraw',
+            null,
+            function (e) {
+                var data = e.getData();
+                if (!data.newResponse.boardConfig) {
+                    return;
+                }
+                var new_config;
+                if (data.fromServer) {
+                    new_config = data.newResponse.boardConfig;
+                    statics.boardConfigCache[data.newResponseID] = new_config;
+                } else {
+                    new_config = statics.boardConfigCache[data.newResponseID];
+                    statics.boardID = new_config.boardID;
+                }
+                update_statics(new_config);
+            });
+        return true;
+    }
+
+    if (!statics.setup) {
+        update_statics(config);
+        var current_page_id = JX.Quicksand.getCurrentPageID();
+        statics.boardConfigCache = {};
+        statics.boardConfigCache[current_page_id] = config;
+        statics.setup = init_board();
+    }
+
 });
diff --git a/rsrc/sprintui-object-box.css b/rsrc/sprintui-object-box.css
new file mode 100644
index 0000000..56cfd89
--- /dev/null
+++ b/rsrc/sprintui-object-box.css
@@ -0,0 +1,74 @@
+/**
+ * @provides sprintui-object-box-css
+ */
+
+.sprintui-object-box {
+    position: relative;
+    overflow-x: scroll;
+    overflow-y:hidden;
+}
+
+div.phui-object-box.phui-object-box-flush {
+    margin-top: 0;
+}
+
+.phui-object-box .phui-header-shell {
+    padding: 4px 5px 4px 12px;
+border-bottom: 1px solid {$lightblueborder};
+border-top: none;
+}
+
+.phui-object-box .phui-header-image {
+    margin: 1px 8px -7px -7px;
+}
+
+.phui-object-box .phui-header-shell h1 {
+    text-shadow: 0 1px #fff;
+    padding: 8px 0;
+}
+
+.phui-object-box .phui-header-shell + .phui-info-view {
+    margin: 0;
+    border-width: 0;
+border-bottom: 1px solid {$lightblueborder};
+}
+
+.device-phone .phui-object-box {
+    margin: 8px 8px 0 8px;
+}
+
+.phui-box-border.phui-object-box-lightgreen {
+border: 1px solid {$lightgreenborder};
+border-bottom: 1px solid {$greenborder};
+}
+
+.phui-box-border.phui-object-box-lightgreen .phui-action-header {
+border-bottom: 1px solid {$lightgreenborder};
+}
+
+.phui-box-border.phui-object-box-lightblue {
+border: 1px solid {$lightblueborder};
+border-bottom: 1px solid {$blueborder};
+}
+
+.phui-box-border.phui-object-box-lightblue .phui-action-header {
+border-bottom: 1px solid {$lightblueborder};
+}
+
+.phui-box-border.phui-object-box-lightred {
+border: 1px solid {$lightredborder};
+border-bottom: 1px solid {$redborder};
+}
+
+.phui-box-border.phui-object-box-lightred .phui-action-header {
+border-bottom: 1px solid {$lightredborder};
+}
+
+.phui-box-border.phui-object-box-lightviolet {
+border: 1px solid {$lightvioletborder};
+border-bottom: 1px solid {$violetborder};
+}
+
+.phui-box-border.phui-object-box-lightviolet .phui-action-header {
+border-bottom: 1px solid {$lightvioletborder};
+}
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
index 0fd9367..aa783ce 100644
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -68,6 +68,7 @@
     'SprintTableView' => 'view/SprintTableView.php',
     'SprintTaskStoryPointsField' => 
'customfield/SprintTaskStoryPointsField.php',
     'SprintTestCase' => 'tests/SprintTestCase.php',
+    'SprintUIObjectBoxView' => 'view/SprintUIObjectBoxView.php',
     'SprintValidator' => 'util/SprintValidator.php',
     'SprintView' => 'view/SprintView.php',
     'TaskTableDataProvider' => 'storage/TaskTableDataProvider.php',
@@ -125,6 +126,7 @@
       'PhabricatorStandardCustomFieldInterface',
     ),
     'SprintTestCase' => 'PHPUnit_Framework_TestCase',
+    'SprintUIObjectBoxView' => 'AphrontView',
     'SprintView' => 'AphrontView',
     'UserOpenTasksView' => 'OpenTasksView',
   ),
diff --git a/src/celerity/CeleritySprintResources.php 
b/src/celerity/CeleritySprintResources.php
index b448183..c885e42 100644
--- a/src/celerity/CeleritySprintResources.php
+++ b/src/celerity/CeleritySprintResources.php
@@ -25,4 +25,3 @@
   }
 
 }
-
diff --git a/src/celerity/map.php b/src/celerity/map.php
index ad3c084..9148118 100644
--- a/src/celerity/map.php
+++ b/src/celerity/map.php
@@ -9,24 +9,25 @@
   'names' => array(
     'behavior-board-data-pie.js' => 'a1302bf1',
     'behavior-burndown-report-chart.js' => '631b0017',
-    'behavior-c3-chart.js' => '36bdb7ef',
+    'behavior-c3-chart.js' => '0fe21223',
     'behavior-c3-pie.js' => 'ae804fb1',
     'behavior-events-table.js' => 'f202fb99',
     'behavior-priority-pie.js' => 'f72c0144',
-    'behavior-sprint-boards.js' => 'b2754b95',
-    'behavior-sprint-table.js' => '01ed4a30',
+    'behavior-sprint-boards.js' => '034c8e2a',
+    'behavior-sprint-table.js' => '7fb99402',
     'behavior-tasks-table.js' => '60d7b7fb',
-    'c3.css' => 'cc484ff6',
+    'c3.css' => '1cf719ad',
     'c3.js' => '1997878e',
     'd3.min.js' => '97b28f9e',
-    'dataTables.css' => '1239d5f5',
+    'dataTables.css' => 'b74437b2',
     'dataTables.tableTools.css' => '380aa862',
     'dataTables.tableTools.js' => '69919d95',
     'images/Screenshot-1.png' => '500c0ca0',
     'jquery-1.11.2.js' => '75fa3fcc',
     'jquery.dataTables.js' => 'faddf310',
-    'phui-workboard-view.css' => '24307748',
+    'phui-workboard-view.css' => '4f0fb320',
     'sprint-report.css' => 'f6959ade',
+    'sprintui-object-box.css' => '287505a8',
     'webroot-static/copy_csv_xls.swf' => 'fcbb02cb',
     'webroot-static/sort_asc.png' => '68adbacc',
     'webroot-static/sort_both.png' => '9c425f1b',
@@ -34,23 +35,24 @@
   ),
   'symbols' => array(
     'c3' => '1997878e',
-    'c3-css' => 'cc484ff6',
+    'c3-css' => '1cf719ad',
     'd3' => '97b28f9e',
     'dataTables' => 'faddf310',
-    'dataTables-css' => '1239d5f5',
+    'dataTables-css' => 'b74437b2',
     'dataTables.tableTools' => '69919d95',
     'javelin-behavior-burndown-report-chart' => '631b0017',
     'javelin-behavior-c3-board-data-pie' => 'a1302bf1',
-    'javelin-behavior-c3-chart' => '36bdb7ef',
+    'javelin-behavior-c3-chart' => '0fe21223',
     'javelin-behavior-c3-pie' => 'ae804fb1',
     'javelin-behavior-events-table' => 'f202fb99',
     'javelin-behavior-priority-pie' => 'f72c0144',
-    'javelin-behavior-sprint-boards' => 'b2754b95',
-    'javelin-behavior-sprint-table' => '01ed4a30',
+    'javelin-behavior-sprint-boards' => '034c8e2a',
+    'javelin-behavior-sprint-table' => '7fb99402',
     'javelin-behavior-tasks-table' => '60d7b7fb',
     'jquery' => '75fa3fcc',
-    'phui-workboard-view-css' => '24307748',
+    'phui-workboard-view-css' => '4f0fb320',
     'sprint-report-css' => 'f6959ade',
+    'sprintui-object-box-css' => '287505a8',
     'tableTools-css' => '380aa862',
   ),
   'requires' => array(
diff --git a/src/controller/board/SprintBoardBatchEditController.php 
b/src/controller/board/SprintBoardBatchEditController.php
index 91526bc..0038dc5 100644
--- a/src/controller/board/SprintBoardBatchEditController.php
+++ b/src/controller/board/SprintBoardBatchEditController.php
@@ -265,8 +265,8 @@
             continue 2;
           }
           $value = head($value);
-          $no_owner = ManiphestNoOwnerDatasource::FUNCTION_TOKEN;
-          if ($value === ManiphestNoOwnerDatasource::FUNCTION_TOKEN) {
+          $no_owner = PhabricatorPeopleNoOwnerDatasource::FUNCTION_TOKEN;
+          if ($value === $no_owner) {
             $value = null;
           }
           break;
diff --git a/src/controller/board/SprintBoardViewController.php 
b/src/controller/board/SprintBoardViewController.php
index 8d6f315..378463e 100755
--- a/src/controller/board/SprintBoardViewController.php
+++ b/src/controller/board/SprintBoardViewController.php
@@ -165,7 +165,10 @@
     $task_query = $engine->buildQueryFromSavedQuery($saved);
 
     $tasks = $task_query
-      ->addWithAllProjects(array($project->getPHID()))
+        ->withEdgeLogicPHIDs(
+            PhabricatorProjectObjectHasProjectEdgeType::EDGECONST,
+            PhabricatorQueryConstraint::OPERATOR_AND,
+            array($project->getPHID()))
       ->setOrderBy(ManiphestTaskQuery::ORDER_PRIORITY)
       ->setViewer($viewer)
       ->execute();
@@ -272,25 +275,29 @@
       ->setID($board_id);
 
     if ($is_sprint == true) {
-      Javelin::initBehavior(
-          'sprint-boards',
-          array(
+      $behavior_config = array(
               'boardID' => $board_id,
               'projectPHID' => $project->getPHID(),
               'moveURI' => 
$this->getApplicationURI('move/'.$project->getID().'/'),
               'createURI' => '/project/sprint/board/task/create/',
               'order' => $this->sortKey,
-          ), 'sprint');
+          );
+      $this->initSprintBehavior(
+          'sprint-boards',
+          $behavior_config);
+      $this->addExtraQuickSandConfig(array('boardConfig' => $behavior_config));
     } else {
+      $behavior_config = array(
+          'boardID' => $board_id,
+          'projectPHID' => $project->getPHID(),
+          'moveURI' => $this->getApplicationURI('move/'.$project->getID().'/'),
+          'createURI' => '/maniphest/task/create/',
+          'order' => $this->sortKey,
+      );
       $this->initBehavior(
           'project-boards',
-          array(
-              'boardID' => $board_id,
-              'projectPHID' => $project->getPHID(),
-              'moveURI' => 
$this->getApplicationURI('move/'.$project->getID().'/'),
-              'createURI' => '/maniphest/task/create/',
-              'order' => $this->sortKey,
-          ));
+          $behavior_config);
+      $this->addExtraQuickSandConfig(array('boardConfig' => $behavior_config));
     }
 
     $this->handles = ManiphestTaskListView::loadTaskHandles($viewer, $tasks);
@@ -368,10 +375,6 @@
       $board->addPanel($panel);
     }
 
-    Javelin::initBehavior(
-      'boards-dropdown',
-      array());
-
     $sort_menu = $this->buildSortMenu(
       $viewer,
       $sort_key);
@@ -409,9 +412,7 @@
     $nav->appendChild($board_box);
 
     return $this->buildApplicationPage(
-      array(
         $nav,
-      ),
       array(
         'title' => pht('%s Board', $project->getName()),
         'showFooter' => false,
@@ -773,4 +774,11 @@
     return $base;
   }
 
+  public function initSprintBehavior($name, $config = array()) {
+    Javelin::initBehavior(
+        $name,
+        $config,
+        'sprint');
+  }
+
 }
diff --git a/src/view/SprintUIObjectBoxView.php 
b/src/view/SprintUIObjectBoxView.php
new file mode 100644
index 0000000..824b185
--- /dev/null
+++ b/src/view/SprintUIObjectBoxView.php
@@ -0,0 +1,314 @@
+<?php
+
+final class SprintUIObjectBoxView extends AphrontView {
+
+  private $headerText;
+  private $headerColor;
+  private $formErrors = null;
+  private $formSaved = false;
+  private $infoView;
+  private $form;
+  private $validationException;
+  private $header;
+  private $flush;
+  private $id;
+  private $sigils = array();
+  private $metadata;
+  private $actionListID;
+
+  private $tabs = array();
+  private $propertyLists = array();
+
+  public function addSigil($sigil) {
+    $this->sigils[] = $sigil;
+    return $this;
+  }
+
+  public function setMetadata(array $metadata) {
+    $this->metadata = $metadata;
+    return $this;
+  }
+
+  public function addPropertyList(
+      PHUIPropertyListView $property_list,
+      $tab = null) {
+
+    if (!($tab instanceof PHUIListItemView) &&
+        ($tab !== null)) {
+      assert_stringlike($tab);
+      $tab = id(new PHUIListItemView())->setName($tab);
+    }
+
+    if ($tab) {
+      if ($tab->getKey()) {
+        $key = $tab->getKey();
+      } else {
+        $key = 'tab.default.'.spl_object_hash($tab);
+        $tab->setKey($key);
+      }
+    } else {
+      $key = 'tab.default';
+    }
+
+    if ($tab) {
+      if (empty($this->tabs[$key])) {
+        $tab->addSigil('phui-object-box-tab');
+        $tab->setMetadata(
+            array(
+                'tabKey' => $key,
+            ));
+
+        if (!$tab->getHref()) {
+          $tab->setHref('#');
+        }
+
+        if (!$tab->getType()) {
+          $tab->setType(PHUIListItemView::TYPE_LINK);
+        }
+
+        $this->tabs[$key] = $tab;
+      }
+    }
+
+    $this->propertyLists[$key][] = $property_list;
+
+    $action_list = $property_list->getActionList();
+    if ($action_list) {
+      $this->actionListID = celerity_generate_unique_node_id();
+      $action_list->setId($this->actionListID);
+    }
+
+    return $this;
+  }
+
+  public function setHeaderText($text) {
+    $this->headerText = $text;
+    return $this;
+  }
+
+  public function setHeaderColor($color) {
+    $this->headerColor = $color;
+    return $this;
+  }
+
+  public function setFormErrors(array $errors, $title = null) {
+    if ($errors) {
+      $this->formErrors = id(new PHUIInfoView())
+          ->setTitle($title)
+          ->setErrors($errors);
+    }
+    return $this;
+  }
+
+  public function setFormSaved($saved, $text = null) {
+    if (!$text) {
+      $text = pht('Changes saved.');
+    }
+    if ($saved) {
+      $save = id(new PHUIInfoView())
+          ->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
+          ->appendChild($text);
+      $this->formSaved = $save;
+    }
+    return $this;
+  }
+
+  public function setInfoView(PHUIInfoView $view) {
+    $this->infoView = $view;
+    return $this;
+  }
+
+  public function setForm($form) {
+    $this->form = $form;
+    return $this;
+  }
+
+  public function setID($id) {
+    $this->id = $id;
+    return $this;
+  }
+
+  public function setHeader($header) {
+    $this->header = $header;
+    return $this;
+  }
+
+  public function setFlush($flush) {
+    $this->flush = $flush;
+    return $this;
+  }
+
+  public function setValidationException(
+      PhabricatorApplicationTransactionValidationException $ex = null) {
+    $this->validationException = $ex;
+    return $this;
+  }
+
+  public function render() {
+
+    require_celerity_resource('sprintui-object-box-css', 'sprint');
+
+    if ($this->headerColor) {
+      $header_color = $this->headerColor;
+    } else {
+      $header_color = PHUIActionHeaderView::HEADER_LIGHTBLUE;
+    }
+
+    if ($this->header) {
+      $header = $this->header;
+      $header->setHeaderColor($header_color);
+    } else {
+      $header = id(new PHUIHeaderView())
+          ->setHeader($this->headerText)
+          ->setHeaderColor($header_color);
+    }
+
+    if ($this->actionListID) {
+      $icon_id = celerity_generate_unique_node_id();
+      $icon = id(new PHUIIconView())
+          ->setIconFont('fa-bars');
+      $meta = array(
+          'map' => array(
+              $this->actionListID => 'phabricator-action-list-toggle',
+              $icon_id => 'phuix-dropdown-open',
+          ),
+      );
+      $mobile_menu = id(new PHUIButtonView())
+          ->setTag('a')
+          ->setText(pht('Actions'))
+          ->setHref('#')
+          ->setIcon($icon)
+          ->addClass('phui-mobile-menu')
+          ->setID($icon_id)
+          ->addSigil('jx-toggle-class')
+          ->setMetadata($meta);
+      $header->addActionLink($mobile_menu);
+    }
+
+    $ex = $this->validationException;
+    $exception_errors = null;
+    if ($ex) {
+      $messages = array();
+      foreach ($ex->getErrors() as $error) {
+        $messages[] = $error->getMessage();
+      }
+      if ($messages) {
+        $exception_errors = id(new PHUIInfoView())
+            ->setErrors($messages);
+      }
+    }
+
+    $tab_lists = array();
+    $property_lists = array();
+    $tab_map = array();
+
+    $default_key = 'tab.default';
+
+    // Find the selected tab, or select the first tab if none are selected.
+    if ($this->tabs) {
+      $selected_tab = null;
+      foreach ($this->tabs as $key => $tab) {
+        if ($tab->getSelected()) {
+          $selected_tab = $key;
+          break;
+        }
+      }
+      if ($selected_tab === null) {
+        head($this->tabs)->setSelected(true);
+        $selected_tab = head_key($this->tabs);
+      }
+    }
+
+    foreach ($this->propertyLists as $key => $list) {
+      $group = new PHUIPropertyGroupView();
+      $i = 0;
+      foreach ($list as $item) {
+        $group->addPropertyList($item);
+        if ($i > 0) {
+          $item->addClass('phui-property-list-section-noninitial');
+        }
+        $i++;
+      }
+
+      if ($this->tabs && $key != $default_key) {
+        $tab_id = celerity_generate_unique_node_id();
+        $tab_map[$key] = $tab_id;
+
+        if ($key === $selected_tab) {
+          $style = null;
+        } else {
+          $style = 'display: none';
+        }
+
+        $tab_lists[] = phutil_tag(
+            'div',
+            array(
+                'style' => $style,
+                'id' => $tab_id,
+            ),
+            $group);
+      } else {
+        if ($this->tabs) {
+          $group->addClass('phui-property-group-noninitial');
+        }
+        $property_lists[] = $group;
+      }
+    }
+
+    $tabs = null;
+    if ($this->tabs) {
+      $tabs = id(new PHUIListView())
+          ->setType(PHUIListView::NAVBAR_LIST);
+      foreach ($this->tabs as $tab) {
+        $tabs->addMenuItem($tab);
+      }
+
+      Javelin::initBehavior('phui-object-box-tabs');
+    }
+
+    $content = id(new PHUIBoxView())
+        ->appendChild(
+            array(
+                $header,
+                $this->infoView,
+                $this->formErrors,
+                $this->formSaved,
+                $exception_errors,
+                $this->form,
+                $tabs,
+                $tab_lists,
+                $property_lists,
+                $this->renderChildren(),
+            ))
+        ->setBorder(true)
+        ->setID($this->id)
+        ->addMargin(PHUI::MARGIN_LARGE_TOP)
+        ->addMargin(PHUI::MARGIN_LARGE_LEFT)
+        ->addMargin(PHUI::MARGIN_LARGE_RIGHT)
+        ->addClass('sprintui-object-box');
+
+    if ($this->tabs) {
+      $content->addSigil('sprintui-object-box');
+      $content->setMetadata(
+          array(
+              'tabMap' => $tab_map,
+          ));
+    }
+
+    if ($this->flush) {
+      $content->addClass('phui-object-box-flush');
+    }
+
+    $content->addClass('sprintui-object-box-'.$header_color);
+
+    foreach ($this->sigils as $sigil) {
+      $content->addSigil($sigil);
+    }
+
+    if ($this->metadata !== null) {
+      $content->setMetadata($this->metadata);
+    }
+
+    return $content;
+  }
+}
diff --git a/src/view/burndown/BoardDataPieView.php 
b/src/view/burndown/BoardDataPieView.php
index 3674893..ca1653a 100644
--- a/src/view/burndown/BoardDataPieView.php
+++ b/src/view/burndown/BoardDataPieView.php
@@ -33,7 +33,7 @@
             margin-left: 900px;',
         ), pht('Task Priority'));
 
-    $box = id(new PHUIObjectBoxView())
+    $box = id(new SprintUIObjectBoxView())
         ->setHeaderText(pht('Points Allocation Report for '.
             $project_name))
         ->appendChild($boardpie)
diff --git a/src/view/burndown/BurndownChartView.php 
b/src/view/burndown/BurndownChartView.php
index 149cf29..b6643b2 100644
--- a/src/view/burndown/BurndownChartView.php
+++ b/src/view/burndown/BurndownChartView.php
@@ -31,12 +31,11 @@
         'pointstoday' => $pointstoday,
     ), 'sprint');
 
-    $chart = id(new PHUIObjectBoxView())
-        ->setHeaderText(pht('Burndown for '.$project_name))
+    $chart = id(new SprintUIObjectBoxView())->setHeaderText(pht('Burndown for 
'.$project_name))
         ->appendChild(phutil_tag('div',
             array(
                 'id' => 'chart',
-                'style' => 'width: 100%; height:450px',
+                'style' => 'width: 100%; height:450px;',
             ), ''));
 
     return $chart;
diff --git a/src/view/reports/OpenTasksView.php 
b/src/view/reports/OpenTasksView.php
index e5d3f80..648566e 100644
--- a/src/view/reports/OpenTasksView.php
+++ b/src/view/reports/OpenTasksView.php
@@ -5,4 +5,3 @@
   abstract public function execute($tasks, $recently_closed, $date);
 
 }
-
diff --git a/src/view/reports/SprintReportOpenTasksView.php 
b/src/view/reports/SprintReportOpenTasksView.php
index c0b2ee0..c7a4856 100644
--- a/src/view/reports/SprintReportOpenTasksView.php
+++ b/src/view/reports/SprintReportOpenTasksView.php
@@ -391,7 +391,10 @@
     $query = id(new ManiphestTaskQuery())
         ->setViewer($user)
         ->needProjectPHIDs(true)
-        ->withAnyProjects($phids)
+        ->withEdgeLogicPHIDs(
+            PhabricatorProjectObjectHasProjectEdgeType::EDGECONST,
+            PhabricatorQueryConstraint::OPERATOR_OR,
+            $phids)
         ->withStatuses(ManiphestTaskStatus::getOpenStatusConstants());
     $tasks = $query->execute();
     return $tasks;
diff --git a/src/view/reports/UserOpenTasksView.php 
b/src/view/reports/UserOpenTasksView.php
index 39017e1..b065d5c 100644
--- a/src/view/reports/UserOpenTasksView.php
+++ b/src/view/reports/UserOpenTasksView.php
@@ -20,4 +20,3 @@
     return array ( $leftover, $leftover_closed, $base_link, $leftover_name, 
$col_header, $header, $result_closed, $result );
   }
 }
-

-- 
To view, visit https://gerrit.wikimedia.org/r/207415
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I0e05acc938ba581720de7f2277459a0b7490eae4
Gerrit-PatchSet: 3
Gerrit-Project: phabricator/extensions/Sprint
Gerrit-Branch: master
Gerrit-Owner: Christopher Johnson (WMDE) <[email protected]>
Gerrit-Reviewer: Christopher Johnson (WMDE) <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to