diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index 12a904ba69..896b9fbf61 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -3884,6 +3884,15 @@ celerity_register_resource_map(array( ), 'disk' => '/rsrc/css/phui/phui-workpanel-view.css', ), + 'policy-css' => + array( + 'uri' => '/res/ebb12aa0/rsrc/css/application/policy/policy.css', + 'type' => 'css', + 'requires' => + array( + ), + 'disk' => '/rsrc/css/application/policy/policy.css', + ), 'ponder-comment-table-css' => array( 'uri' => '/res/4aa4b865/rsrc/css/application/ponder/comments.css', diff --git a/src/applications/base/controller/PhabricatorController.php b/src/applications/base/controller/PhabricatorController.php index 39d5881d23..8d9943c986 100644 --- a/src/applications/base/controller/PhabricatorController.php +++ b/src/applications/base/controller/PhabricatorController.php @@ -364,9 +364,46 @@ abstract class PhabricatorController extends AphrontController { $capability); } - protected function explainApplicationCapability($capability, $message) { - // TODO: Render a link to get more information. - return $message; + protected function explainApplicationCapability( + $capability, + $positive_message, + $negative_message) { + + $can_act = $this->hasApplicationCapability($capability); + if ($can_act) { + $message = $positive_message; + $icon_name = 'enable-grey'; + } else { + $message = $negative_message; + $icon_name = 'lock'; + } + + $icon = id(new PHUIIconView()) + ->setSpriteSheet(PHUIIconView::SPRITE_ICONS) + ->setSpriteIcon($icon_name); + + require_celerity_resource('policy-css'); + + $phid = $this->getCurrentApplication()->getPHID(); + $explain_uri = "/policy/explain/{$phid}/{$capability}/"; + + $message = phutil_tag( + 'div', + array( + 'class' => 'policy-capability-explanation', + ), + array( + $icon, + javelin_tag( + 'a', + array( + 'href' => $explain_uri, + 'sigil' => 'workflow', + ), + $message), + )); + + return array($can_act, $message); } } diff --git a/src/applications/herald/controller/HeraldNewController.php b/src/applications/herald/controller/HeraldNewController.php index e27b33160c..7251ca6570 100644 --- a/src/applications/herald/controller/HeraldNewController.php +++ b/src/applications/herald/controller/HeraldNewController.php @@ -17,9 +17,6 @@ final class HeraldNewController extends HeraldController { $this->requireApplicationCapability( HeraldCapabilityCreateRules::CAPABILITY); - $can_global = $this->hasApplicationCapability( - HeraldCapabilityManageGlobalRules::CAPABILITY); - $content_type_map = HeraldAdapter::getEnabledAdapterMap($user); if (empty($content_type_map[$this->contentType])) { $this->contentType = head_key($content_type_map); @@ -37,13 +34,10 @@ final class HeraldNewController extends HeraldController { HeraldRuleTypeConfig::RULE_TYPE_PERSONAL, )) + $rule_type_map; - if (!$can_global) { - $global_link = $this->explainApplicationCapability( - HeraldCapabilityManageGlobalRules::CAPABILITY, - pht('You do not have permission to create or manage global rules.')); - } else { - $global_link = null; - } + list($can_global, $global_link) = $this->explainApplicationCapability( + HeraldCapabilityManageGlobalRules::CAPABILITY, + pht('You have permission to create and manage global rules.'), + pht('You do not have permission to create or manage global rules.')); $captions = array( HeraldRuleTypeConfig::RULE_TYPE_PERSONAL => @@ -52,15 +46,12 @@ final class HeraldNewController extends HeraldController { 'only affect you. Personal rules only trigger for objects you have '. 'permission to see.'), HeraldRuleTypeConfig::RULE_TYPE_GLOBAL => - phutil_implode_html( - phutil_tag('br'), - array_filter( - array( - pht( - 'Global rules notify anyone about events. Global rules can '. - 'bypass access control policies and act on any object.'), - $global_link, - ))), + array( + pht( + 'Global rules notify anyone about events. Global rules can '. + 'bypass access control policies and act on any object.'), + $global_link, + ), ); $radio = id(new AphrontFormRadioButtonControl()) diff --git a/src/applications/policy/controller/PhabricatorPolicyExplainController.php b/src/applications/policy/controller/PhabricatorPolicyExplainController.php index 91b2b3b18c..2679a0519a 100644 --- a/src/applications/policy/controller/PhabricatorPolicyExplainController.php +++ b/src/applications/policy/controller/PhabricatorPolicyExplainController.php @@ -63,8 +63,14 @@ final class PhabricatorPolicyExplainController $auto_info = phutil_tag('ul', array(), $auto_info); } + $capability_name = $capability; + $capobj = PhabricatorPolicyCapability::getCapabilityByKey($capability); + if ($capobj) { + $capability_name = $capobj->getCapabilityName(); + } + $content = array( - pht('Users with the "%s" capability:', "Can View"), + pht('Users with the "%s" capability:', $capability_name), $auto_info, ); diff --git a/src/view/form/control/AphrontFormRadioButtonControl.php b/src/view/form/control/AphrontFormRadioButtonControl.php index b69879fc46..589968af13 100644 --- a/src/view/form/control/AphrontFormRadioButtonControl.php +++ b/src/view/form/control/AphrontFormRadioButtonControl.php @@ -50,7 +50,7 @@ final class AphrontFormRadioButtonControl extends AphrontFormControl { ), $button['label']); - if (strlen($button['caption'])) { + if ($button['caption']) { $label = hsprintf( '%s
%s
', $label, diff --git a/webroot/rsrc/css/application/policy/policy.css b/webroot/rsrc/css/application/policy/policy.css new file mode 100644 index 0000000000..348853990d --- /dev/null +++ b/webroot/rsrc/css/application/policy/policy.css @@ -0,0 +1,18 @@ +/** + * @provides policy-css + */ + +.policy-capability-explanation .phui-icon-view { + display: inline-block; + vertical-align: text-top; +} + +.policy-capability-explanation { + margin: 8px 0 0; +} + +.policy-capability-explanation a { + line-height: 14px; + margin-left: 4px; + color: {$bluetext}; +}