diff --git a/resources/celerity/map.php b/resources/celerity/map.php --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -148,6 +148,7 @@ 'rsrc/css/phui/phui-tag-view.css' => '402691cc', 'rsrc/css/phui/phui-text.css' => 'cf019f54', 'rsrc/css/phui/phui-timeline-view.css' => 'f1bccf73', + 'rsrc/css/phui/phui-two-column-view.css' => 'add0a7d1', 'rsrc/css/phui/phui-workboard-view.css' => '6704d68d', 'rsrc/css/phui/phui-workpanel-view.css' => 'adec7699', 'rsrc/css/sprite-login.css' => '1ebb9bf9', @@ -801,6 +802,7 @@ 'phui-text-css' => 'cf019f54', 'phui-theme-css' => '6b451f24', 'phui-timeline-view-css' => 'f1bccf73', + 'phui-two-column-view-css' => 'add0a7d1', 'phui-workboard-view-css' => '6704d68d', 'phui-workpanel-view-css' => 'adec7699', 'phuix-action-list-view' => 'b5c256b8', diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1406,6 +1406,7 @@ 'PHUITimelineEventView' => 'view/phui/PHUITimelineEventView.php', 'PHUITimelineExample' => 'applications/uiexample/examples/PHUITimelineExample.php', 'PHUITimelineView' => 'view/phui/PHUITimelineView.php', + 'PHUITwoColumnView' => 'view/phui/PHUITwoColumnView.php', 'PHUITypeaheadExample' => 'applications/uiexample/examples/PHUITypeaheadExample.php', 'PHUIWorkboardView' => 'view/phui/PHUIWorkboardView.php', 'PHUIWorkpanelView' => 'view/phui/PHUIWorkpanelView.php', @@ -5183,6 +5184,7 @@ 'PHUITimelineEventView' => 'AphrontView', 'PHUITimelineExample' => 'PhabricatorUIExample', 'PHUITimelineView' => 'AphrontView', + 'PHUITwoColumnView' => 'AphrontTagView', 'PHUITypeaheadExample' => 'PhabricatorUIExample', 'PHUIWorkboardView' => 'AphrontTagView', 'PHUIWorkpanelView' => 'AphrontTagView', diff --git a/src/applications/ponder/constants/PonderQuestionStatus.php b/src/applications/ponder/constants/PonderQuestionStatus.php --- a/src/applications/ponder/constants/PonderQuestionStatus.php +++ b/src/applications/ponder/constants/PonderQuestionStatus.php @@ -26,6 +26,16 @@ return idx($map, $status, pht('Unknown')); } + public static function getQuestionStatusName($status) { + $map = array( + self::STATUS_OPEN => pht('Open'), + self::STATUS_CLOSED_RESOLVED => pht('Resolved'), + self::STATUS_CLOSED_OBSOLETE => pht('Obsolete'), + self::STATUS_CLOSED_DUPLICATE => pht('Duplicate'), + ); + return idx($map, $status, pht('Unknown')); + } + public static function getQuestionStatusDescription($status) { $map = array( self::STATUS_OPEN => diff --git a/src/applications/ponder/controller/PonderQuestionViewController.php b/src/applications/ponder/controller/PonderQuestionViewController.php --- a/src/applications/ponder/controller/PonderQuestionViewController.php +++ b/src/applications/ponder/controller/PonderQuestionViewController.php @@ -10,6 +10,7 @@ ->setViewer($viewer) ->withIDs(array($id)) ->needAnswers(true) + ->needProjectPHIDs(true) ->executeOne(); if (!$question) { return new Aphront404Response(); @@ -51,6 +52,7 @@ $actions = $this->buildActionListView($question); $properties = $this->buildPropertyListView($question, $actions); + $sidebar = $this->buildSidebar($question); $object_box = id(new PHUIObjectBoxView()) ->setHeader($header) @@ -59,21 +61,19 @@ $crumbs = $this->buildApplicationCrumbs($this->buildSideNavView()); $crumbs->addTextCrumb('Q'.$id, '/Q'.$id); - $ponder_view = phutil_tag( - 'div', - array( - 'class' => 'ponder-question-view', - ), - array( - $crumbs, - $object_box, - $question_xactions, - $answers, - $answer_add_panel, - )); + $ponder_view = id(new PHUITwoColumnView()) + ->setMainColumn(array( + $object_box, + $question_xactions, + $answers, + $answer_add_panel, + )) + ->setSideColumn($sidebar) + ->addClass('ponder-question-view'); return $this->buildApplicationPage( array( + $crumbs, $ponder_view, ), array( @@ -410,4 +410,46 @@ return array($show, $hide); } + private function buildSidebar(PonderQuestion $question) { + $viewer = $this->getViewer(); + $status = $question->getStatus(); + $id = $question->getID(); + + $questions = id(new PonderQuestionQuery()) + ->setViewer($viewer) + ->withStatuses(array($status)) + ->withEdgeLogicPHIDs( + PhabricatorProjectObjectHasProjectEdgeType::EDGECONST, + PhabricatorQueryConstraint::OPERATOR_OR, + $question->getProjectPHIDs()) + ->setLimit(10) + ->execute(); + + $list = id(new PHUIObjectItemListView()) + ->setUser($viewer) + ->setNoDataString(pht('No similar questions found.')); + + foreach ($questions as $question) { + if ($id == $question->getID()) { + continue; + } + $item = new PHUIObjectItemView(); + $item->setObjectName('Q'.$question->getID()); + $item->setHeader($question->getTitle()); + $item->setHref('/Q'.$question->getID()); + $item->setObject($question); + + $item->addAttribute( + pht('%d Answer(s)', $question->getAnswerCount())); + + $list->addItem($item); + } + + $box = id(new PHUIObjectBoxView()) + ->setHeaderText(pht('Similar Questions')) + ->setObjectList($list); + + return $box; + } + } diff --git a/src/view/phui/PHUITwoColumnView.php b/src/view/phui/PHUITwoColumnView.php new file mode 100644 --- /dev/null +++ b/src/view/phui/PHUITwoColumnView.php @@ -0,0 +1,48 @@ +mainColumn = $main; + return $this; + } + + public function setSideColumn($side) { + $this->sideColumn = $side; + return $this; + } + + protected function getTagAttributes() { + return array( + 'class' => 'phui-two-column-view grouped', + ); + } + + protected function getTagContent() { + require_celerity_resource('phui-two-column-view-css'); + + $main = phutil_tag( + 'div', + array( + 'class' => 'phui-main-column', + ), + $this->mainColumn); + + $side = phutil_tag( + 'div', + array( + 'class' => 'phui-side-column', + ), + $this->sideColumn); + + return phutil_tag_div( + 'phui-two-column-row', + array( + $main, + $side, + )); + } +} diff --git a/webroot/rsrc/css/phui/phui-two-column-view.css b/webroot/rsrc/css/phui/phui-two-column-view.css new file mode 100644 --- /dev/null +++ b/webroot/rsrc/css/phui/phui-two-column-view.css @@ -0,0 +1,33 @@ +/** + * @provides phui-two-column-view-css + */ + +.phui-two-column-view { + display: table; + width: 100%; +} + +.phui-two-column-row { + display: table-row; +} + +.device-desktop .phui-two-column-view .phui-main-column { + display: table-cell; + vertical-align: top; +} + +.device-desktop .phui-two-column-view .phui-side-column { + width: 320px; + display: table-cell; + vertical-align: top; +} + +.device-desktop .phui-two-column-view + .phui-main-column .phui-object-box:first-child { + margin: 0 16px 0 16px; +} + +.device-desktop .phui-two-column-view + .phui-side-column .phui-object-box:first-child { + margin: 0 16px 16px 0; +}