diff --git a/src/applications/base/PhabricatorApplication.php b/src/applications/base/PhabricatorApplication.php --- a/src/applications/base/PhabricatorApplication.php +++ b/src/applications/base/PhabricatorApplication.php @@ -61,6 +61,21 @@ return pht('%s Application', $this->getName()); } + /** + * Extensions are allowed to register multi-character monograms. + * The name "Monogram" is actually a bit of a misnomer, + * but we're keeping it due to the history. + * + * @return array + */ + public function getMonograms() { + return array(); + } + + public function isDeprecated() { + return false; + } + final public function isInstalled() { if (!$this->canUninstall()) { return true; diff --git a/src/applications/calendar/application/PhabricatorCalendarApplication.php b/src/applications/calendar/application/PhabricatorCalendarApplication.php --- a/src/applications/calendar/application/PhabricatorCalendarApplication.php +++ b/src/applications/calendar/application/PhabricatorCalendarApplication.php @@ -28,6 +28,10 @@ return "\xE2\x8C\xA8"; } + public function getMonograms() { + return array('E'); + } + public function getApplicationGroup() { return self::GROUP_UTILITIES; } diff --git a/src/applications/chatlog/application/PhabricatorChatLogApplication.php b/src/applications/chatlog/application/PhabricatorChatLogApplication.php --- a/src/applications/chatlog/application/PhabricatorChatLogApplication.php +++ b/src/applications/chatlog/application/PhabricatorChatLogApplication.php @@ -11,7 +11,7 @@ } public function getShortDescription() { - return pht('(Deprecated)'); + return pht('IRC Logs'); } public function getIcon() { @@ -22,6 +22,10 @@ return true; } + public function isDeprecated() { + return true; + } + public function getTitleGlyph() { return "\xE0\xBC\x84"; } @@ -30,7 +34,7 @@ return self::GROUP_UTILITIES; } - public function getRoutes() { + public function getRoutes() { return array( '/chatlog/' => array( '' => 'PhabricatorChatLogChannelListController', diff --git a/src/applications/conpherence/application/PhabricatorConpherenceApplication.php b/src/applications/conpherence/application/PhabricatorConpherenceApplication.php --- a/src/applications/conpherence/application/PhabricatorConpherenceApplication.php +++ b/src/applications/conpherence/application/PhabricatorConpherenceApplication.php @@ -28,6 +28,10 @@ ); } + public function getMonograms() { + return array('Z'); + } + public function getRoutes() { return array( '/Z(?P[1-9]\d*)' diff --git a/src/applications/countdown/application/PhabricatorCountdownApplication.php b/src/applications/countdown/application/PhabricatorCountdownApplication.php --- a/src/applications/countdown/application/PhabricatorCountdownApplication.php +++ b/src/applications/countdown/application/PhabricatorCountdownApplication.php @@ -36,6 +36,10 @@ ); } + public function getMonograms() { + return array('C'); + } + public function getRoutes() { return array( '/C(?P[1-9]\d*)' => 'PhabricatorCountdownViewController', diff --git a/src/applications/dashboard/application/PhabricatorDashboardApplication.php b/src/applications/dashboard/application/PhabricatorDashboardApplication.php --- a/src/applications/dashboard/application/PhabricatorDashboardApplication.php +++ b/src/applications/dashboard/application/PhabricatorDashboardApplication.php @@ -30,6 +30,10 @@ return 0.160; } + public function getMonograms() { + return array('W'); + } + public function getRoutes() { $menu_rules = $this->getProfileMenuRouting( 'PhabricatorDashboardPortalViewController'); diff --git a/src/applications/differential/application/PhabricatorDifferentialApplication.php b/src/applications/differential/application/PhabricatorDifferentialApplication.php --- a/src/applications/differential/application/PhabricatorDifferentialApplication.php +++ b/src/applications/differential/application/PhabricatorDifferentialApplication.php @@ -42,6 +42,10 @@ 'engineers to review, discuss and approve changes to software.'); } + public function getMonograms() { + return array('D'); + } + public function getRoutes() { return array( '/D(?P[1-9]\d*)' => array( diff --git a/src/applications/diffusion/application/PhabricatorDiffusionApplication.php b/src/applications/diffusion/application/PhabricatorDiffusionApplication.php --- a/src/applications/diffusion/application/PhabricatorDiffusionApplication.php +++ b/src/applications/diffusion/application/PhabricatorDiffusionApplication.php @@ -44,6 +44,11 @@ ); } + public function getMonograms() { + // This is a special case, as r and R mean different things. + return array('r', 'R'); + } + public function getRoutes() { $repository_routes = array( '/' => array( diff --git a/src/applications/files/application/PhabricatorFilesApplication.php b/src/applications/files/application/PhabricatorFilesApplication.php --- a/src/applications/files/application/PhabricatorFilesApplication.php +++ b/src/applications/files/application/PhabricatorFilesApplication.php @@ -67,6 +67,10 @@ ); } + public function getMonograms() { + return array('F'); + } + public function getRoutes() { return array( '/F(?P[1-9]\d*)(?:\$(?P\d+(?:-\d+)?))?' diff --git a/src/applications/fund/application/PhabricatorFundApplication.php b/src/applications/fund/application/PhabricatorFundApplication.php --- a/src/applications/fund/application/PhabricatorFundApplication.php +++ b/src/applications/fund/application/PhabricatorFundApplication.php @@ -36,6 +36,10 @@ ); } + public function getMonograms() { + return array('I'); + } + public function getRoutes() { return array( '/I(?P[1-9]\d*)' => 'FundInitiativeViewController', diff --git a/src/applications/harbormaster/application/PhabricatorHarbormasterApplication.php b/src/applications/harbormaster/application/PhabricatorHarbormasterApplication.php --- a/src/applications/harbormaster/application/PhabricatorHarbormasterApplication.php +++ b/src/applications/harbormaster/application/PhabricatorHarbormasterApplication.php @@ -51,6 +51,10 @@ ); } + public function getMonograms() { + return array('B'); + } + public function getRoutes() { return array( '/B(?P[1-9]\d*)' => 'HarbormasterBuildableViewController', diff --git a/src/applications/herald/application/PhabricatorHeraldApplication.php b/src/applications/herald/application/PhabricatorHeraldApplication.php --- a/src/applications/herald/application/PhabricatorHeraldApplication.php +++ b/src/applications/herald/application/PhabricatorHeraldApplication.php @@ -49,6 +49,10 @@ ); } + public function getMonograms() { + return array('H'); + } + public function getRoutes() { return array( '/H(?P[1-9]\d*)' => 'HeraldRuleViewController', diff --git a/src/applications/legalpad/application/PhabricatorLegalpadApplication.php b/src/applications/legalpad/application/PhabricatorLegalpadApplication.php --- a/src/applications/legalpad/application/PhabricatorLegalpadApplication.php +++ b/src/applications/legalpad/application/PhabricatorLegalpadApplication.php @@ -48,6 +48,10 @@ 'open source projects keep track of Contributor License Agreements.'); } + public function getMonograms() { + return array('L'); + } + public function getRoutes() { return array( '/L(?P\d+)' => 'LegalpadDocumentSignController', diff --git a/src/applications/maniphest/application/PhabricatorManiphestApplication.php b/src/applications/maniphest/application/PhabricatorManiphestApplication.php --- a/src/applications/maniphest/application/PhabricatorManiphestApplication.php +++ b/src/applications/maniphest/application/PhabricatorManiphestApplication.php @@ -42,6 +42,10 @@ ); } + public function getMonograms() { + return array('T'); + } + public function getRoutes() { return array( '/T(?P[1-9]\d*)' => 'ManiphestTaskDetailController', diff --git a/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php b/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php --- a/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php +++ b/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php @@ -38,6 +38,30 @@ $header->setStatus('fa-ban', 'dark', pht('Uninstalled')); } + if (!$selected->isFirstParty()) { + $header->addTag(id(new PHUITagView()) + ->setName('Extension') + ->setIcon('fa-plug') + ->setColor(PHUITagView::COLOR_INDIGO) + ->setType(PHUITagView::TYPE_SHADE)); + } + + if ($selected->isPrototype()) { + $header->addTag(id(new PHUITagView()) + ->setName('Prototype') + ->setIcon('fa-exclamation-circle') + ->setColor(PHUITagView::COLOR_ORANGE) + ->setType(PHUITagView::TYPE_SHADE)); + } + + if ($selected->isDeprecated()) { + $header->addTag(id(new PHUITagView()) + ->setName('Deprecated') + ->setIcon('fa-exclamation-triangle') + ->setColor(PHUITagView::COLOR_RED) + ->setType(PHUITagView::TYPE_SHADE)); + } + $timeline = $this->buildTransactionTimeline( $selected, new PhabricatorApplicationApplicationTransactionQuery()); @@ -95,6 +119,27 @@ phutil_tag('em', array(), $application->getFlavorText())); } + $phids = PhabricatorPHIDType::getAllTypesForApplication( + $viewer, get_class($application)); + + $user_friendly_phids = array(); + foreach ($phids as $phid => $type) { + $user_friendly_phids[] = "PHID-{$phid} ({$type->getTypeName()})"; + } + + if (count($user_friendly_phids) > 0) { + $properties->addProperty( + 'PHIDs', + phutil_implode_html(', ', $user_friendly_phids)); + } + + $monograms = $application->getMonograms(); + if ($monograms) { + $properties->addProperty( + 'Monograms', + phutil_implode_html(', ', $monograms)); + } + if ($application->isPrototype()) { $proto_href = PhabricatorEnv::getDoclink( 'User Guide: Prototype Applications'); diff --git a/src/applications/meta/query/PhabricatorAppSearchEngine.php b/src/applications/meta/query/PhabricatorAppSearchEngine.php --- a/src/applications/meta/query/PhabricatorAppSearchEngine.php +++ b/src/applications/meta/query/PhabricatorAppSearchEngine.php @@ -231,13 +231,13 @@ ->setSideColumn($configure); if (!$application->isFirstParty()) { - $tag = id(new PHUITagView()) + $extension_tag = id(new PHUITagView()) ->setName(pht('Extension')) - ->setIcon('fa-puzzle-piece') - ->setColor(PHUITagView::COLOR_BLUE) + ->setIcon('fa-plug') + ->setColor(PHUITagView::COLOR_INDIGO) ->setType(PHUITagView::TYPE_SHADE) ->setSlimShady(true); - $item->addAttribute($tag); + $item->addAttribute($extension_tag); } if ($application->isPrototype()) { @@ -250,6 +250,16 @@ $item->addAttribute($prototype_tag); } + if ($application->isDeprecated()) { + $deprecated_tag = id(new PHUITagView()) + ->setName(pht('Deprecated')) + ->setIcon('fa-exclamation-triangle') + ->setColor(PHUITagView::COLOR_RED) + ->setType(PHUITagView::TYPE_SHADE) + ->setSlimShady(true); + $item->addAttribute($deprecated_tag); + } + $item->addAttribute($description); if ($application->getBaseURI() && $application->isInstalled()) { diff --git a/src/applications/owners/application/PhabricatorOwnersApplication.php b/src/applications/owners/application/PhabricatorOwnersApplication.php --- a/src/applications/owners/application/PhabricatorOwnersApplication.php +++ b/src/applications/owners/application/PhabricatorOwnersApplication.php @@ -45,6 +45,10 @@ ); } + public function getMonograms() { + return array('O'); + } + public function getRoutes() { return array( '/owners/' => array( diff --git a/src/applications/passphrase/application/PhabricatorPassphraseApplication.php b/src/applications/passphrase/application/PhabricatorPassphraseApplication.php --- a/src/applications/passphrase/application/PhabricatorPassphraseApplication.php +++ b/src/applications/passphrase/application/PhabricatorPassphraseApplication.php @@ -34,6 +34,10 @@ return false; } + public function getMonograms() { + return array('K'); + } + public function getRoutes() { return array( '/K(?P\d+)' => 'PassphraseCredentialViewController', diff --git a/src/applications/paste/application/PhabricatorPasteApplication.php b/src/applications/paste/application/PhabricatorPasteApplication.php --- a/src/applications/paste/application/PhabricatorPasteApplication.php +++ b/src/applications/paste/application/PhabricatorPasteApplication.php @@ -32,6 +32,10 @@ ); } + public function getMonograms() { + return array('P'); + } + public function getRoutes() { return array( '/P(?P[1-9]\d*)(?:\$(?P\d+(?:-\d+)?))?' diff --git a/src/applications/phame/application/PhabricatorPhameApplication.php b/src/applications/phame/application/PhabricatorPhameApplication.php --- a/src/applications/phame/application/PhabricatorPhameApplication.php +++ b/src/applications/phame/application/PhabricatorPhameApplication.php @@ -31,6 +31,10 @@ ); } + public function getMonograms() { + return array('J'); + } + public function getRoutes() { return array( '/J(?P[1-9]\d*)' => 'PhamePostViewController', diff --git a/src/applications/phid/type/PhabricatorPHIDType.php b/src/applications/phid/type/PhabricatorPHIDType.php --- a/src/applications/phid/type/PhabricatorPHIDType.php +++ b/src/applications/phid/type/PhabricatorPHIDType.php @@ -205,4 +205,29 @@ return $installed_types; } + + /** + * Get all PHID types of applications installed for a given viewer. + * + * @param PhabricatorUser Viewing user. + * @return dict Map of constants to installed + * types. + */ + public static function getAllTypesForApplication( + PhabricatorUser $viewer, string $application) { + $all_types = self::getAllTypes(); + + $installed_types = array(); + + foreach ($all_types as $key => $type) { + if ($type->getPHIDTypeApplicationClass() != $application) { + continue; + } + + $installed_types[$key] = $type; + } + + return $installed_types; + } + } diff --git a/src/applications/pholio/application/PhabricatorPholioApplication.php b/src/applications/pholio/application/PhabricatorPholioApplication.php --- a/src/applications/pholio/application/PhabricatorPholioApplication.php +++ b/src/applications/pholio/application/PhabricatorPholioApplication.php @@ -32,6 +32,10 @@ ); } + public function getMonograms() { + return array('M'); + } + public function getRoutes() { return array( '/M(?P[1-9]\d*)(?:/(?P\d+)/)?' => 'PholioMockViewController', diff --git a/src/applications/phurl/application/PhabricatorPhurlApplication.php b/src/applications/phurl/application/PhabricatorPhurlApplication.php --- a/src/applications/phurl/application/PhabricatorPhurlApplication.php +++ b/src/applications/phurl/application/PhabricatorPhurlApplication.php @@ -37,6 +37,10 @@ ); } + public function getMonograms() { + return array('U'); + } + public function getRoutes() { return array( '/U(?P[1-9]\d*)/?' => 'PhabricatorPhurlURLViewController', diff --git a/src/applications/ponder/application/PhabricatorPonderApplication.php b/src/applications/ponder/application/PhabricatorPonderApplication.php --- a/src/applications/ponder/application/PhabricatorPonderApplication.php +++ b/src/applications/ponder/application/PhabricatorPonderApplication.php @@ -47,6 +47,10 @@ pht('Learn More'))); } + public function getMonograms() { + return array('Q'); + } + public function getRoutes() { return array( '/Q(?P[1-9]\d*)' diff --git a/src/applications/slowvote/application/PhabricatorSlowvoteApplication.php b/src/applications/slowvote/application/PhabricatorSlowvoteApplication.php --- a/src/applications/slowvote/application/PhabricatorSlowvoteApplication.php +++ b/src/applications/slowvote/application/PhabricatorSlowvoteApplication.php @@ -45,6 +45,10 @@ ); } + public function getMonograms() { + return array('V'); + } + public function getRoutes() { return array( '/V(?P[1-9]\d*)' => 'PhabricatorSlowvotePollController', diff --git a/src/applications/spaces/application/PhabricatorSpacesApplication.php b/src/applications/spaces/application/PhabricatorSpacesApplication.php --- a/src/applications/spaces/application/PhabricatorSpacesApplication.php +++ b/src/applications/spaces/application/PhabricatorSpacesApplication.php @@ -49,6 +49,10 @@ ); } + public function getMonograms() { + return array('S'); + } + public function getRoutes() { return array( '/S(?P[1-9]\d*)' => 'PhabricatorSpacesViewController',