mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-26 00:32:42 +01:00
Update Herald rule creation workflow to use more modern UI elements
Summary: Ref T13480. Creating a rule in Herald currently uses the older radio-button flow. Update it to the "clickable menu" flow to simplify it a little bit. Test Plan: Created new personal, object, and global rules. Hit the object rule error conditions. Maniphest Tasks: T13480 Differential Revision: https://secure.phabricator.com/D20956
This commit is contained in:
parent
4904d7711e
commit
6d4c6924d6
5 changed files with 315 additions and 246 deletions
|
@ -9,7 +9,7 @@ return array(
|
||||||
'names' => array(
|
'names' => array(
|
||||||
'conpherence.pkg.css' => '3c8a0668',
|
'conpherence.pkg.css' => '3c8a0668',
|
||||||
'conpherence.pkg.js' => '020aebcf',
|
'conpherence.pkg.js' => '020aebcf',
|
||||||
'core.pkg.css' => '6d9a0ba6',
|
'core.pkg.css' => '5edb4679',
|
||||||
'core.pkg.js' => '705aec2c',
|
'core.pkg.js' => '705aec2c',
|
||||||
'differential.pkg.css' => '607c84be',
|
'differential.pkg.css' => '607c84be',
|
||||||
'differential.pkg.js' => '1b97518d',
|
'differential.pkg.js' => '1b97518d',
|
||||||
|
@ -165,7 +165,7 @@ return array(
|
||||||
'rsrc/css/phui/phui-left-right.css' => '68513c34',
|
'rsrc/css/phui/phui-left-right.css' => '68513c34',
|
||||||
'rsrc/css/phui/phui-lightbox.css' => '4ebf22da',
|
'rsrc/css/phui/phui-lightbox.css' => '4ebf22da',
|
||||||
'rsrc/css/phui/phui-list.css' => 'b05144dd',
|
'rsrc/css/phui/phui-list.css' => 'b05144dd',
|
||||||
'rsrc/css/phui/phui-object-box.css' => 'f434b6be',
|
'rsrc/css/phui/phui-object-box.css' => 'b8d7eea0',
|
||||||
'rsrc/css/phui/phui-pager.css' => 'd022c7ad',
|
'rsrc/css/phui/phui-pager.css' => 'd022c7ad',
|
||||||
'rsrc/css/phui/phui-pinboard-view.css' => '1f08f5d8',
|
'rsrc/css/phui/phui-pinboard-view.css' => '1f08f5d8',
|
||||||
'rsrc/css/phui/phui-policy-section-view.css' => '139fdc64',
|
'rsrc/css/phui/phui-policy-section-view.css' => '139fdc64',
|
||||||
|
@ -855,7 +855,7 @@ return array(
|
||||||
'phui-left-right-css' => '68513c34',
|
'phui-left-right-css' => '68513c34',
|
||||||
'phui-lightbox-css' => '4ebf22da',
|
'phui-lightbox-css' => '4ebf22da',
|
||||||
'phui-list-view-css' => 'b05144dd',
|
'phui-list-view-css' => 'b05144dd',
|
||||||
'phui-object-box-css' => 'f434b6be',
|
'phui-object-box-css' => 'b8d7eea0',
|
||||||
'phui-oi-big-ui-css' => 'fa74cc35',
|
'phui-oi-big-ui-css' => 'fa74cc35',
|
||||||
'phui-oi-color-css' => 'b517bfa0',
|
'phui-oi-color-css' => 'b517bfa0',
|
||||||
'phui-oi-drag-ui-css' => 'da15d3dc',
|
'phui-oi-drag-ui-css' => 'da15d3dc',
|
||||||
|
|
|
@ -243,6 +243,12 @@ abstract class HeraldAdapter extends Phobject {
|
||||||
abstract public function getAdapterApplicationClass();
|
abstract public function getAdapterApplicationClass();
|
||||||
abstract public function getObject();
|
abstract public function getObject();
|
||||||
|
|
||||||
|
public function getAdapterContentIcon() {
|
||||||
|
$application_class = $this->getAdapterApplicationClass();
|
||||||
|
$application = newv($application_class, array());
|
||||||
|
return $application->getIcon();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a new characteristic object for this adapter.
|
* Return a new characteristic object for this adapter.
|
||||||
*
|
*
|
||||||
|
|
|
@ -3,42 +3,39 @@
|
||||||
final class HeraldNewController extends HeraldController {
|
final class HeraldNewController extends HeraldController {
|
||||||
|
|
||||||
public function handleRequest(AphrontRequest $request) {
|
public function handleRequest(AphrontRequest $request) {
|
||||||
$viewer = $request->getViewer();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
$adapter_type_map = HeraldAdapter::getEnabledAdapterMap($viewer);
|
||||||
|
$adapter_type = $request->getStr('adapter');
|
||||||
|
|
||||||
|
if (!isset($adapter_type_map[$adapter_type])) {
|
||||||
|
$title = pht('Create Herald Rule');
|
||||||
|
$content = $this->newAdapterMenu($title);
|
||||||
|
} else {
|
||||||
|
$adapter = HeraldAdapter::getAdapterForContentType($adapter_type);
|
||||||
|
|
||||||
$content_type_map = HeraldAdapter::getEnabledAdapterMap($viewer);
|
|
||||||
$rule_type_map = HeraldRuleTypeConfig::getRuleTypeMap();
|
$rule_type_map = HeraldRuleTypeConfig::getRuleTypeMap();
|
||||||
|
$rule_type = $request->getStr('type');
|
||||||
|
|
||||||
|
if (!isset($rule_type_map[$rule_type])) {
|
||||||
|
$title = pht(
|
||||||
|
'Create Herald Rule: %s',
|
||||||
|
$adapter->getAdapterContentName());
|
||||||
|
|
||||||
|
$content = $this->newTypeMenu($adapter, $title);
|
||||||
|
} else {
|
||||||
|
if ($rule_type !== HeraldRuleTypeConfig::RULE_TYPE_OBJECT) {
|
||||||
|
$target_phid = null;
|
||||||
|
$target_okay = true;
|
||||||
|
} else {
|
||||||
|
$object_name = $request->getStr('objectName');
|
||||||
|
$target_okay = false;
|
||||||
|
|
||||||
$errors = array();
|
$errors = array();
|
||||||
|
|
||||||
$e_type = null;
|
|
||||||
$e_rule = null;
|
|
||||||
$e_object = null;
|
$e_object = null;
|
||||||
|
|
||||||
$step = $request->getInt('step');
|
|
||||||
if ($request->isFormPost()) {
|
if ($request->isFormPost()) {
|
||||||
$content_type = $request->getStr('content_type');
|
if (strlen($object_name)) {
|
||||||
if (empty($content_type_map[$content_type])) {
|
|
||||||
$errors[] = pht('You must choose a content type for this rule.');
|
|
||||||
$e_type = pht('Required');
|
|
||||||
$step = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$errors && $step > 1) {
|
|
||||||
$rule_type = $request->getStr('rule_type');
|
|
||||||
if (empty($rule_type_map[$rule_type])) {
|
|
||||||
$errors[] = pht('You must choose a rule type for this rule.');
|
|
||||||
$e_rule = pht('Required');
|
|
||||||
$step = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$errors && $step >= 2) {
|
|
||||||
$target_phid = null;
|
|
||||||
$object_name = $request->getStr('objectName');
|
|
||||||
$done = false;
|
|
||||||
if ($rule_type != HeraldRuleTypeConfig::RULE_TYPE_OBJECT) {
|
|
||||||
$done = true;
|
|
||||||
} else if (strlen($object_name)) {
|
|
||||||
$target_object = id(new PhabricatorObjectQuery())
|
$target_object = id(new PhabricatorObjectQuery())
|
||||||
->setViewer($viewer)
|
->setViewer($viewer)
|
||||||
->withNames(array($object_name))
|
->withNames(array($object_name))
|
||||||
|
@ -50,99 +47,255 @@ final class HeraldNewController extends HeraldController {
|
||||||
PhabricatorPolicyCapability::CAN_EDIT);
|
PhabricatorPolicyCapability::CAN_EDIT);
|
||||||
if (!$can_edit) {
|
if (!$can_edit) {
|
||||||
$errors[] = pht(
|
$errors[] = pht(
|
||||||
'You can not create a rule for that object, because you do '.
|
'You can not create a rule for that object, because you '.
|
||||||
'not have permission to edit it. You can only create rules '.
|
'do not have permission to edit it. You can only create '.
|
||||||
'for objects you can edit.');
|
'rules for objects you can edit.');
|
||||||
$e_object = pht('Not Editable');
|
$e_object = pht('Not Editable');
|
||||||
$step = 2;
|
|
||||||
} else {
|
} else {
|
||||||
$adapter = HeraldAdapter::getAdapterForContentType($content_type);
|
|
||||||
if (!$adapter->canTriggerOnObject($target_object)) {
|
if (!$adapter->canTriggerOnObject($target_object)) {
|
||||||
$errors[] = pht(
|
$errors[] = pht(
|
||||||
'This object is not of an allowed type for the rule. '.
|
'This object is not of an allowed type for the rule. '.
|
||||||
'Rules can only trigger on certain objects.');
|
'Rules can only trigger on certain objects.');
|
||||||
$e_object = pht('Invalid');
|
$e_object = pht('Invalid');
|
||||||
$step = 2;
|
|
||||||
} else {
|
} else {
|
||||||
$target_phid = $target_object->getPHID();
|
$target_phid = $target_object->getPHID();
|
||||||
$done = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$errors[] = pht('No object exists by that name.');
|
$errors[] = pht('No object exists by that name.');
|
||||||
$e_object = pht('Invalid');
|
$e_object = pht('Invalid');
|
||||||
$step = 2;
|
|
||||||
}
|
}
|
||||||
} else if ($step > 2) {
|
} else {
|
||||||
$errors[] = pht(
|
$errors[] = pht(
|
||||||
'You must choose an object to associate this rule with.');
|
'You must choose an object to associate this rule with.');
|
||||||
$e_object = pht('Required');
|
$e_object = pht('Required');
|
||||||
$step = 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$errors && $done) {
|
$target_okay = !$errors;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$target_okay) {
|
||||||
|
$title = pht('Choose Object');
|
||||||
|
$content = $this->newTargetForm(
|
||||||
|
$adapter,
|
||||||
|
$rule_type,
|
||||||
|
$object_name,
|
||||||
|
$errors,
|
||||||
|
$e_object,
|
||||||
|
$title);
|
||||||
|
} else {
|
||||||
$params = array(
|
$params = array(
|
||||||
'content_type' => $content_type,
|
'content_type' => $adapter_type,
|
||||||
'rule_type' => $rule_type,
|
'rule_type' => $rule_type,
|
||||||
'targetPHID' => $target_phid,
|
'targetPHID' => $target_phid,
|
||||||
);
|
);
|
||||||
|
|
||||||
$uri = new PhutilURI('edit/', $params);
|
$edit_uri = $this->getApplicationURI('edit/');
|
||||||
$uri = $this->getApplicationURI($uri);
|
$edit_uri = new PhutilURI($edit_uri, $params);
|
||||||
return id(new AphrontRedirectResponse())->setURI($uri);
|
|
||||||
|
return id(new AphrontRedirectResponse())
|
||||||
|
->setURI($edit_uri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$content_type = $request->getStr('content_type');
|
$crumbs = $this
|
||||||
$rule_type = $request->getStr('rule_type');
|
->buildApplicationCrumbs()
|
||||||
|
->addTextCrumb(pht('Create Rule'))
|
||||||
|
->setBorder(true);
|
||||||
|
|
||||||
$form = id(new AphrontFormView())
|
$view = id(new PHUITwoColumnView())
|
||||||
->setUser($viewer)
|
->setFooter($content);
|
||||||
->setAction($this->getApplicationURI('new/'));
|
|
||||||
|
|
||||||
switch ($step) {
|
return $this->newPage()
|
||||||
case 0:
|
->setTitle($title)
|
||||||
default:
|
->setCrumbs($crumbs)
|
||||||
$content_types = $this->renderContentTypeControl(
|
->appendChild($view);
|
||||||
$content_type_map,
|
}
|
||||||
$e_type);
|
|
||||||
|
|
||||||
$form
|
private function newAdapterMenu($title) {
|
||||||
->addHiddenInput('step', 1)
|
$viewer = $this->getViewer();
|
||||||
->appendChild($content_types);
|
|
||||||
|
|
||||||
$cancel_text = null;
|
$types = HeraldAdapter::getEnabledAdapterMap($viewer);
|
||||||
$cancel_uri = $this->getApplicationURI();
|
|
||||||
$title = pht('Create Herald Rule');
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
$rule_types = $this->renderRuleTypeControl(
|
|
||||||
$rule_type_map,
|
|
||||||
$e_rule);
|
|
||||||
|
|
||||||
$form
|
foreach ($types as $key => $type) {
|
||||||
->addHiddenInput('content_type', $content_type)
|
$types[$key] = HeraldAdapter::getAdapterForContentType($key);
|
||||||
->addHiddenInput('step', 2)
|
}
|
||||||
->appendChild($rule_types);
|
|
||||||
|
|
||||||
$params = array(
|
$types = msort($types, 'getAdapterContentName');
|
||||||
'content_type' => $content_type,
|
|
||||||
'step' => '0',
|
$base_uri = $this->getApplicationURI('create/');
|
||||||
|
|
||||||
|
$menu = id(new PHUIObjectItemListView())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->setBig(true);
|
||||||
|
|
||||||
|
foreach ($types as $key => $adapter) {
|
||||||
|
$adapter_uri = id(new PhutilURI($base_uri))
|
||||||
|
->replaceQueryParam('adapter', $key);
|
||||||
|
|
||||||
|
$description = $adapter->getAdapterContentDescription();
|
||||||
|
$description = phutil_escape_html_newlines($description);
|
||||||
|
|
||||||
|
$item = id(new PHUIObjectItemView())
|
||||||
|
->setHeader($adapter->getAdapterContentName())
|
||||||
|
->setImageIcon($adapter->getAdapterContentIcon())
|
||||||
|
->addAttribute($description)
|
||||||
|
->setHref($adapter_uri)
|
||||||
|
->setClickable(true);
|
||||||
|
|
||||||
|
$menu->addItem($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
$box = id(new PHUIObjectBoxView())
|
||||||
|
->setHeaderText($title)
|
||||||
|
->setBackground(PHUIObjectBoxView::WHITE_CONFIG)
|
||||||
|
->setObjectList($menu);
|
||||||
|
|
||||||
|
return id(new PHUILauncherView())
|
||||||
|
->appendChild($box);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function newTypeMenu(HeraldAdapter $adapter, $title) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
$global_capability = HeraldManageGlobalRulesCapability::CAPABILITY;
|
||||||
|
$can_global = $this->hasApplicationCapability($global_capability);
|
||||||
|
|
||||||
|
if ($can_global) {
|
||||||
|
$global_note = pht(
|
||||||
|
'You have permission to create and manage global rules.');
|
||||||
|
} else {
|
||||||
|
$global_note = pht(
|
||||||
|
'You do not have permission to create or manage global rules.');
|
||||||
|
}
|
||||||
|
$global_note = phutil_tag('em', array(), $global_note);
|
||||||
|
|
||||||
|
$specs = array(
|
||||||
|
HeraldRuleTypeConfig::RULE_TYPE_PERSONAL => array(
|
||||||
|
'name' => pht('Personal Rule'),
|
||||||
|
'icon' => 'fa-user',
|
||||||
|
'help' => pht(
|
||||||
|
'Personal rules notify you about events. You own them, but they can '.
|
||||||
|
'only affect you. Personal rules only trigger for objects you have '.
|
||||||
|
'permission to see.'),
|
||||||
|
'enabled' => true,
|
||||||
|
),
|
||||||
|
HeraldRuleTypeConfig::RULE_TYPE_OBJECT => array(
|
||||||
|
'name' => pht('Object Rule'),
|
||||||
|
'icon' => 'fa-cube',
|
||||||
|
'help' => pht(
|
||||||
|
'Object rules notify anyone about events. They are bound to an '.
|
||||||
|
'object (like a repository) and can only act on that object. You '.
|
||||||
|
'must be able to edit an object to create object rules for it. '.
|
||||||
|
'Other users who can edit the object can edit its rules.'),
|
||||||
|
'enabled' => true,
|
||||||
|
),
|
||||||
|
HeraldRuleTypeConfig::RULE_TYPE_GLOBAL => array(
|
||||||
|
'name' => pht('Global Rule'),
|
||||||
|
'icon' => 'fa-globe',
|
||||||
|
'help' => array(
|
||||||
|
pht(
|
||||||
|
'Global rules notify anyone about events. Global rules can '.
|
||||||
|
'bypass access control policies and act on any object.'),
|
||||||
|
$global_note,
|
||||||
|
),
|
||||||
|
'enabled' => $can_global,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
$cancel_text = pht('Back');
|
$adapter_type = $adapter->getAdapterContentType();
|
||||||
$cancel_uri = new PhutilURI('new/', $params);
|
|
||||||
$cancel_uri = $this->getApplicationURI($cancel_uri);
|
$base_uri = new PhutilURI($this->getApplicationURI('create/'));
|
||||||
$title = pht('Create Herald Rule: %s',
|
|
||||||
idx($content_type_map, $content_type));
|
$adapter_uri = id(clone $base_uri)
|
||||||
break;
|
->replaceQueryParam('adapter', $adapter_type);
|
||||||
case 2:
|
|
||||||
$adapter = HeraldAdapter::getAdapterForContentType($content_type);
|
$menu = id(new PHUIObjectItemListView())
|
||||||
$form
|
->setUser($viewer)
|
||||||
->addHiddenInput('content_type', $content_type)
|
->setBig(true);
|
||||||
->addHiddenInput('rule_type', $rule_type)
|
|
||||||
->addHiddenInput('step', 3)
|
foreach ($specs as $rule_type => $spec) {
|
||||||
|
$type_uri = id(clone $adapter_uri)
|
||||||
|
->replaceQueryParam('type', $rule_type);
|
||||||
|
|
||||||
|
$name = $spec['name'];
|
||||||
|
$icon = $spec['icon'];
|
||||||
|
|
||||||
|
$description = $spec['help'];
|
||||||
|
$description = (array)$description;
|
||||||
|
|
||||||
|
$enabled = $spec['enabled'];
|
||||||
|
if ($enabled) {
|
||||||
|
$enabled = $adapter->supportsRuleType($rule_type);
|
||||||
|
if (!$enabled) {
|
||||||
|
$description[] = phutil_tag(
|
||||||
|
'em',
|
||||||
|
array(),
|
||||||
|
pht(
|
||||||
|
'This rule type is not supported by the selected '.
|
||||||
|
'content type.'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$description = phutil_implode_html(
|
||||||
|
array(
|
||||||
|
phutil_tag('br'),
|
||||||
|
phutil_tag('br'),
|
||||||
|
),
|
||||||
|
$description);
|
||||||
|
|
||||||
|
$item = id(new PHUIObjectItemView())
|
||||||
|
->setHeader($name)
|
||||||
|
->setImageIcon($icon)
|
||||||
|
->addAttribute($description);
|
||||||
|
|
||||||
|
if ($enabled) {
|
||||||
|
$item
|
||||||
|
->setHref($type_uri)
|
||||||
|
->setClickable(true);
|
||||||
|
} else {
|
||||||
|
$item->setDisabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$menu->addItem($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
$box = id(new PHUIObjectBoxView())
|
||||||
|
->setHeaderText($title)
|
||||||
|
->setBackground(PHUIObjectBoxView::WHITE_CONFIG)
|
||||||
|
->setObjectList($menu);
|
||||||
|
|
||||||
|
$box->newTailButton()
|
||||||
|
->setText(pht('Back to Content Types'))
|
||||||
|
->setIcon('fa-chevron-left')
|
||||||
|
->setHref($base_uri);
|
||||||
|
|
||||||
|
return id(new PHUILauncherView())
|
||||||
|
->appendChild($box);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function newTargetForm(
|
||||||
|
HeraldAdapter $adapter,
|
||||||
|
$rule_type,
|
||||||
|
$object_name,
|
||||||
|
$errors,
|
||||||
|
$e_object,
|
||||||
|
$title) {
|
||||||
|
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
$content_type = $adapter->getAdapterContentType();
|
||||||
|
$rule_type_map = HeraldRuleTypeConfig::getRuleTypeMap();
|
||||||
|
|
||||||
|
$params = array(
|
||||||
|
'adapter' => $content_type,
|
||||||
|
'type' => $rule_type,
|
||||||
|
);
|
||||||
|
|
||||||
|
$form = id(new AphrontFormView())
|
||||||
|
->setViewer($viewer)
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormStaticControl())
|
id(new AphrontFormStaticControl())
|
||||||
->setLabel(pht('Rule for'))
|
->setLabel(pht('Rule for'))
|
||||||
|
@ -150,7 +303,7 @@ final class HeraldNewController extends HeraldController {
|
||||||
phutil_tag(
|
phutil_tag(
|
||||||
'strong',
|
'strong',
|
||||||
array(),
|
array(),
|
||||||
idx($content_type_map, $content_type))))
|
$adapter->getAdapterContentName())))
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormStaticControl())
|
id(new AphrontFormStaticControl())
|
||||||
->setLabel(pht('Rule Type'))
|
->setLabel(pht('Rule Type'))
|
||||||
|
@ -170,28 +323,23 @@ final class HeraldNewController extends HeraldController {
|
||||||
id(new AphrontFormTextControl())
|
id(new AphrontFormTextControl())
|
||||||
->setName('objectName')
|
->setName('objectName')
|
||||||
->setError($e_object)
|
->setError($e_object)
|
||||||
->setValue($request->getStr('objectName'))
|
->setValue($object_name)
|
||||||
->setLabel(pht('Object')));
|
->setLabel(pht('Object')));
|
||||||
|
|
||||||
$params = array(
|
foreach ($params as $key => $value) {
|
||||||
'content_type' => $content_type,
|
$form->addHiddenInput($key, $value);
|
||||||
'rule_type' => $rule_type,
|
|
||||||
'step' => 1,
|
|
||||||
);
|
|
||||||
|
|
||||||
$cancel_text = pht('Back');
|
|
||||||
$cancel_uri = new PhutilURI('new/', $params);
|
|
||||||
$cancel_uri = $this->getApplicationURI($cancel_uri);
|
|
||||||
$title = pht('Create Herald Rule: %s',
|
|
||||||
idx($content_type_map, $content_type));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$form
|
$cancel_params = $params;
|
||||||
->appendChild(
|
unset($cancel_params['type']);
|
||||||
|
|
||||||
|
$cancel_uri = $this->getApplicationURI('new/');
|
||||||
|
$cancel_uri = new PhutilURI($cancel_uri, $params);
|
||||||
|
|
||||||
|
$form->appendChild(
|
||||||
id(new AphrontFormSubmitControl())
|
id(new AphrontFormSubmitControl())
|
||||||
->setValue(pht('Continue'))
|
->setValue(pht('Continue'))
|
||||||
->addCancelButton($cancel_uri, $cancel_text));
|
->addCancelButton($cancel_uri, pht('Back')));
|
||||||
|
|
||||||
$form_box = id(new PHUIObjectBoxView())
|
$form_box = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText($title)
|
->setHeaderText($title)
|
||||||
|
@ -199,118 +347,7 @@ final class HeraldNewController extends HeraldController {
|
||||||
->setBackground(PHUIObjectBoxView::WHITE_CONFIG)
|
->setBackground(PHUIObjectBoxView::WHITE_CONFIG)
|
||||||
->setForm($form);
|
->setForm($form);
|
||||||
|
|
||||||
$crumbs = $this
|
return $form_box;
|
||||||
->buildApplicationCrumbs()
|
|
||||||
->addTextCrumb(pht('Create Rule'))
|
|
||||||
->setBorder(true);
|
|
||||||
|
|
||||||
$view = id(new PHUITwoColumnView())
|
|
||||||
->setFooter($form_box);
|
|
||||||
|
|
||||||
return $this->newPage()
|
|
||||||
->setTitle($title)
|
|
||||||
->setCrumbs($crumbs)
|
|
||||||
->appendChild(
|
|
||||||
array(
|
|
||||||
$view,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function renderContentTypeControl(array $content_type_map, $e_type) {
|
|
||||||
$request = $this->getRequest();
|
|
||||||
|
|
||||||
$radio = id(new AphrontFormRadioButtonControl())
|
|
||||||
->setLabel(pht('New Rule for'))
|
|
||||||
->setName('content_type')
|
|
||||||
->setValue($request->getStr('content_type'))
|
|
||||||
->setError($e_type);
|
|
||||||
|
|
||||||
foreach ($content_type_map as $value => $name) {
|
|
||||||
$adapter = HeraldAdapter::getAdapterForContentType($value);
|
|
||||||
$radio->addButton(
|
|
||||||
$value,
|
|
||||||
$name,
|
|
||||||
phutil_escape_html_newlines($adapter->getAdapterContentDescription()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $radio;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private function renderRuleTypeControl(array $rule_type_map, $e_rule) {
|
|
||||||
$request = $this->getRequest();
|
|
||||||
|
|
||||||
// Reorder array to put less powerful rules first.
|
|
||||||
$rule_type_map = array_select_keys(
|
|
||||||
$rule_type_map,
|
|
||||||
array(
|
|
||||||
HeraldRuleTypeConfig::RULE_TYPE_PERSONAL,
|
|
||||||
HeraldRuleTypeConfig::RULE_TYPE_OBJECT,
|
|
||||||
HeraldRuleTypeConfig::RULE_TYPE_GLOBAL,
|
|
||||||
)) + $rule_type_map;
|
|
||||||
|
|
||||||
list($can_global, $global_link) = $this->explainApplicationCapability(
|
|
||||||
HeraldManageGlobalRulesCapability::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 =>
|
|
||||||
pht(
|
|
||||||
'Personal rules notify you about events. You own them, but they can '.
|
|
||||||
'only affect you. Personal rules only trigger for objects you have '.
|
|
||||||
'permission to see.'),
|
|
||||||
HeraldRuleTypeConfig::RULE_TYPE_OBJECT =>
|
|
||||||
pht(
|
|
||||||
'Object rules notify anyone about events. They are bound to an '.
|
|
||||||
'object (like a repository) and can only act on that object. You '.
|
|
||||||
'must be able to edit an object to create object rules for it. '.
|
|
||||||
'Other users who can edit the object can edit its rules.'),
|
|
||||||
HeraldRuleTypeConfig::RULE_TYPE_GLOBAL =>
|
|
||||||
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())
|
|
||||||
->setLabel(pht('Rule Type'))
|
|
||||||
->setName('rule_type')
|
|
||||||
->setValue($request->getStr('rule_type'))
|
|
||||||
->setError($e_rule);
|
|
||||||
|
|
||||||
$adapter = HeraldAdapter::getAdapterForContentType(
|
|
||||||
$request->getStr('content_type'));
|
|
||||||
|
|
||||||
foreach ($rule_type_map as $value => $name) {
|
|
||||||
$caption = idx($captions, $value);
|
|
||||||
$disabled = ($value == HeraldRuleTypeConfig::RULE_TYPE_GLOBAL) &&
|
|
||||||
(!$can_global);
|
|
||||||
|
|
||||||
if (!$adapter->supportsRuleType($value)) {
|
|
||||||
$disabled = true;
|
|
||||||
$caption = array(
|
|
||||||
$caption,
|
|
||||||
"\n\n",
|
|
||||||
phutil_tag(
|
|
||||||
'em',
|
|
||||||
array(),
|
|
||||||
pht(
|
|
||||||
'This rule type is not supported by the selected content type.')),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$radio->addButton(
|
|
||||||
$value,
|
|
||||||
$name,
|
|
||||||
phutil_escape_html_newlines($caption),
|
|
||||||
$disabled ? 'disabled' : null,
|
|
||||||
$disabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $radio;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ final class PHUIObjectBoxView extends AphrontTagView {
|
||||||
private $showHideOpen;
|
private $showHideOpen;
|
||||||
|
|
||||||
private $propertyLists = array();
|
private $propertyLists = array();
|
||||||
|
private $tailButtons = array();
|
||||||
|
|
||||||
const COLOR_RED = 'red';
|
const COLOR_RED = 'red';
|
||||||
const COLOR_BLUE = 'blue';
|
const COLOR_BLUE = 'blue';
|
||||||
|
@ -153,6 +154,16 @@ final class PHUIObjectBoxView extends AphrontTagView {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function newTailButton() {
|
||||||
|
$button = id(new PHUIButtonView())
|
||||||
|
->setTag('a')
|
||||||
|
->setColor(PHUIButtonView::GREY);
|
||||||
|
|
||||||
|
$this->tailButtons[] = $button;
|
||||||
|
|
||||||
|
return $button;
|
||||||
|
}
|
||||||
|
|
||||||
protected function getTagAttributes() {
|
protected function getTagAttributes() {
|
||||||
$classes = array();
|
$classes = array();
|
||||||
$classes[] = 'phui-box';
|
$classes[] = 'phui-box';
|
||||||
|
@ -329,6 +340,15 @@ final class PHUIObjectBoxView extends AphrontTagView {
|
||||||
$content[] = $this->objectList;
|
$content[] = $this->objectList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->tailButtons) {
|
||||||
|
$content[] = phutil_tag(
|
||||||
|
'div',
|
||||||
|
array(
|
||||||
|
'class' => 'phui-object-box-tail-buttons',
|
||||||
|
),
|
||||||
|
$this->tailButtons);
|
||||||
|
}
|
||||||
|
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,12 @@ div.phui-object-box.phui-object-box-flush {
|
||||||
font-size: {$normalfontsize};
|
font-size: {$normalfontsize};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.phui-object-box-tail-buttons {
|
||||||
|
padding: 8px;
|
||||||
|
background: {$lightgreybackground};
|
||||||
|
border-top: 1px solid {$lightgreyborder};
|
||||||
|
}
|
||||||
|
|
||||||
/* - Object Box Colors ------------------------------------------------------ */
|
/* - Object Box Colors ------------------------------------------------------ */
|
||||||
|
|
||||||
.phui-box-border.phui-object-box-green {
|
.phui-box-border.phui-object-box-green {
|
||||||
|
|
Loading…
Reference in a new issue