diff --git a/src/applications/dashboard/controller/PhabricatorDashboardPanelViewController.php b/src/applications/dashboard/controller/PhabricatorDashboardPanelViewController.php index 9d33d0a638..91e664a9ae 100644 --- a/src/applications/dashboard/controller/PhabricatorDashboardPanelViewController.php +++ b/src/applications/dashboard/controller/PhabricatorDashboardPanelViewController.php @@ -1,173 +1,180 @@ id = $data['id']; } public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); $panel = id(new PhabricatorDashboardPanelQuery()) ->setViewer($viewer) ->withIDs(array($this->id)) ->executeOne(); if (!$panel) { return new Aphront404Response(); } $title = $panel->getMonogram().' '.$panel->getName(); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb( pht('Panels'), $this->getApplicationURI('panel/')); $crumbs->addTextCrumb($panel->getMonogram()); $header = $this->buildHeaderView($panel); $actions = $this->buildActionView($panel); $properties = $this->buildPropertyView($panel); $timeline = $this->buildTransactionTimeline( $panel, new PhabricatorDashboardPanelTransactionQuery()); $timeline->setShouldTerminate(true); $properties->setActionList($actions); $box = id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($properties); $rendered_panel = id(new PhabricatorDashboardPanelRenderingEngine()) ->setViewer($viewer) ->setPanel($panel) ->setParentPanelPHIDs(array()) ->renderPanel(); $view = id(new PHUIBoxView()) ->addMargin(PHUI::MARGIN_LARGE_LEFT) ->addMargin(PHUI::MARGIN_LARGE_RIGHT) ->addMargin(PHUI::MARGIN_LARGE_TOP) ->appendChild($rendered_panel); return $this->buildApplicationPage( array( $crumbs, $box, $view, $timeline, ), array( 'title' => $title, )); } private function buildHeaderView(PhabricatorDashboardPanel $panel) { $viewer = $this->getRequest()->getUser(); - return id(new PHUIHeaderView()) + $header = id(new PHUIHeaderView()) ->setUser($viewer) ->setHeader($panel->getName()) ->setPolicyObject($panel); + + if (!$panel->getIsArchived()) { + $header->setStatus('fa-check', 'bluegrey', pht('Active')); + } else { + $header->setStatus('fa-ban', 'red', pht('Archived')); + } + return $header; } private function buildActionView(PhabricatorDashboardPanel $panel) { $viewer = $this->getRequest()->getUser(); $id = $panel->getID(); $actions = id(new PhabricatorActionListView()) ->setObjectURI('/'.$panel->getMonogram()) ->setUser($viewer); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $panel, PhabricatorPolicyCapability::CAN_EDIT); $actions->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Panel')) ->setIcon('fa-pencil') ->setHref($this->getApplicationURI("panel/edit/{$id}/")) ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); if (!$panel->getIsArchived()) { $archive_text = pht('Archive Panel'); - $archive_icon = 'fa-times'; + $archive_icon = 'fa-ban'; } else { $archive_text = pht('Activate Panel'); - $archive_icon = 'fa-plus'; + $archive_icon = 'fa-check'; } $actions->addAction( id(new PhabricatorActionView()) ->setName($archive_text) ->setIcon($archive_icon) ->setHref($this->getApplicationURI("panel/archive/{$id}/")) ->setDisabled(!$can_edit) ->setWorkflow(true)); $actions->addAction( id(new PhabricatorActionView()) ->setName(pht('View Standalone')) ->setIcon('fa-eye') ->setHref($this->getApplicationURI("panel/render/{$id}/"))); return $actions; } private function buildPropertyView(PhabricatorDashboardPanel $panel) { $viewer = $this->getRequest()->getUser(); $properties = id(new PHUIPropertyListView()) ->setUser($viewer) ->setObject($panel); $descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions( $viewer, $panel); $panel_type = $panel->getImplementation(); if ($panel_type) { $type_name = $panel_type->getPanelTypeName(); } else { $type_name = phutil_tag( 'em', array(), nonempty($panel->getPanelType(), pht('null'))); } $properties->addProperty( pht('Panel Type'), $type_name); $properties->addProperty( pht('Editable By'), $descriptions[PhabricatorPolicyCapability::CAN_EDIT]); $dashboard_phids = PhabricatorEdgeQuery::loadDestinationPHIDs( $panel->getPHID(), PhabricatorDashboardPanelHasDashboardEdgeType::EDGECONST); $this->loadHandles($dashboard_phids); $does_not_appear = pht( 'This panel does not appear on any dashboards.'); $properties->addProperty( pht('Appears On'), $dashboard_phids ? $this->renderHandlesForPHIDs($dashboard_phids) : phutil_tag('em', array(), $does_not_appear)); return $properties; } } diff --git a/src/applications/herald/controller/HeraldDisableController.php b/src/applications/herald/controller/HeraldDisableController.php index 9412997e94..edf15f80f6 100644 --- a/src/applications/herald/controller/HeraldDisableController.php +++ b/src/applications/herald/controller/HeraldDisableController.php @@ -1,74 +1,74 @@ id = $data['id']; $this->action = $data['action']; } public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); $id = $this->id; $rule = id(new HeraldRuleQuery()) ->setViewer($viewer) ->withIDs(array($id)) ->requireCapabilities( array( PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT, )) ->executeOne(); if (!$rule) { return new Aphront404Response(); } if ($rule->isGlobalRule()) { $this->requireApplicationCapability( HeraldManageGlobalRulesCapability::CAPABILITY); } $view_uri = $this->getApplicationURI("rule/{$id}/"); $is_disable = ($this->action === 'disable'); if ($request->isFormPost()) { $xaction = id(new HeraldRuleTransaction()) ->setTransactionType(HeraldRuleTransaction::TYPE_DISABLE) ->setNewValue($is_disable); id(new HeraldRuleEditor()) ->setActor($viewer) ->setContinueOnNoEffect(true) ->setContentSourceFromRequest($request) ->applyTransactions($rule, array($xaction)); return id(new AphrontRedirectResponse())->setURI($view_uri); } if ($is_disable) { - $title = pht('Really disable this rule?'); + $title = pht('Really archive this rule?'); $body = pht('This rule will no longer activate.'); - $button = pht('Disable Rule'); + $button = pht('Archive Rule'); } else { - $title = pht('Really enable this rule?'); + $title = pht('Really activate this rule?'); $body = pht('This rule will become active again.'); - $button = pht('Enable Rule'); + $button = pht('Activate Rule'); } $dialog = id(new AphrontDialogView()) ->setUser($viewer) ->setTitle($title) ->appendChild($body) ->addSubmitButton($button) ->addCancelButton($view_uri); return id(new AphrontDialogResponse())->setDialog($dialog); } } diff --git a/src/applications/herald/controller/HeraldRuleViewController.php b/src/applications/herald/controller/HeraldRuleViewController.php index d8d6b87a45..c4dda13309 100644 --- a/src/applications/herald/controller/HeraldRuleViewController.php +++ b/src/applications/herald/controller/HeraldRuleViewController.php @@ -1,163 +1,163 @@ id = $data['id']; } public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); $rule = id(new HeraldRuleQuery()) ->setViewer($viewer) ->withIDs(array($this->id)) ->needConditionsAndActions(true) ->executeOne(); if (!$rule) { return new Aphront404Response(); } $header = id(new PHUIHeaderView()) ->setUser($viewer) ->setHeader($rule->getName()) ->setPolicyObject($rule); if ($rule->getIsDisabled()) { $header->setStatus( 'fa-ban', - 'dark', - pht('Disabled')); + 'red', + pht('Archived')); } else { $header->setStatus( 'fa-check', 'bluegrey', pht('Active')); } $actions = $this->buildActionView($rule); $properties = $this->buildPropertyView($rule, $actions); $id = $rule->getID(); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb("H{$id}"); $crumbs->setActionList($actions); $object_box = id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($properties); $timeline = $this->buildTransactionTimeline( $rule, new HeraldTransactionQuery()); return $this->buildApplicationPage( array( $crumbs, $object_box, $timeline, ), array( 'title' => $rule->getName(), )); } private function buildActionView(HeraldRule $rule) { $viewer = $this->getRequest()->getUser(); $id = $rule->getID(); $view = id(new PhabricatorActionListView()) ->setUser($viewer) ->setObject($rule) ->setObjectURI($this->getApplicationURI("rule/{$id}/")); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $rule, PhabricatorPolicyCapability::CAN_EDIT); $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Rule')) ->setHref($this->getApplicationURI("edit/{$id}/")) ->setIcon('fa-pencil') ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); if ($rule->getIsDisabled()) { $disable_uri = "disable/{$id}/enable/"; - $disable_icon = 'fa-check-circle-o'; - $disable_name = pht('Enable Rule'); + $disable_icon = 'fa-check'; + $disable_name = pht('Activate Rule'); } else { $disable_uri = "disable/{$id}/disable/"; $disable_icon = 'fa-ban'; - $disable_name = pht('Disable Rule'); + $disable_name = pht('Archive Rule'); } $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Disable Rule')) ->setHref($this->getApplicationURI($disable_uri)) ->setIcon($disable_icon) ->setName($disable_name) ->setDisabled(!$can_edit) ->setWorkflow(true)); return $view; } private function buildPropertyView( HeraldRule $rule, PhabricatorActionListView $actions) { $viewer = $this->getRequest()->getUser(); $this->loadHandles(HeraldAdapter::getHandlePHIDs($rule)); $view = id(new PHUIPropertyListView()) ->setUser($viewer) ->setObject($rule) ->setActionList($actions); $view->addProperty( pht('Rule Type'), idx(HeraldRuleTypeConfig::getRuleTypeMap(), $rule->getRuleType())); if ($rule->isPersonalRule()) { $view->addProperty( pht('Author'), $this->getHandle($rule->getAuthorPHID())->renderLink()); } $adapter = HeraldAdapter::getAdapterForContentType($rule->getContentType()); if ($adapter) { $view->addProperty( pht('Applies To'), idx( HeraldAdapter::getEnabledAdapterMap($viewer), $rule->getContentType())); if ($rule->isObjectRule()) { $view->addProperty( pht('Trigger Object'), $this->getHandle($rule->getTriggerObjectPHID())->renderLink()); } $view->invokeWillRenderEvent(); $view->addSectionHeader( pht('Rule Description'), PHUIPropertyListView::ICON_SUMMARY); $view->addTextContent( $adapter->renderRuleAsText($rule, $this->getLoadedHandles())); } return $view; } } diff --git a/src/applications/herald/storage/HeraldRuleTransaction.php b/src/applications/herald/storage/HeraldRuleTransaction.php index 8046eb1c3f..8d4201faf6 100644 --- a/src/applications/herald/storage/HeraldRuleTransaction.php +++ b/src/applications/herald/storage/HeraldRuleTransaction.php @@ -1,92 +1,92 @@ getOldValue(); $new = $this->getNewValue(); switch ($this->getTransactionType()) { case self::TYPE_DISABLE: if ($new) { return 'red'; } else { return 'green'; } } return parent::getColor(); } public function getActionName() { $old = $this->getOldValue(); $new = $this->getNewValue(); switch ($this->getTransactionType()) { case self::TYPE_DISABLE: if ($new) { return pht('Disabled'); } else { return pht('Enabled'); } } return parent::getActionName(); } public function getIcon() { $old = $this->getOldValue(); $new = $this->getNewValue(); switch ($this->getTransactionType()) { case self::TYPE_DISABLE: if ($new) { - return 'fa-pause'; + return 'fa-ban'; } else { - return 'fa-play'; + return 'fa-check'; } } return parent::getIcon(); } public function getTitle() { $author_phid = $this->getAuthorPHID(); $old = $this->getOldValue(); $new = $this->getNewValue(); switch ($this->getTransactionType()) { case self::TYPE_DISABLE: if ($new) { return pht( '%s disabled this rule.', $this->renderHandleLink($author_phid)); } else { return pht( '%s enabled this rule.', $this->renderHandleLink($author_phid)); } } return parent::getTitle(); } } diff --git a/src/applications/macro/controller/PhabricatorMacroViewController.php b/src/applications/macro/controller/PhabricatorMacroViewController.php index 3726c627a7..90b493e9d7 100644 --- a/src/applications/macro/controller/PhabricatorMacroViewController.php +++ b/src/applications/macro/controller/PhabricatorMacroViewController.php @@ -1,184 +1,182 @@ id = $data['id']; } public function shouldAllowPublic() { return true; } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $macro = id(new PhabricatorMacroQuery()) ->setViewer($user) ->withIDs(array($this->id)) ->needFiles(true) ->executeOne(); if (!$macro) { return new Aphront404Response(); } $file = $macro->getFile(); $title_short = pht('Macro "%s"', $macro->getName()); $title_long = pht('Image Macro "%s"', $macro->getName()); $actions = $this->buildActionView($macro); $crumbs = $this->buildApplicationCrumbs(); $crumbs->setActionList($actions); $crumbs->addTextCrumb( $title_short, $this->getApplicationURI('/view/'.$macro->getID().'/')); $properties = $this->buildPropertyView($macro, $actions); if ($file) { $file_view = new PHUIPropertyListView(); $file_view->addImageContent( phutil_tag( 'img', array( 'src' => $file->getViewURI(), 'class' => 'phabricator-image-macro-hero', ))); } $timeline = $this->buildTransactionTimeline( $macro, new PhabricatorMacroTransactionQuery()); $header = id(new PHUIHeaderView()) ->setUser($user) ->setPolicyObject($macro) ->setHeader($title_long); - if ($macro->getIsDisabled()) { - $header->addTag( - id(new PHUITagView()) - ->setType(PHUITagView::TYPE_STATE) - ->setName(pht('Macro Disabled')) - ->setBackgroundColor(PHUITagView::COLOR_BLACK)); + if (!$macro->getIsDisabled()) { + $header->setStatus('fa-check', 'bluegrey', pht('Active')); + } else { + $header->setStatus('fa-ban', 'red', pht('Archived')); } $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business'); $comment_header = $is_serious ? pht('Add Comment') : pht('Grovel in Awe'); $draft = PhabricatorDraft::newFromUserAndKey($user, $macro->getPHID()); $add_comment_form = id(new PhabricatorApplicationTransactionCommentView()) ->setUser($user) ->setObjectPHID($macro->getPHID()) ->setDraft($draft) ->setHeaderText($comment_header) ->setAction($this->getApplicationURI('/comment/'.$macro->getID().'/')) ->setSubmitButtonName(pht('Add Comment')); $object_box = id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($properties); if ($file_view) { $object_box->addPropertyList($file_view); } return $this->buildApplicationPage( array( $crumbs, $object_box, $timeline, $add_comment_form, ), array( 'title' => $title_short, )); } private function buildActionView(PhabricatorFileImageMacro $macro) { $can_manage = $this->hasApplicationCapability( PhabricatorMacroManageCapability::CAPABILITY); $request = $this->getRequest(); $view = id(new PhabricatorActionListView()) ->setUser($request->getUser()) ->setObject($macro) ->setObjectURI($request->getRequestURI()) ->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Macro')) ->setHref($this->getApplicationURI('/edit/'.$macro->getID().'/')) ->setDisabled(!$can_manage) ->setWorkflow(!$can_manage) ->setIcon('fa-pencil')); $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Audio')) ->setHref($this->getApplicationURI('/audio/'.$macro->getID().'/')) ->setDisabled(!$can_manage) ->setWorkflow(!$can_manage) ->setIcon('fa-music')); if ($macro->getIsDisabled()) { $view->addAction( id(new PhabricatorActionView()) - ->setName(pht('Restore Macro')) + ->setName(pht('Activate Macro')) ->setHref($this->getApplicationURI('/disable/'.$macro->getID().'/')) ->setWorkflow(true) ->setDisabled(!$can_manage) - ->setIcon('fa-check-circle-o')); + ->setIcon('fa-check')); } else { $view->addAction( id(new PhabricatorActionView()) - ->setName(pht('Disable Macro')) + ->setName(pht('Archive Macro')) ->setHref($this->getApplicationURI('/disable/'.$macro->getID().'/')) ->setWorkflow(true) ->setDisabled(!$can_manage) ->setIcon('fa-ban')); } return $view; } private function buildPropertyView( PhabricatorFileImageMacro $macro, PhabricatorActionListView $actions) { $view = id(new PHUIPropertyListView()) ->setUser($this->getRequest()->getUser()) ->setObject($macro) ->setActionList($actions); switch ($macro->getAudioBehavior()) { case PhabricatorFileImageMacro::AUDIO_BEHAVIOR_ONCE: $view->addProperty(pht('Audio Behavior'), pht('Play Once')); break; case PhabricatorFileImageMacro::AUDIO_BEHAVIOR_LOOP: $view->addProperty(pht('Audio Behavior'), pht('Loop')); break; } $audio_phid = $macro->getAudioPHID(); if ($audio_phid) { $this->loadHandles(array($audio_phid)); $view->addProperty( pht('Audio'), $this->getHandle($audio_phid)->renderLink()); } $view->invokeWillRenderEvent(); return $view; } } diff --git a/src/applications/ponder/controller/PonderQuestionViewController.php b/src/applications/ponder/controller/PonderQuestionViewController.php index e606bb2b93..b8ad937c23 100644 --- a/src/applications/ponder/controller/PonderQuestionViewController.php +++ b/src/applications/ponder/controller/PonderQuestionViewController.php @@ -1,405 +1,411 @@ questionID = $data['id']; } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $question = id(new PonderQuestionQuery()) ->setViewer($user) ->withIDs(array($this->questionID)) ->needAnswers(true) ->needViewerVotes(true) ->executeOne(); if (!$question) { return new Aphront404Response(); } $question->attachVotes($user->getPHID()); $question_xactions = $this->buildQuestionTransactions($question); $answers = $this->buildAnswers($question->getAnswers()); $authors = mpull($question->getAnswers(), null, 'getAuthorPHID'); if (isset($authors[$user->getPHID()])) { $answer_add_panel = id(new AphrontErrorView()) ->setSeverity(AphrontErrorView::SEVERITY_NODATA) ->appendChild( pht( 'You have already answered this question. You can not answer '. 'twice, but you can edit your existing answer.')); } else { $answer_add_panel = new PonderAddAnswerView(); $answer_add_panel ->setQuestion($question) ->setUser($user) ->setActionURI('/ponder/answer/add/'); } $header = id(new PHUIHeaderView()) ->setHeader($question->getTitle()); + if ($question->getStatus() == PonderQuestionStatus::STATUS_OPEN) { + $header->setStatus('fa-square-o', 'bluegrey', pht('Open')); + } else { + $header->setStatus('fa-check-square-o', 'dark', pht('Closed')); + } + $actions = $this->buildActionListView($question); $properties = $this->buildPropertyListView($question, $actions); $object_box = id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($properties); $crumbs = $this->buildApplicationCrumbs($this->buildSideNavView()); $crumbs->setActionList($actions); $crumbs->addTextCrumb('Q'.$this->questionID, '/Q'.$this->questionID); return $this->buildApplicationPage( array( $crumbs, $object_box, $question_xactions, $answers, $answer_add_panel, ), array( 'title' => 'Q'.$question->getID().' '.$question->getTitle(), 'pageObjects' => array_merge( array($question->getPHID()), mpull($question->getAnswers(), 'getPHID')), )); } private function buildActionListView(PonderQuestion $question) { $request = $this->getRequest(); $viewer = $request->getUser(); $id = $question->getID(); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $question, PhabricatorPolicyCapability::CAN_EDIT); $view = id(new PhabricatorActionListView()) ->setUser($request->getUser()) ->setObject($question) ->setObjectURI($request->getRequestURI()); $view->addAction( id(new PhabricatorActionView()) ->setIcon('fa-pencil') ->setName(pht('Edit Question')) ->setHref($this->getApplicationURI("/question/edit/{$id}/")) ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); if ($question->getStatus() == PonderQuestionStatus::STATUS_OPEN) { $name = pht('Close Question'); - $icon = 'fa-times'; + $icon = 'fa-check-square-o'; $href = 'close'; } else { $name = pht('Reopen Question'); - $icon = 'fa-check-circle-o'; + $icon = 'fa-square-o'; $href = 'open'; } $view->addAction( id(new PhabricatorActionView()) ->setName($name) ->setIcon($icon) ->setRenderAsForm($can_edit) ->setWorkflow(!$can_edit) ->setDisabled(!$can_edit) ->setHref($this->getApplicationURI("/question/{$href}/{$id}/"))); $view->addAction( id(new PhabricatorActionView()) ->setIcon('fa-list') ->setName(pht('View History')) ->setHref($this->getApplicationURI("/question/history/{$id}/"))); return $view; } private function buildPropertyListView( PonderQuestion $question, PhabricatorActionListView $actions) { $viewer = $this->getRequest()->getUser(); $view = id(new PHUIPropertyListView()) ->setUser($viewer) ->setObject($question) ->setActionList($actions); $this->loadHandles(array($question->getAuthorPHID())); $view->addProperty( pht('Status'), PonderQuestionStatus::getQuestionStatusFullName($question->getStatus())); $view->addProperty( pht('Author'), $this->getHandle($question->getAuthorPHID())->renderLink()); $view->addProperty( pht('Created'), phabricator_datetime($question->getDateCreated(), $viewer)); $view->invokeWillRenderEvent(); $votable = id(new PonderVotableView()) ->setPHID($question->getPHID()) ->setURI($this->getApplicationURI('vote/')) ->setCount($question->getVoteCount()) ->setVote($question->getUserVote()); $view->addSectionHeader(pht('Question')); $view->addTextContent( array( $votable, phutil_tag( 'div', array( 'class' => 'phabricator-remarkup', ), PhabricatorMarkupEngine::renderOneObject( $question, $question->getMarkupField(), $viewer)), )); return $view; } private function buildQuestionTransactions(PonderQuestion $question) { $viewer = $this->getViewer(); $id = $question->getID(); $timeline = $this->buildTransactionTimeline( $question, id(new PonderQuestionTransactionQuery()) ->withTransactionTypes(array(PhabricatorTransactions::TYPE_COMMENT))); $xactions = $timeline->getTransactions(); $add_comment = id(new PhabricatorApplicationTransactionCommentView()) ->setUser($viewer) ->setObjectPHID($question->getPHID()) ->setShowPreview(false) ->setHeaderText(pht('Question Comment')) ->setAction($this->getApplicationURI("/question/comment/{$id}/")) ->setSubmitButtonName(pht('Comment')); return $this->wrapComments( count($xactions), array( $timeline, $add_comment, )); } /** * This is fairly non-standard; building N timelines at once (N = number of * answers) is tricky business. * * TODO - re-factor this to ajax in one answer panel at a time in a more * standard fashion. This is necessary to scale this application. */ private function buildAnswers(array $answers) { $request = $this->getRequest(); $viewer = $request->getUser(); $out = array(); $phids = mpull($answers, 'getAuthorPHID'); $this->loadHandles($phids); $xactions = id(new PonderAnswerTransactionQuery()) ->setViewer($viewer) ->withTransactionTypes(array(PhabricatorTransactions::TYPE_COMMENT)) ->withObjectPHIDs(mpull($answers, 'getPHID')) ->execute(); $engine = id(new PhabricatorMarkupEngine()) ->setViewer($viewer); foreach ($xactions as $xaction) { if ($xaction->getComment()) { $engine->addObject( $xaction->getComment(), PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT); } } $engine->process(); $xaction_groups = mgroup($xactions, 'getObjectPHID'); foreach ($answers as $answer) { $author_phid = $answer->getAuthorPHID(); $xactions = idx($xaction_groups, $answer->getPHID(), array()); $id = $answer->getID(); $out[] = phutil_tag('br'); $out[] = phutil_tag('br'); $out[] = id(new PhabricatorAnchorView()) ->setAnchorName("A$id"); $header = id(new PHUIHeaderView()) ->setHeader($this->getHandle($author_phid)->getFullName()); $actions = $this->buildAnswerActions($answer); $properties = $this->buildAnswerProperties($answer, $actions); $object_box = id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($properties); $out[] = $object_box; $details = array(); $details[] = id(new PhabricatorApplicationTransactionView()) ->setUser($viewer) ->setObjectPHID($answer->getPHID()) ->setTransactions($xactions) ->setMarkupEngine($engine); $form = id(new PhabricatorApplicationTransactionCommentView()) ->setUser($viewer) ->setObjectPHID($answer->getPHID()) ->setShowPreview(false) ->setHeaderText(pht('Answer Comment')) ->setAction($this->getApplicationURI("/answer/comment/{$id}/")) ->setSubmitButtonName(pht('Comment')); $details[] = $form; $out[] = $this->wrapComments( count($xactions), $details); } $out[] = phutil_tag('br'); $out[] = phutil_tag('br'); return $out; } private function buildAnswerActions(PonderAnswer $answer) { $request = $this->getRequest(); $viewer = $request->getUser(); $id = $answer->getID(); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $answer, PhabricatorPolicyCapability::CAN_EDIT); $view = id(new PhabricatorActionListView()) ->setUser($request->getUser()) ->setObject($answer) ->setObjectURI($request->getRequestURI()); $view->addAction( id(new PhabricatorActionView()) ->setIcon('fa-pencil') ->setName(pht('Edit Answer')) ->setHref($this->getApplicationURI("/answer/edit/{$id}/")) ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); $view->addAction( id(new PhabricatorActionView()) ->setIcon('fa-list') ->setName(pht('View History')) ->setHref($this->getApplicationURI("/answer/history/{$id}/"))); return $view; } private function buildAnswerProperties( PonderAnswer $answer, PhabricatorActionListView $actions) { $viewer = $this->getRequest()->getUser(); $view = id(new PHUIPropertyListView()) ->setUser($viewer) ->setObject($answer) ->setActionList($actions); $view->addProperty( pht('Created'), phabricator_datetime($answer->getDateCreated(), $viewer)); $view->invokeWillRenderEvent(); $votable = id(new PonderVotableView()) ->setPHID($answer->getPHID()) ->setURI($this->getApplicationURI('vote/')) ->setCount($answer->getVoteCount()) ->setVote($answer->getUserVote()); $view->addSectionHeader(pht('Answer')); $view->addTextContent( array( $votable, phutil_tag( 'div', array( 'class' => 'phabricator-remarkup', ), PhabricatorMarkupEngine::renderOneObject( $answer, $answer->getMarkupField(), $viewer)), )); return $view; } private function wrapComments($n, $stuff) { if ($n == 0) { $text = pht('Add a Comment'); } else { $text = pht('Show %s Comments', new PhutilNumber($n)); } $show_id = celerity_generate_unique_node_id(); $hide_id = celerity_generate_unique_node_id(); Javelin::initBehavior('phabricator-reveal-content'); require_celerity_resource('ponder-comment-table-css'); $show = phutil_tag( 'div', array( 'id' => $show_id, 'class' => 'ponder-show-comments', ), javelin_tag( 'a', array( 'href' => '#', 'sigil' => 'reveal-content', 'meta' => array( 'showIDs' => array($hide_id), 'hideIDs' => array($show_id), ), ), $text)); $hide = phutil_tag( 'div', array( 'id' => $hide_id, 'style' => 'display: none', ), $stuff); return array($show, $hide); } } diff --git a/src/applications/project/controller/PhabricatorProjectArchiveController.php b/src/applications/project/controller/PhabricatorProjectArchiveController.php index 1138581fdc..f158783262 100644 --- a/src/applications/project/controller/PhabricatorProjectArchiveController.php +++ b/src/applications/project/controller/PhabricatorProjectArchiveController.php @@ -1,74 +1,74 @@ id = $data['id']; } public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); $project = id(new PhabricatorProjectQuery()) ->setViewer($viewer) ->withIDs(array($this->id)) ->requireCapabilities( array( PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT, )) ->executeOne(); if (!$project) { return new Aphront404Response(); } $edit_uri = $this->getApplicationURI('edit/'.$project->getID().'/'); if ($request->isFormPost()) { if ($project->isArchived()) { $new_status = PhabricatorProjectStatus::STATUS_ACTIVE; } else { $new_status = PhabricatorProjectStatus::STATUS_ARCHIVED; } $xactions = array(); $xactions[] = id(new PhabricatorProjectTransaction()) ->setTransactionType(PhabricatorProjectTransaction::TYPE_STATUS) ->setNewValue($new_status); id(new PhabricatorProjectTransactionEditor()) ->setActor($viewer) ->setContentSourceFromRequest($request) ->setContinueOnNoEffect(true) ->setContinueOnMissingFields(true) ->applyTransactions($project, $xactions); return id(new AphrontRedirectResponse())->setURI($edit_uri); } if ($project->isArchived()) { - $title = pht('Really unarchive project?'); + $title = pht('Really activate project?'); $body = pht('This project will become active again.'); - $button = pht('Unarchive Project'); + $button = pht('Activate Project'); } else { $title = pht('Really archive project?'); $body = pht('This project will be moved to the archive.'); $button = pht('Archive Project'); } $dialog = id(new AphrontDialogView()) ->setUser($viewer) ->setTitle($title) ->appendChild($body) ->addCancelButton($edit_uri) ->addSubmitButton($button); return id(new AphrontDialogResponse())->setDialog($dialog); } } diff --git a/src/applications/project/controller/PhabricatorProjectEditMainController.php b/src/applications/project/controller/PhabricatorProjectEditMainController.php index ec874c789f..2067fd7d05 100644 --- a/src/applications/project/controller/PhabricatorProjectEditMainController.php +++ b/src/applications/project/controller/PhabricatorProjectEditMainController.php @@ -1,162 +1,162 @@ id = idx($data, 'id'); } public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); $project = id(new PhabricatorProjectQuery()) ->setViewer($viewer) ->withIDs(array($this->id)) ->needImages(true) ->executeOne(); if (!$project) { return new Aphront404Response(); } $header = id(new PHUIHeaderView()) ->setHeader(pht('Edit %s', $project->getName())) ->setUser($viewer) ->setPolicyObject($project) ->setImage($project->getProfileImageURI()); if ($project->getStatus() == PhabricatorProjectStatus::STATUS_ACTIVE) { $header->setStatus('fa-check', 'bluegrey', pht('Active')); } else { - $header->setStatus('fa-ban', 'dark', pht('Archived')); + $header->setStatus('fa-ban', 'red', pht('Archived')); } $actions = $this->buildActionListView($project); $properties = $this->buildPropertyListView($project, $actions); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb( $project->getName(), $this->getApplicationURI('view/'.$project->getID().'/')); $crumbs->addTextCrumb(pht('Edit')); $crumbs->setActionList($actions); $object_box = id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($properties); $timeline = $this->buildTransactionTimeline( $project, new PhabricatorProjectTransactionQuery()); $timeline->setShouldTerminate(true); return $this->buildApplicationPage( array( $crumbs, $object_box, $timeline, ), array( 'title' => $project->getName(), )); } private function buildActionListView(PhabricatorProject $project) { $request = $this->getRequest(); $viewer = $request->getUser(); $id = $project->getID(); $view = id(new PhabricatorActionListView()) ->setUser($viewer) ->setObjectURI($request->getRequestURI()); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $project, PhabricatorPolicyCapability::CAN_EDIT); $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Details')) ->setIcon('fa-pencil') ->setHref($this->getApplicationURI("details/{$id}/")) ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Picture')) ->setIcon('fa-picture-o') ->setHref($this->getApplicationURI("picture/{$id}/")) ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); if ($project->isArchived()) { $view->addAction( id(new PhabricatorActionView()) - ->setName(pht('Unarchive Project')) + ->setName(pht('Activate Project')) ->setIcon('fa-check') ->setHref($this->getApplicationURI("archive/{$id}/")) ->setDisabled(!$can_edit) ->setWorkflow(true)); } else { $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Archive Project')) ->setIcon('fa-ban') ->setHref($this->getApplicationURI("archive/{$id}/")) ->setDisabled(!$can_edit) ->setWorkflow(true)); } return $view; } private function buildPropertyListView( PhabricatorProject $project, PhabricatorActionListView $actions) { $request = $this->getRequest(); $viewer = $request->getUser(); $view = id(new PHUIPropertyListView()) ->setUser($viewer) ->setObject($project) ->setActionList($actions); $descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions( $viewer, $project); $this->loadHandles(array($project->getPHID())); $view->addProperty( pht('Looks Like'), $this->getHandle($project->getPHID())->renderTag()); $view->addProperty( pht('Visible To'), $descriptions[PhabricatorPolicyCapability::CAN_VIEW]); $view->addProperty( pht('Editable By'), $descriptions[PhabricatorPolicyCapability::CAN_EDIT]); $view->addProperty( pht('Joinable By'), $descriptions[PhabricatorPolicyCapability::CAN_JOIN]); return $view; } } diff --git a/src/applications/project/controller/PhabricatorProjectProfileController.php b/src/applications/project/controller/PhabricatorProjectProfileController.php index 56dfae0d76..c1d19209e1 100644 --- a/src/applications/project/controller/PhabricatorProjectProfileController.php +++ b/src/applications/project/controller/PhabricatorProjectProfileController.php @@ -1,336 +1,336 @@ id = idx($data, 'id'); // via /tag/$slug/ $this->slug = idx($data, 'slug'); } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $query = id(new PhabricatorProjectQuery()) ->setViewer($user) ->needMembers(true) ->needWatchers(true) ->needImages(true) ->needSlugs(true); if ($this->slug) { $query->withSlugs(array($this->slug)); } else { $query->withIDs(array($this->id)); } $project = $query->executeOne(); if (!$project) { return new Aphront404Response(); } if ($this->slug && $this->slug != $project->getPrimarySlug()) { return id(new AphrontRedirectResponse()) ->setURI('/tag/'.$project->getPrimarySlug().'/'); } $picture = $project->getProfileImageURI(); require_celerity_resource('phabricator-profile-css'); $tasks = $this->renderTasksPage($project); $query = new PhabricatorFeedQuery(); $query->setFilterPHIDs( array( $project->getPHID(), )); $query->setLimit(50); $query->setViewer($this->getRequest()->getUser()); $stories = $query->execute(); $feed = $this->renderStories($stories); $content = phutil_tag_div( 'phabricator-project-layout', array($tasks, $feed)); $id = $project->getID(); $icon = id(new PHUIIconView()) ->setIconFont('fa-columns'); $board_btn = id(new PHUIButtonView()) ->setTag('a') ->setText(pht('Workboard')) ->setHref($this->getApplicationURI("board/{$id}/")) ->setIcon($icon); $header = id(new PHUIHeaderView()) ->setHeader($project->getName()) ->setUser($user) ->setPolicyObject($project) ->setImage($picture) ->addActionLink($board_btn); if ($project->getStatus() == PhabricatorProjectStatus::STATUS_ACTIVE) { $header->setStatus('fa-check', 'bluegrey', pht('Active')); } else { - $header->setStatus('fa-ban', 'dark', pht('Archived')); + $header->setStatus('fa-ban', 'red', pht('Archived')); } $actions = $this->buildActionListView($project); $properties = $this->buildPropertyListView($project, $actions); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb($project->getName()) ->setActionList($actions); $object_box = id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($properties); return $this->buildApplicationPage( array( $crumbs, $object_box, $content, ), array( 'title' => $project->getName(), )); } private function renderFeedPage(PhabricatorProject $project) { $query = new PhabricatorFeedQuery(); $query->setFilterPHIDs(array($project->getPHID())); $query->setViewer($this->getRequest()->getUser()); $query->setLimit(100); $stories = $query->execute(); if (!$stories) { return pht('There are no stories about this project.'); } return $this->renderStories($stories); } private function renderStories(array $stories) { assert_instances_of($stories, 'PhabricatorFeedStory'); $builder = new PhabricatorFeedBuilder($stories); $builder->setUser($this->getRequest()->getUser()); $builder->setShowHovercards(true); $view = $builder->buildView(); return phutil_tag_div( 'profile-feed', $view->render()); } private function renderTasksPage(PhabricatorProject $project) { $user = $this->getRequest()->getUser(); $limit = 10; $query = id(new ManiphestTaskQuery()) ->setViewer($user) ->withAnyProjects(array($project->getPHID())) ->withStatuses(ManiphestTaskStatus::getOpenStatusConstants()) ->setOrderBy(ManiphestTaskQuery::ORDER_PRIORITY) ->needProjectPHIDs(true) ->setLimit(($limit + 1)); $tasks = $query->execute(); $count = count($tasks); if ($count == ($limit + 1)) { array_pop($tasks); } $phids = mpull($tasks, 'getOwnerPHID'); $phids = array_merge( $phids, array_mergev(mpull($tasks, 'getProjectPHIDs'))); $phids = array_filter($phids); $handles = $this->loadViewerHandles($phids); $task_list = new ManiphestTaskListView(); $task_list->setUser($user); $task_list->setTasks($tasks); $task_list->setHandles($handles); $phid = $project->getPHID(); $view_uri = urisprintf( '/maniphest/?statuses=%s&allProjects=%s#R', implode(',', ManiphestTaskStatus::getOpenStatusConstants()), $phid); $create_uri = '/maniphest/task/create/?projects='.$phid; $icon = id(new PHUIIconView()) ->setIconFont('fa-list'); $button_view = id(new PHUIButtonView()) ->setTag('a') ->setText(pht('View All')) ->setHref($view_uri) ->setIcon($icon); $icon_new = id(new PHUIIconView()) ->setIconFont('fa-plus'); $button_add = id(new PHUIButtonView()) ->setTag('a') ->setText(pht('New Task')) ->setHref($create_uri) ->setIcon($icon_new); $header = id(new PHUIHeaderView()) ->addActionLink($button_add) ->addActionLink($button_view); if ($count > $limit) { $header->setHeader(pht('Highest Priority (some)')); } else { $header->setHeader(pht('Highest Priority (all)')); } $content = id(new PHUIObjectBoxView()) ->setHeader($header) ->appendChild($task_list); return $content; } private function buildActionListView(PhabricatorProject $project) { $request = $this->getRequest(); $viewer = $request->getUser(); $id = $project->getID(); $view = id(new PhabricatorActionListView()) ->setUser($viewer) ->setObject($project) ->setObjectURI($request->getRequestURI()); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $project, PhabricatorPolicyCapability::CAN_EDIT); $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Project')) ->setIcon('fa-pencil') ->setHref($this->getApplicationURI("edit/{$id}/"))); $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Members')) ->setIcon('fa-users') ->setHref($this->getApplicationURI("members/{$id}/")) ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); $action = null; if (!$project->isUserMember($viewer->getPHID())) { $can_join = PhabricatorPolicyFilter::hasCapability( $viewer, $project, PhabricatorPolicyCapability::CAN_JOIN); $action = id(new PhabricatorActionView()) ->setUser($viewer) ->setRenderAsForm(true) ->setHref('/project/update/'.$project->getID().'/join/') ->setIcon('fa-plus') ->setDisabled(!$can_join) ->setName(pht('Join Project')); $view->addAction($action); } else { $action = id(new PhabricatorActionView()) ->setWorkflow(true) ->setHref('/project/update/'.$project->getID().'/leave/') ->setIcon('fa-times') ->setName(pht('Leave Project...')); $view->addAction($action); if (!$project->isUserWatcher($viewer->getPHID())) { $action = id(new PhabricatorActionView()) ->setWorkflow(true) ->setHref('/project/watch/'.$project->getID().'/') ->setIcon('fa-eye') ->setName(pht('Watch Project')); $view->addAction($action); } else { $action = id(new PhabricatorActionView()) ->setWorkflow(true) ->setHref('/project/unwatch/'.$project->getID().'/') ->setIcon('fa-eye-slash') ->setName(pht('Unwatch Project')); $view->addAction($action); } } $have_phriction = PhabricatorApplication::isClassInstalledForViewer( 'PhabricatorPhrictionApplication', $viewer); if ($have_phriction) { $view->addAction( id(new PhabricatorActionView()) ->setIcon('fa-book grey') ->setName(pht('View Wiki')) ->setWorkflow(true) ->setHref('/project/wiki/')); } return $view; } private function buildPropertyListView( PhabricatorProject $project, PhabricatorActionListView $actions) { $request = $this->getRequest(); $viewer = $request->getUser(); $this->loadHandles( array_merge( $project->getMemberPHIDs(), $project->getWatcherPHIDs())); $view = id(new PHUIPropertyListView()) ->setUser($viewer) ->setObject($project) ->setActionList($actions); $hashtags = array(); foreach ($project->getSlugs() as $slug) { $hashtags[] = id(new PHUITagView()) ->setType(PHUITagView::TYPE_OBJECT) ->setName('#'.$slug->getSlug()); } $view->addProperty(pht('Hashtags'), phutil_implode_html(' ', $hashtags)); $view->addProperty( pht('Members'), $project->getMemberPHIDs() ? $this->renderHandlesForPHIDs($project->getMemberPHIDs(), ',') : phutil_tag('em', array(), pht('None'))); $view->addProperty( pht('Watchers'), $project->getWatcherPHIDs() ? $this->renderHandlesForPHIDs($project->getWatcherPHIDs(), ',') : phutil_tag('em', array(), pht('None'))); $field_list = PhabricatorCustomField::getObjectFields( $project, PhabricatorCustomField::ROLE_VIEW); $field_list->appendFieldsToPropertyList($project, $viewer, $view); return $view; } }