From c5e7222f9e900910ec53843be3fc341eb5640fcd Mon Sep 17 00:00:00 2001 From: Chad Little Date: Mon, 20 May 2013 08:24:07 -0700 Subject: [PATCH] Modernize Herald Summary: Convert to responsive layout, pht, etc. Test Plan: Test Herald on desktop and mobile. Reviewers: epriestley, btrahan Reviewed By: epriestley CC: aran, Korvin Differential Revision: https://secure.phabricator.com/D5976 --- .../herald/adapter/HeraldCommitAdapter.php | 6 +- .../HeraldDifferentialRevisionAdapter.php | 18 ++--- .../herald/adapter/HeraldDryRunAdapter.php | 2 +- .../herald/adapter/HeraldObjectAdapter.php | 7 +- .../PhabricatorApplicationHerald.php | 2 +- .../herald/config/HeraldActionConfig.php | 22 +++--- .../herald/config/HeraldConditionConfig.php | 36 ++++----- .../herald/config/HeraldContentTypeConfig.php | 6 +- .../herald/config/HeraldFieldConfig.php | 39 +++++----- .../herald/config/HeraldRuleTypeConfig.php | 6 +- .../herald/controller/HeraldController.php | 34 ++++++--- .../controller/HeraldDeleteController.php | 9 ++- .../controller/HeraldHomeController.php | 45 +++++------ .../herald/controller/HeraldNewController.php | 21 +++-- .../controller/HeraldRuleController.php | 76 ++++++++++--------- .../HeraldRuleEditHistoryController.php | 14 +++- .../HeraldTestConsoleController.php | 34 +++++---- .../controller/HeraldTranscriptController.php | 74 ++++++++++-------- .../HeraldTranscriptListController.php | 20 ++--- .../herald/view/HeraldRuleEditHistoryView.php | 39 ++++------ .../herald/view/HeraldRuleListView.php | 70 ++++++----------- 21 files changed, 299 insertions(+), 281 deletions(-) diff --git a/src/applications/herald/adapter/HeraldCommitAdapter.php b/src/applications/herald/adapter/HeraldCommitAdapter.php index 35cb0e0ddf..754912d6e0 100644 --- a/src/applications/herald/adapter/HeraldCommitAdapter.php +++ b/src/applications/herald/adapter/HeraldCommitAdapter.php @@ -204,7 +204,7 @@ final class HeraldCommitAdapter extends HeraldObjectAdapter { $result[] = new HeraldApplyTranscript( $effect, true, - 'Great success at doing nothing.'); + pht('Great success at doing nothing.')); break; case HeraldActionConfig::ACTION_EMAIL: foreach ($effect->getTarget() as $phid) { @@ -213,7 +213,7 @@ final class HeraldCommitAdapter extends HeraldObjectAdapter { $result[] = new HeraldApplyTranscript( $effect, true, - 'Added address to email targets.'); + pht('Added address to email targets.')); break; case HeraldActionConfig::ACTION_AUDIT: foreach ($effect->getTarget() as $phid) { @@ -225,7 +225,7 @@ final class HeraldCommitAdapter extends HeraldObjectAdapter { $result[] = new HeraldApplyTranscript( $effect, true, - 'Triggered an audit.'); + pht('Triggered an audit.')); break; case HeraldActionConfig::ACTION_FLAG: $result[] = parent::applyFlagEffect( diff --git a/src/applications/herald/adapter/HeraldDifferentialRevisionAdapter.php b/src/applications/herald/adapter/HeraldDifferentialRevisionAdapter.php index a4be15d361..d17b560b52 100644 --- a/src/applications/herald/adapter/HeraldDifferentialRevisionAdapter.php +++ b/src/applications/herald/adapter/HeraldDifferentialRevisionAdapter.php @@ -217,12 +217,12 @@ final class HeraldDifferentialRevisionAdapter extends HeraldObjectAdapter { $effect->setAction(HeraldActionConfig::ACTION_ADD_CC); $effect->setTarget(array_keys($this->explicitCCs)); $effect->setReason( - 'CCs provided explicitly by revision author or carried over from a '. - 'previous version of the revision.'); + pht('CCs provided explicitly by revision author or carried over '. + 'from a previous version of the revision.')); $result[] = new HeraldApplyTranscript( $effect, true, - 'Added addresses to CC list.'); + pht('Added addresses to CC list.')); } $forbidden_ccs = array_fill_keys( @@ -236,7 +236,7 @@ final class HeraldDifferentialRevisionAdapter extends HeraldObjectAdapter { $result[] = new HeraldApplyTranscript( $effect, true, - 'OK, did nothing.'); + pht('OK, did nothing.')); break; case HeraldActionConfig::ACTION_FLAG: $result[] = parent::applyFlagEffect( @@ -269,18 +269,18 @@ final class HeraldDifferentialRevisionAdapter extends HeraldObjectAdapter { $result[] = new HeraldApplyTranscript( $effect, true, - 'Added these addresses to '.$op.' list. '. - 'Others could not be added.'); + pht('Added these addresses to %s list. '. + 'Others could not be added.', $op)); } $result[] = new HeraldApplyTranscript( $failed, false, - $op.' forbidden, these addresses have unsubscribed.'); + pht('%s forbidden, these addresses have unsubscribed.', $op)); } else { $result[] = new HeraldApplyTranscript( $effect, true, - 'Added addresses to '.$op.' list.'); + pht('Added addresses to %s list.', $op)); } break; case HeraldActionConfig::ACTION_REMOVE_CC: @@ -290,7 +290,7 @@ final class HeraldDifferentialRevisionAdapter extends HeraldObjectAdapter { $result[] = new HeraldApplyTranscript( $effect, true, - 'Removed addresses from CC list.'); + pht('Removed addresses from CC list.')); break; default: throw new Exception("No rules to handle action '{$action}'."); diff --git a/src/applications/herald/adapter/HeraldDryRunAdapter.php b/src/applications/herald/adapter/HeraldDryRunAdapter.php index 4c58374578..8d82e0da64 100644 --- a/src/applications/herald/adapter/HeraldDryRunAdapter.php +++ b/src/applications/herald/adapter/HeraldDryRunAdapter.php @@ -25,7 +25,7 @@ final class HeraldDryRunAdapter extends HeraldObjectAdapter { $results[] = new HeraldApplyTranscript( $effect, false, - 'This was a dry run, so no actions were actually taken.'); + pht('This was a dry run, so no actions were actually taken.')); } return $results; } diff --git a/src/applications/herald/adapter/HeraldObjectAdapter.php b/src/applications/herald/adapter/HeraldObjectAdapter.php index 0a1d2c7b43..7b2949ed8d 100644 --- a/src/applications/herald/adapter/HeraldObjectAdapter.php +++ b/src/applications/herald/adapter/HeraldObjectAdapter.php @@ -22,7 +22,7 @@ abstract class HeraldObjectAdapter { return new HeraldApplyTranscript( $effect, false, - 'Object already flagged.'); + pht('Object already flagged.')); } $handle = PhabricatorObjectHandleData::loadOneHandle( @@ -38,13 +38,14 @@ abstract class HeraldObjectAdapter { $flag->setReasonPHID($user->getPHID()); $flag->setColor($color); - $flag->setNote('Flagged by Herald Rule "'.$rule->getName().'".'); + $flag->setNote( + pht('Flagged by Herald Rule "%s".', $rule->getName())); $flag->save(); return new HeraldApplyTranscript( $effect, true, - 'Added flag.'); + pht('Added flag.')); } } diff --git a/src/applications/herald/application/PhabricatorApplicationHerald.php b/src/applications/herald/application/PhabricatorApplicationHerald.php index 7687a906ea..f751971093 100644 --- a/src/applications/herald/application/PhabricatorApplicationHerald.php +++ b/src/applications/herald/application/PhabricatorApplicationHerald.php @@ -11,7 +11,7 @@ final class PhabricatorApplicationHerald extends PhabricatorApplication { } public function getShortDescription() { - return 'Create Notification Rules'; + return pht('Create Notification Rules'); } public function getTitleGlyph() { diff --git a/src/applications/herald/config/HeraldActionConfig.php b/src/applications/herald/config/HeraldActionConfig.php index ea7a8d3cb4..1194fdfcec 100644 --- a/src/applications/herald/config/HeraldActionConfig.php +++ b/src/applications/herald/config/HeraldActionConfig.php @@ -11,26 +11,26 @@ final class HeraldActionConfig { public static function getActionMessageMapForRuleType($rule_type) { $generic_mappings = array( - self::ACTION_NOTHING => 'Do nothing', - self::ACTION_ADD_CC => 'Add emails to CC', - self::ACTION_REMOVE_CC => 'Remove emails from CC', - self::ACTION_EMAIL => 'Send an email to', - self::ACTION_AUDIT => 'Trigger an Audit', - self::ACTION_FLAG => 'Mark with flag', + self::ACTION_NOTHING => pht('Do nothing'), + self::ACTION_ADD_CC => pht('Add emails to CC'), + self::ACTION_REMOVE_CC => pht('Remove emails from CC'), + self::ACTION_EMAIL => pht('Send an email to'), + self::ACTION_AUDIT => pht('Trigger an Audit'), + self::ACTION_FLAG => pht('Mark with flag'), ); switch ($rule_type) { case HeraldRuleTypeConfig::RULE_TYPE_GLOBAL: $specific_mappings = array( - self::ACTION_AUDIT => 'Trigger an Audit for project', + self::ACTION_AUDIT => pht('Trigger an Audit for project'), ); break; case HeraldRuleTypeConfig::RULE_TYPE_PERSONAL: $specific_mappings = array( - self::ACTION_ADD_CC => 'CC me', - self::ACTION_REMOVE_CC => 'Remove me from CC', - self::ACTION_EMAIL => 'Email me', - self::ACTION_AUDIT => 'Trigger an Audit by me', + self::ACTION_ADD_CC => pht('CC me'), + self::ACTION_REMOVE_CC => pht('Remove me from CC'), + self::ACTION_EMAIL => pht('Email me'), + self::ACTION_AUDIT => pht('Trigger an Audit by me'), ); break; case null: diff --git a/src/applications/herald/config/HeraldConditionConfig.php b/src/applications/herald/config/HeraldConditionConfig.php index 55fc1e9718..b273ebf2ba 100644 --- a/src/applications/herald/config/HeraldConditionConfig.php +++ b/src/applications/herald/config/HeraldConditionConfig.php @@ -21,24 +21,24 @@ final class HeraldConditionConfig { const CONDITION_REGEXP_PAIR = 'regexp-pair'; public static function getConditionMap() { - static $map = array( - self::CONDITION_CONTAINS => 'contains', - self::CONDITION_NOT_CONTAINS => 'does not contain', - self::CONDITION_IS => 'is', - self::CONDITION_IS_NOT => 'is not', - self::CONDITION_IS_ANY => 'is any of', - self::CONDITION_IS_NOT_ANY => 'is not any of', - self::CONDITION_INCLUDE_ALL => 'include all of', - self::CONDITION_INCLUDE_ANY => 'include any of', - self::CONDITION_INCLUDE_NONE => 'include none of', - self::CONDITION_IS_ME => 'is myself', - self::CONDITION_IS_NOT_ME => 'is not myself', - self::CONDITION_REGEXP => 'matches regexp', - self::CONDITION_RULE => 'matches:', - self::CONDITION_NOT_RULE => 'does not match:', - self::CONDITION_EXISTS => 'exists', - self::CONDITION_NOT_EXISTS => 'does not exist', - self::CONDITION_REGEXP_PAIR => 'matches regexp pair', + $map = array( + self::CONDITION_CONTAINS => pht('contains'), + self::CONDITION_NOT_CONTAINS => pht('does not contain'), + self::CONDITION_IS => pht('is'), + self::CONDITION_IS_NOT => pht('is not'), + self::CONDITION_IS_ANY => pht('is any of'), + self::CONDITION_IS_NOT_ANY => pht('is not any of'), + self::CONDITION_INCLUDE_ALL => pht('include all of'), + self::CONDITION_INCLUDE_ANY => pht('include any of'), + self::CONDITION_INCLUDE_NONE => pht('include none of'), + self::CONDITION_IS_ME => pht('is myself'), + self::CONDITION_IS_NOT_ME => pht('is not myself'), + self::CONDITION_REGEXP => pht('matches regexp'), + self::CONDITION_RULE => pht('matches:'), + self::CONDITION_NOT_RULE => pht('does not match:'), + self::CONDITION_EXISTS => pht('exists'), + self::CONDITION_NOT_EXISTS => pht('does not exist'), + self::CONDITION_REGEXP_PAIR => pht('matches regexp pair'), ); return $map; diff --git a/src/applications/herald/config/HeraldContentTypeConfig.php b/src/applications/herald/config/HeraldContentTypeConfig.php index 364a6f0912..01ea861b67 100644 --- a/src/applications/herald/config/HeraldContentTypeConfig.php +++ b/src/applications/herald/config/HeraldContentTypeConfig.php @@ -8,9 +8,9 @@ final class HeraldContentTypeConfig { const CONTENT_TYPE_OWNERS = 'owners'; public static function getContentTypeMap() { - static $map = array( - self::CONTENT_TYPE_DIFFERENTIAL => 'Differential Revisions', - self::CONTENT_TYPE_COMMIT => 'Commits', + $map = array( + self::CONTENT_TYPE_DIFFERENTIAL => pht('Differential Revisions'), + self::CONTENT_TYPE_COMMIT => pht('Commits'), /* TODO: Deal with this self::CONTENT_TYPE_MERGE => 'Merge Requests', self::CONTENT_TYPE_OWNERS => 'Owners Changes', diff --git a/src/applications/herald/config/HeraldFieldConfig.php b/src/applications/herald/config/HeraldFieldConfig.php index d2273e27ac..8942815102 100644 --- a/src/applications/herald/config/HeraldFieldConfig.php +++ b/src/applications/herald/config/HeraldFieldConfig.php @@ -22,26 +22,27 @@ final class HeraldFieldConfig { const FIELD_MERGE_REQUESTER = 'merge-requester'; public static function getFieldMap() { - static $map = array( - self::FIELD_TITLE => 'Title', - self::FIELD_BODY => 'Body', - self::FIELD_AUTHOR => 'Author', - self::FIELD_REVIEWER => 'Reviewer', - self::FIELD_REVIEWERS => 'Reviewers', - self::FIELD_CC => 'CCs', - self::FIELD_TAGS => 'Tags', - self::FIELD_DIFF_FILE => 'Any changed filename', - self::FIELD_DIFF_CONTENT => 'Any changed file content', - self::FIELD_REPOSITORY => 'Repository', - self::FIELD_RULE => 'Another Herald rule', - self::FIELD_AFFECTED_PACKAGE => 'Any affected package', - self::FIELD_AFFECTED_PACKAGE_OWNER => "Any affected package's owner", + $map = array( + self::FIELD_TITLE => pht('Title'), + self::FIELD_BODY => pht('Body'), + self::FIELD_AUTHOR => pht('Author'), + self::FIELD_REVIEWER => pht('Reviewer'), + self::FIELD_REVIEWERS => pht('Reviewers'), + self::FIELD_CC => pht('CCs'), + self::FIELD_TAGS => pht('Tags'), + self::FIELD_DIFF_FILE => pht('Any changed filename'), + self::FIELD_DIFF_CONTENT => pht('Any changed file content'), + self::FIELD_REPOSITORY => pht('Repository'), + self::FIELD_RULE => pht('Another Herald rule'), + self::FIELD_AFFECTED_PACKAGE => pht('Any affected package'), + self::FIELD_AFFECTED_PACKAGE_OWNER => + pht("Any affected package's owner"), self::FIELD_NEED_AUDIT_FOR_PACKAGE => - 'Affected packages that need audit', - self::FIELD_DIFFERENTIAL_REVISION => 'Differential revision', - self::FIELD_DIFFERENTIAL_REVIEWERS => 'Differential reviewers', - self::FIELD_DIFFERENTIAL_CCS => 'Differential CCs', - self::FIELD_MERGE_REQUESTER => 'Merge requester' + pht('Affected packages that need audit'), + self::FIELD_DIFFERENTIAL_REVISION => pht('Differential revision'), + self::FIELD_DIFFERENTIAL_REVIEWERS => pht('Differential reviewers'), + self::FIELD_DIFFERENTIAL_CCS => pht('Differential CCs'), + self::FIELD_MERGE_REQUESTER => pht('Merge requester') ); return $map; diff --git a/src/applications/herald/config/HeraldRuleTypeConfig.php b/src/applications/herald/config/HeraldRuleTypeConfig.php index 7d9e4812f8..6d9712134a 100644 --- a/src/applications/herald/config/HeraldRuleTypeConfig.php +++ b/src/applications/herald/config/HeraldRuleTypeConfig.php @@ -6,9 +6,9 @@ final class HeraldRuleTypeConfig { const RULE_TYPE_PERSONAL = 'personal'; public static function getRuleTypeMap() { - static $map = array( - self::RULE_TYPE_GLOBAL => 'Global', - self::RULE_TYPE_PERSONAL => 'Personal', + $map = array( + self::RULE_TYPE_GLOBAL => pht('Global'), + self::RULE_TYPE_PERSONAL => pht('Personal'), ); return $map; } diff --git a/src/applications/herald/controller/HeraldController.php b/src/applications/herald/controller/HeraldController.php index 7ad03c5fd2..9242792316 100644 --- a/src/applications/herald/controller/HeraldController.php +++ b/src/applications/herald/controller/HeraldController.php @@ -5,7 +5,7 @@ abstract class HeraldController extends PhabricatorController { public function buildStandardPageResponse($view, array $data) { $page = $this->buildStandardPageView(); - $page->setApplicationName('Herald'); + $page->setApplicationName(pht('Herald')); $page->setBaseURI('/herald/'); $page->setTitle(idx($data, 'title')); $page->setGlyph("\xE2\x98\xBF"); @@ -16,31 +16,47 @@ abstract class HeraldController extends PhabricatorController { return $response->setContent($page->render()); } + public function buildApplicationMenu() { + return $this->renderNav()->getMenu(); + } + + public function buildApplicationCrumbs() { + $crumbs = parent::buildApplicationCrumbs(); + + $crumbs->addAction( + id(new PhabricatorMenuItemView()) + ->setName(pht('Create Herald Rule')) + ->setHref($this->getApplicationURI('new/')) + ->setIcon('create')); + + return $crumbs; + } + protected function renderNav() { $nav = id(new AphrontSideNavFilterView()) ->setBaseURI(new PhutilURI('/herald/')) - ->addLabel('My Rules') - ->addFilter('new', 'Create Rule'); + ->addLabel(pht('My Rules')) + ->addFilter('new', pht('Create Rule')); $rules_map = HeraldContentTypeConfig::getContentTypeMap(); foreach ($rules_map as $key => $value) { $nav->addFilter("view/{$key}/personal", $value); } - $nav->addLabel('Global Rules'); + $nav->addLabel(pht('Global Rules')); foreach ($rules_map as $key => $value) { $nav->addFilter("view/{$key}/global", $value); } $nav - ->addLabel('Utilities') - ->addFilter('test', 'Test Console') - ->addFilter('transcript', 'Transcripts') - ->addFilter('history', 'Edit Log'); + ->addLabel(pht('Utilities')) + ->addFilter('test', pht('Test Console')) + ->addFilter('transcript', pht('Transcripts')) + ->addFilter('history', pht('Edit Log')); if ($this->getRequest()->getUser()->getIsAdmin()) { - $nav->addLabel('Admin'); + $nav->addLabel(pht('Admin')); foreach ($rules_map as $key => $value) { $nav->addFilter("view/{$key}/all", $value); } diff --git a/src/applications/herald/controller/HeraldDeleteController.php b/src/applications/herald/controller/HeraldDeleteController.php index 8649f63993..47fb857849 100644 --- a/src/applications/herald/controller/HeraldDeleteController.php +++ b/src/applications/herald/controller/HeraldDeleteController.php @@ -42,11 +42,12 @@ final class HeraldDeleteController extends HeraldController { $dialog = new AphrontDialogView(); $dialog->setUser($request->getUser()); - $dialog->setTitle('Really delete this rule?'); - $dialog->appendChild(hsprintf( - "Are you sure you want to delete the rule '%s'?", + $dialog->setTitle(pht('Really delete this rule?')); + $dialog->setHeaderColor(PhabricatorActionHeaderView::HEADER_RED); + $dialog->appendChild(pht( + "Are you sure you want to delete the rule: %s?", $rule->getName())); - $dialog->addSubmitButton('Delete'); + $dialog->addSubmitButton(pht('Delete')); $dialog->addCancelButton('/herald/'); $dialog->setSubmitURI($request->getPath()); diff --git a/src/applications/herald/controller/HeraldHomeController.php b/src/applications/herald/controller/HeraldHomeController.php index 66d95c3956..223d70998f 100644 --- a/src/applications/herald/controller/HeraldHomeController.php +++ b/src/applications/herald/controller/HeraldHomeController.php @@ -36,10 +36,8 @@ final class HeraldHomeController extends HeraldController { $query->withContentTypes(array($this->contentType)); - $is_admin_page = false; $show_author = false; $show_rule_type = false; - $can_create = false; $has_author_filter = false; $author_filter_phid = null; @@ -48,7 +46,6 @@ final class HeraldHomeController extends HeraldController { if (!$user->getIsAdmin()) { return new Aphront400Response(); } - $is_admin_page = true; $show_rule_type = true; $show_author = true; $has_author_filter = true; @@ -56,20 +53,18 @@ final class HeraldHomeController extends HeraldController { if ($author_filter_phid) { $query->withAuthorPHIDs(array($author_filter_phid)); } - $rule_desc = 'All'; + $rule_desc = pht('All'); break; case HeraldRuleTypeConfig::RULE_TYPE_GLOBAL: $query->withRuleTypes(array(HeraldRuleTypeConfig::RULE_TYPE_GLOBAL)); - $can_create = true; - $rule_desc = 'Global'; + $rule_desc = pht('Global'); break; case HeraldRuleTypeConfig::RULE_TYPE_PERSONAL: default: $this->ruleType = HeraldRuleTypeConfig::RULE_TYPE_PERSONAL; $query->withRuleTypes(array(HeraldRuleTypeConfig::RULE_TYPE_PERSONAL)); $query->withAuthorPHIDs(array($user->getPHID())); - $can_create = true; - $rule_desc = 'Personal'; + $rule_desc = pht('Personal'); break; } @@ -94,19 +89,16 @@ final class HeraldHomeController extends HeraldController { $panel->appendChild($pager); $panel->setNoBackground(); - $panel->setHeader("Herald: {$rule_desc} Rules for {$content_desc}"); - - if ($can_create) { - $panel->addButton( - phutil_tag( - 'a', - array( - 'href' => '/herald/new/'.$this->contentType.'/'.$this->ruleType.'/', - 'class' => 'green button', - ), - 'Create New Herald Rule')); - } + $panel->setHeader( + pht("Herald: %s Rules for %s", $rule_desc, $content_desc)); + $crumbs = $this + ->buildApplicationCrumbs() + ->addCrumb( + id(new PhabricatorCrumbView()) + ->setName(pht('Herald Rules')) + ->setHref($this->getApplicationURI( + 'view/'.$this->contentType.'/'.$this->ruleType))); $nav = $this->renderNav(); $nav->selectFilter('view/'.$this->contentType.'/'.$this->ruleType); @@ -116,12 +108,14 @@ final class HeraldHomeController extends HeraldController { } $nav->appendChild($panel); + $nav->setCrumbs($crumbs); - return $this->buildStandardPageResponse( + return $this->buildApplicationPage( $nav, array( - 'title' => 'Herald', - 'admin' => $is_admin_page, + 'title' => pht('Herald'), + 'dust' => true, + 'device' => true, )); } @@ -140,16 +134,17 @@ final class HeraldHomeController extends HeraldController { $form = id(new AphrontFormView()) ->setUser($user) + ->setNoShading(true) ->appendChild( id(new AphrontFormTokenizerControl()) ->setName('set_phid') ->setValue($tokens) ->setLimit(1) - ->setLabel('Filter Author') + ->setLabel(pht('Filter Author')) ->setDataSource('/typeahead/common/accounts/')) ->appendChild( id(new AphrontFormSubmitControl()) - ->setValue('Apply Filter')); + ->setValue(pht('Apply Filter'))); $filter = new AphrontListFilterView(); $filter->appendChild($form); diff --git a/src/applications/herald/controller/HeraldNewController.php b/src/applications/herald/controller/HeraldNewController.php index 327379b517..15e0f52cba 100644 --- a/src/applications/herald/controller/HeraldNewController.php +++ b/src/applications/herald/controller/HeraldNewController.php @@ -34,16 +34,16 @@ final class HeraldNewController extends HeraldController { $captions = array( HeraldRuleTypeConfig::RULE_TYPE_PERSONAL => - 'Personal rules notify you about events. You own them, but they can '. - 'only affect you.', + pht('Personal rules notify you about events. You own them, but '. + 'they can only affect you.'), HeraldRuleTypeConfig::RULE_TYPE_GLOBAL => - 'Global rules notify anyone about events. No one owns them, and '. + pht('Global rules notify anyone about events. No one owns them, and '. 'anyone can edit them. Usually, Global rules are used to notify '. - 'mailing lists.', + 'mailing lists.'), ); $radio = id(new AphrontFormRadioButtonControl()) - ->setLabel('Type') + ->setLabel(pht('Type')) ->setName('rule_type') ->setValue($this->ruleType); @@ -70,13 +70,18 @@ final class HeraldNewController extends HeraldController { ->setValue(pht('Create Rule')) ->addCancelButton('/herald/view/'.$this->contentType.'/')); - $header = new PhabricatorHeaderView(); - $header->setHeader(pht('Create New Herald Rule')); + $crumbs = $this + ->buildApplicationCrumbs() + ->addCrumb( + id(new PhabricatorCrumbView()) + ->setName(pht('Create Herald Rule')) + ->setHref($this->getApplicationURI( + 'view/'.$this->contentType.'/'.$this->ruleType))); $nav = $this->renderNav(); $nav->selectFilter('new'); - $nav->appendChild($header); $nav->appendChild($form); + $nav->setCrumbs($crumbs); return $this->buildApplicationPage( $nav, diff --git a/src/applications/herald/controller/HeraldRuleController.php b/src/applications/herald/controller/HeraldRuleController.php index fa61e4f946..44d25a29af 100644 --- a/src/applications/herald/controller/HeraldRuleController.php +++ b/src/applications/herald/controller/HeraldRuleController.php @@ -75,7 +75,7 @@ final class HeraldRuleController extends HeraldController { if ($errors) { $error_view = new AphrontErrorView(); - $error_view->setTitle('Form Errors'); + $error_view->setTitle(pht('Form Errors')); $error_view->setErrors($errors); } else { $error_view = null; @@ -109,7 +109,7 @@ final class HeraldRuleController extends HeraldController { ))) ->appendChild( id(new AphrontFormTextControl()) - ->setLabel('Rule Name') + ->setLabel(pht('Rule Name')) ->setName('name') ->setError($e_name) ->setValue($rule->getName())); @@ -117,13 +117,13 @@ final class HeraldRuleController extends HeraldController { $form ->appendChild( id(new AphrontFormMarkupControl()) - ->setValue(hsprintf( - "This %s rule triggers for %s.", - $rule_type_name, - $content_type_name))) + ->setValue(pht( + "This %s rule triggers for %s.", + phutil_tag('strong', array(), $rule_type_name), + phutil_tag('strong', array(), $content_type_name)))) ->appendChild( id(new AphrontFormInsetView()) - ->setTitle('Conditions') + ->setTitle(pht('Conditions')) ->setRightButton(javelin_tag( 'a', array( @@ -132,9 +132,9 @@ final class HeraldRuleController extends HeraldController { 'sigil' => 'create-condition', 'mustcapture' => true ), - 'Create New Condition')) + pht('New Condition'))) ->setDescription( - hsprintf('When %s these conditions are met:', $must_match_selector)) + pht('When %s these conditions are met:', $must_match_selector)) ->setContent(javelin_tag( 'table', array( @@ -144,7 +144,7 @@ final class HeraldRuleController extends HeraldController { ''))) ->appendChild( id(new AphrontFormInsetView()) - ->setTitle('Action') + ->setTitle(pht('Action')) ->setRightButton(javelin_tag( 'a', array( @@ -153,8 +153,8 @@ final class HeraldRuleController extends HeraldController { 'sigil' => 'create-action', 'mustcapture' => true, ), - 'Create New Action')) - ->setDescription(hsprintf( + pht('New Action'))) + ->setDescription(pht( 'Take these actions %s this rule matches:', $repetition_selector)) ->setContent(javelin_tag( @@ -166,24 +166,29 @@ final class HeraldRuleController extends HeraldController { ''))) ->appendChild( id(new AphrontFormSubmitControl()) - ->setValue('Save Rule') + ->setValue(pht('Save Rule')) ->addCancelButton('/herald/view/'.$rule->getContentType().'/')); $this->setupEditorBehavior($rule, $handles); - $header = new PhabricatorHeaderView(); - $header->setHeader( - $rule->getID() + $title = $rule->getID() ? pht('Edit Herald Rule') - : pht('Create Herald Rule')); + : pht('Create Herald Rule'); + + $crumbs = $this + ->buildApplicationCrumbs() + ->addCrumb( + id(new PhabricatorCrumbView()) + ->setName($title) + ->setHref('#')); $nav = $this->renderNav(); + $nav->setCrumbs($crumbs); $nav->selectFilter( 'view/'.$rule->getContentType().'/'.$rule->getRuleType()); $nav->appendChild( array( $error_view, - $header, $form, )); @@ -191,6 +196,8 @@ final class HeraldRuleController extends HeraldController { $nav, array( 'title' => pht('Edit Rule'), + 'dust' => true, + 'device' => true, )); } @@ -213,8 +220,8 @@ final class HeraldRuleController extends HeraldController { $errors = array(); if (!strlen($rule->getName())) { - $e_name = "Required"; - $errors[] = "Rule must have a name."; + $e_name = pht("Required"); + $errors[] = pht("Rule must have a name."); } $data = json_decode($request->getStr('rule'), true); @@ -247,10 +254,10 @@ final class HeraldRuleController extends HeraldController { if ($cond_type == HeraldConditionConfig::CONDITION_REGEXP) { if (@preg_match($obj->getValue(), '') === false) { $errors[] = - 'The regular expression "'.$obj->getValue().'" is not valid. '. + pht('The regular expression "%s" is not valid. '. 'Regular expressions must have enclosing characters (e.g. '. '"@/path/to/file@", not "/path/to/file") and be syntactically '. - 'correct.'; + 'correct.', $obj->getValue()); } } @@ -258,26 +265,27 @@ final class HeraldRuleController extends HeraldController { $json = json_decode($obj->getValue(), true); if (!is_array($json)) { $errors[] = - 'The regular expression pair "'.$obj->getValue().'" is not '. - 'valid JSON. Enter a valid JSON array with two elements.'; + pht('The regular expression pair "%s" is not '. + 'valid JSON. Enter a valid JSON array with two elements.', + $obj->getValue()); } else { if (count($json) != 2) { $errors[] = - 'The regular expression pair "'.$obj->getValue().'" must have '. - 'exactly two elements.'; + pht('The regular expression pair "%s" must have '. + 'exactly two elements.', $obj->getValue()); } else { $key_regexp = array_shift($json); $val_regexp = array_shift($json); if (@preg_match($key_regexp, '') === false) { $errors[] = - 'The first regexp, "'.$key_regexp.'" in the regexp pair '. - 'is not a valid regexp.'; + pht('The first regexp, "%s" in the regexp pair '. + 'is not a valid regexp.', $key_regexp); } if (@preg_match($val_regexp, '') === false) { $errors[] = - 'The second regexp, "'.$val_regexp.'" in the regexp pair '. - 'is not a valid regexp.'; + pht('The second regexp, "%s" in the regexp pair '. + 'is not a valid regexp.', $val_regexp); } } } @@ -320,8 +328,8 @@ final class HeraldRuleController extends HeraldController { $rule->saveTransaction(); } catch (AphrontQueryDuplicateKeyException $ex) { - $e_name = "Not Unique"; - $errors[] = "Rule name is not unique. Choose a unique name."; + $e_name = pht("Not Unique"); + $errors[] = pht("Rule name is not unique. Choose a unique name."); } } @@ -469,8 +477,8 @@ final class HeraldRuleController extends HeraldController { return AphrontFormSelectControl::renderSelectTag( $rule->getMustMatchAll() ? 'all' : 'any', array( - 'all' => 'all of', - 'any' => 'any of', + 'all' => pht('all of'), + 'any' => pht('any of'), ), array( 'name' => 'must_match', diff --git a/src/applications/herald/controller/HeraldRuleEditHistoryController.php b/src/applications/herald/controller/HeraldRuleEditHistoryController.php index 5bfd69c2d1..50887264bf 100644 --- a/src/applications/herald/controller/HeraldRuleEditHistoryController.php +++ b/src/applications/herald/controller/HeraldRuleEditHistoryController.php @@ -35,14 +35,24 @@ final class HeraldRuleEditHistoryController extends HeraldController { $panel->appendChild($list_view); $panel->setNoBackground(); + $crumbs = $this + ->buildApplicationCrumbs($can_create = false) + ->addCrumb( + id(new PhabricatorCrumbView()) + ->setName(pht('Edit History')) + ->setHref($this->getApplicationURI('herald/history'))); + $nav = $this->renderNav(); $nav->selectFilter('history'); $nav->appendChild($panel); + $nav->setCrumbs($crumbs); - return $this->buildStandardPageResponse( + return $this->buildApplicationPage( $nav, array( - 'title' => 'Rule Edit History', + 'title' => pht('Rule Edit History'), + 'device' => true, + 'dust' => true, )); } diff --git a/src/applications/herald/controller/HeraldTestConsoleController.php b/src/applications/herald/controller/HeraldTestConsoleController.php index 7d4836c508..e9865a41c7 100644 --- a/src/applications/herald/controller/HeraldTestConsoleController.php +++ b/src/applications/herald/controller/HeraldTestConsoleController.php @@ -15,8 +15,8 @@ final class HeraldTestConsoleController extends HeraldController { $errors = array(); if ($request->isFormPost()) { if (!$object_name) { - $e_name = 'Required'; - $errors[] = 'An object name is required.'; + $e_name = pht('Required'); + $errors[] = pht('An object name is required.'); } if (!$errors) { @@ -25,30 +25,30 @@ final class HeraldTestConsoleController extends HeraldController { if (preg_match('/^D(\d+)$/', $object_name, $matches)) { $object = id(new DifferentialRevision())->load($matches[1]); if (!$object) { - $e_name = 'Invalid'; - $errors[] = 'No Differential Revision with that ID exists.'; + $e_name = pht('Invalid'); + $errors[] = pht('No Differential Revision with that ID exists.'); } } else if (preg_match('/^r([A-Z]+)(\w+)$/', $object_name, $matches)) { $repo = id(new PhabricatorRepository())->loadOneWhere( 'callsign = %s', $matches[1]); if (!$repo) { - $e_name = 'Invalid'; - $errors[] = 'There is no repository with the callsign '. - $matches[1].'.'; + $e_name = pht('Invalid'); + $errors[] = pht('There is no repository with the callsign: %s.', + $matches[1]); } $commit = id(new PhabricatorRepositoryCommit())->loadOneWhere( 'repositoryID = %d AND commitIdentifier = %s', $repo->getID(), $matches[2]); if (!$commit) { - $e_name = 'Invalid'; - $errors[] = 'There is no commit with that identifier.'; + $e_name = pht('Invalid'); + $errors[] = pht('There is no commit with that identifier.'); } $object = $commit; } else { - $e_name = 'Invalid'; - $errors[] = 'This object name is not recognized.'; + $e_name = pht('Invalid'); + $errors[] = pht('This object name is not recognized.'); } if (!$errors) { @@ -88,19 +88,21 @@ final class HeraldTestConsoleController extends HeraldController { if ($errors) { $error_view = new AphrontErrorView(); - $error_view->setTitle('Form Errors'); + $error_view->setTitle(pht('Form Errors')); $error_view->setErrors($errors); } else { $error_view = null; } + $text = pht('Enter an object to test rules '. + 'for, like a Diffusion commit (e.g., rX123) or a '. + 'Differential revision (e.g., D123). You will be shown the '. + 'results of a dry run on the object.'); + $form = id(new AphrontFormView()) ->setUser($user) ->appendChild(hsprintf( - '

Enter an object to test rules '. - 'for, like a Diffusion commit (e.g., rX123) or a '. - 'Differential revision (e.g., D123). You will be shown the '. - 'results of a dry run on the object.

')) + '

%s

', $text)) ->appendChild( id(new AphrontFormTextControl()) ->setLabel(pht('Object Name')) diff --git a/src/applications/herald/controller/HeraldTranscriptController.php b/src/applications/herald/controller/HeraldTranscriptController.php index 870fab3e68..2fb2f76f24 100644 --- a/src/applications/herald/controller/HeraldTranscriptController.php +++ b/src/applications/herald/controller/HeraldTranscriptController.php @@ -34,11 +34,11 @@ final class HeraldTranscriptController extends HeraldController { if (!$object_xscript) { $notice = id(new AphrontErrorView()) ->setSeverity(AphrontErrorView::SEVERITY_NOTICE) - ->setTitle('Old Transcript') + ->setTitle(pht('Old Transcript')) ->appendChild(phutil_tag( 'p', array(), - 'Details of this transcript have been garbage collected.')); + pht('Details of this transcript have been garbage collected.'))); $nav->appendChild($notice); } else { $filter = $this->getFilterPHIDs(); @@ -53,9 +53,9 @@ final class HeraldTranscriptController extends HeraldController { if ($xscript->getDryRun()) { $notice = new AphrontErrorView(); $notice->setSeverity(AphrontErrorView::SEVERITY_NOTICE); - $notice->setTitle('Dry Run'); - $notice->appendChild( - 'This was a dry run to test Herald rules, no actions were executed.'); + $notice->setTitle(pht('Dry Run')); + $notice->appendChild(pht('This was a dry run to test Herald '. + 'rules, no actions were executed.')); $nav->appendChild($notice); } @@ -82,10 +82,12 @@ final class HeraldTranscriptController extends HeraldController { ->setName($xscript->getID())); $nav->setCrumbs($crumbs); - return $this->buildStandardPageResponse( + return $this->buildApplicationPage( $nav, array( - 'title' => 'Transcript', + 'title' => pht('Transcript'), + 'device' => true, + 'dust' => true, )); } @@ -127,9 +129,9 @@ final class HeraldTranscriptController extends HeraldController { protected function getFilterMap() { return array( - self::FILTER_AFFECTED => 'Rules that Affected Me', - self::FILTER_OWNED => 'Rules I Own', - self::FILTER_ALL => 'All Rules', + self::FILTER_AFFECTED => pht('Rules that Affected Me'), + self::FILTER_OWNED => pht('Rules I Own'), + self::FILTER_ALL => pht('All Rules'), ); } @@ -295,9 +297,13 @@ final class HeraldTranscriptController extends HeraldController { } if ($apply_xscript->getApplied()) { - $outcome = hsprintf('SUCCESS'); + $success = pht('SUCCESS'); + $outcome = + hsprintf('%s', $success); } else { - $outcome = hsprintf('FAILURE'); + $failure = pht('FAILURE'); + $outcome = + hsprintf('%s', $failure); } $rows[] = array( @@ -313,12 +319,12 @@ final class HeraldTranscriptController extends HeraldController { } $table = new AphrontTableView($rows); - $table->setNoDataString('No actions were taken.'); + $table->setNoDataString(pht('No actions were taken.')); $table->setHeaders( array( - 'Action', - 'Target', - 'Details', + pht('Action'), + pht('Target'), + pht('Details'), )); $table->setColumnClasses( array( @@ -370,7 +376,7 @@ final class HeraldTranscriptController extends HeraldController { $cond_markup[] = phutil_tag( 'li', array(), - hsprintf( + pht( '%s Condition: %s %s %s%s', $result, $field_names[$cond->getFieldName()], @@ -380,12 +386,14 @@ final class HeraldTranscriptController extends HeraldController { } if ($rule->getResult()) { + $pass = pht('PASS'); $result = hsprintf( - 'PASS'); + '%s', $pass); $class = 'herald-rule-pass'; } else { + $fail = pht('FAIL'); $result = hsprintf( - 'FAIL'); + '%s', $fail); $class = 'herald-rule-fail'; } @@ -435,13 +443,16 @@ final class HeraldTranscriptController extends HeraldController { phutil_tag('ul', array(), $cond_markup))); } - $panel = new AphrontPanelView(); - $panel->setHeader('Rule Details'); - $panel->appendChild(phutil_tag( - 'ul', - array('class' => 'herald-explain-list'), - $rule_markup)); - + $panel = ''; + if ($rule_markup) { + $panel = new AphrontPanelView(); + $panel->setHeader(pht('Rule Details')); + $panel->setNoBackground(); + $panel->appendChild(phutil_tag( + 'ul', + array('class' => 'herald-explain-list'), + $rule_markup)); + } return $panel; } @@ -457,10 +468,10 @@ final class HeraldTranscriptController extends HeraldController { $handles = $this->loadViewerHandles(array($phid)); $data += array( - 'Object Name' => $object_xscript->getName(), - 'Object Type' => $object_xscript->getType(), - 'Object PHID' => $phid, - 'Object Link' => $handles[$phid]->renderLink(), + pht('Object Name') => $object_xscript->getName(), + pht('Object Type') => $object_xscript->getType(), + pht('Object PHID') => $phid, + pht('Object Link') => $handles[$phid]->renderLink(), ); } @@ -501,7 +512,8 @@ final class HeraldTranscriptController extends HeraldController { )); $panel = new AphrontPanelView(); - $panel->setHeader('Object Transcript'); + $panel->setHeader(pht('Object Transcript')); + $panel->setNoBackground(); $panel->appendChild($table); return $panel; diff --git a/src/applications/herald/controller/HeraldTranscriptListController.php b/src/applications/herald/controller/HeraldTranscriptListController.php index c4d131fb80..5e38f31c45 100644 --- a/src/applications/herald/controller/HeraldTranscriptListController.php +++ b/src/applications/herald/controller/HeraldTranscriptListController.php @@ -64,19 +64,19 @@ final class HeraldTranscriptListController extends HeraldController { 'href' => '/herald/transcript/'.$xscript['id'].'/', 'class' => 'button small grey', ), - 'View Transcript'), + pht('View Transcript')), ); } $table = new AphrontTableView($rows); $table->setHeaders( array( - 'Date', - 'Time', - 'Object', - 'Dry Run', - 'Duration', - 'View', + pht('Date'), + pht('Time'), + pht('Object'), + pht('Dry Run'), + pht('Duration'), + pht('View'), )); $table->setColumnClasses( array( @@ -105,10 +105,12 @@ final class HeraldTranscriptListController extends HeraldController { ->setName(pht('Transcripts'))); $nav->setCrumbs($crumbs); - return $this->buildStandardPageResponse( + return $this->buildApplicationPage( $nav, array( - 'title' => 'Herald Transcripts', + 'title' => pht('Herald Transcripts'), + 'device' => true, + 'dust' => true, )); } diff --git a/src/applications/herald/view/HeraldRuleEditHistoryView.php b/src/applications/herald/view/HeraldRuleEditHistoryView.php index 7bbfd2342f..58fa440411 100644 --- a/src/applications/herald/view/HeraldRuleEditHistoryView.php +++ b/src/applications/herald/view/HeraldRuleEditHistoryView.php @@ -21,7 +21,9 @@ final class HeraldRuleEditHistoryView extends AphrontView { } public function render() { - $rows = array(); + $list = new PhabricatorObjectItemListView(); + $list->setFlush(true); + $list->setCards(true); foreach ($this->edits as $edit) { $name = nonempty($edit->getRuleName(), 'Unknown Rule'); @@ -43,31 +45,20 @@ final class HeraldRuleEditHistoryView extends AphrontView { break; } - $rows[] = array( - $edit->getRuleID(), - $this->handles[$edit->getEditorPHID()]->renderLink(), - $details, - phabricator_datetime($edit->getDateCreated(), $this->user), - ); + $editor = $this->handles[$edit->getEditorPHID()]->renderLink(); + $date = phabricator_datetime($edit->getDateCreated(), $this->user); + + $item = id(new PhabricatorObjectItemView()) + ->setObjectName(pht('Rule %d', $edit->getRuleID())) + ->setSubHead($details) + ->addIcon('none', $date) + ->addByLine(pht('Editor: %s', $editor)); + + $list->addItem($item); } - $table = new AphrontTableView($rows); - $table->setNoDataString("No edits for rule."); - $table->setHeaders( - array( - 'Rule ID', - 'Editor', - 'Details', - 'Edit Date', - )); - $table->setColumnClasses( - array( - '', - '', - 'wide', - '', - )); + $list->setNoDataString(pht('No edits for rule.')); - return $table->render(); + return $list; } } diff --git a/src/applications/herald/view/HeraldRuleListView.php b/src/applications/herald/view/HeraldRuleListView.php index d95765ecd7..4109af51bf 100644 --- a/src/applications/herald/view/HeraldRuleListView.php +++ b/src/applications/herald/view/HeraldRuleListView.php @@ -34,76 +34,50 @@ final class HeraldRuleListView extends AphrontView { $type_map = HeraldRuleTypeConfig::getRuleTypeMap(); - $rows = array(); - + $list = new PhabricatorObjectItemListView(); + $list->setFlush(true); + $list->setCards(true); foreach ($this->rules as $rule) { if ($rule->getRuleType() == HeraldRuleTypeConfig::RULE_TYPE_GLOBAL) { - $author = null; + $author = pht('Global Rule'); } else { $author = $this->handles[$rule->getAuthorPHID()]->renderLink(); + $author = pht('Editor: %s', $author); } - $name = phutil_tag( - 'a', - array( - 'href' => '/herald/rule/'.$rule->getID().'/', - ), - $rule->getName()); - $edit_log = phutil_tag( 'a', array( 'href' => '/herald/history/'.$rule->getID().'/', ), - 'View Edit Log'); + pht('View Edit Log')); $delete = javelin_tag( 'a', array( 'href' => '/herald/delete/'.$rule->getID().'/', 'sigil' => 'workflow', - 'class' => 'button small grey', ), - 'Delete'); + pht('Delete')); - $rows[] = array( - $type_map[$rule->getRuleType()], - $author, - $name, - $edit_log, - $delete, - ); + $item = id(new PhabricatorObjectItemView()) + ->setObjectName($type_map[$rule->getRuleType()]) + ->setHeader($rule->getName()) + ->setHref('/herald/rule/'.$rule->getID().'/') + ->addAttribute($edit_log) + ->addIcon('none', $author) + ->addAction( + id(new PhabricatorMenuItemView()) + ->setHref('/herald/delete/'.$rule->getID().'/') + ->setIcon('delete') + ->setWorkflow(true)); + + $list->addItem($item); } - $table = new AphrontTableView($rows); - $table->setNoDataString("No matching rules."); + $list->setNoDataString(pht("No matching rules.")); - $table->setHeaders( - array( - 'Rule Type', - 'Author', - 'Rule Name', - 'Edit Log', - '', - )); - $table->setColumnClasses( - array( - '', - '', - 'wide pri', - '', - 'action' - )); - $table->setColumnVisibility( - array( - $this->showRuleType, - $this->showAuthor, - true, - true, - true, - )); - - return $table->render(); + return $list; } }