From 1b49165ddd16e7a5c6542748b06ea89729fb07a1 Mon Sep 17 00:00:00 2001 From: Matthew Bowker Date: Tue, 21 Nov 2023 11:17:19 -0700 Subject: [PATCH] Show more in Application Detail and List view Summary: Update the Application Detail view and List View to show a unified set of Badges (Deprecated, etc.), show PHIDs and Monograms on the Application Detail view, allow Applications to register Monograms. Example of the page /applications/view/PhabricatorDiffusionApplication/: {F393393} T15568 Test Plan: 1. Visit /applications/ and see Deprecated badges etc. 2. Visit various Configure buttons from that list and see Monograms, Badges, PHIDs etc. 3. Enjoy screenshots in the comments of this Diff Reviewers: O1 Blessed Committers, valerio.bozzolan, avivey, speck Reviewed By: O1 Blessed Committers, valerio.bozzolan, avivey, speck Subscribers: avivey, speck, tobiaswiese, valerio.bozzolan, Cigaryno Differential Revision: https://we.phorge.it/D25362 --- .../base/PhabricatorApplication.php | 15 +++++++ .../PhabricatorCalendarApplication.php | 4 ++ .../PhabricatorChatLogApplication.php | 8 +++- .../PhabricatorConpherenceApplication.php | 4 ++ .../PhabricatorCountdownApplication.php | 4 ++ .../PhabricatorDashboardApplication.php | 4 ++ .../PhabricatorDifferentialApplication.php | 4 ++ .../PhabricatorDiffusionApplication.php | 5 +++ .../PhabricatorFilesApplication.php | 4 ++ .../PhabricatorFundApplication.php | 4 ++ .../PhabricatorHarbormasterApplication.php | 4 ++ .../PhabricatorHeraldApplication.php | 4 ++ .../PhabricatorLegalpadApplication.php | 4 ++ .../PhabricatorManiphestApplication.php | 4 ++ ...ricatorApplicationDetailViewController.php | 45 +++++++++++++++++++ .../meta/query/PhabricatorAppSearchEngine.php | 18 ++++++-- .../PhabricatorOwnersApplication.php | 4 ++ .../PhabricatorPassphraseApplication.php | 4 ++ .../PhabricatorPasteApplication.php | 4 ++ .../PhabricatorPhameApplication.php | 4 ++ .../phid/type/PhabricatorPHIDType.php | 24 ++++++++++ .../PhabricatorPholioApplication.php | 4 ++ .../PhabricatorPhurlApplication.php | 4 ++ .../PhabricatorPonderApplication.php | 4 ++ .../PhabricatorSlowvoteApplication.php | 4 ++ .../PhabricatorSpacesApplication.php | 4 ++ 26 files changed, 189 insertions(+), 6 deletions(-) diff --git a/src/applications/base/PhabricatorApplication.php b/src/applications/base/PhabricatorApplication.php index 9e1ea7d5ba..67294db263 100644 --- a/src/applications/base/PhabricatorApplication.php +++ b/src/applications/base/PhabricatorApplication.php @@ -61,6 +61,21 @@ abstract class PhabricatorApplication 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 index fa534280a0..c9ff3ac9d3 100644 --- a/src/applications/calendar/application/PhabricatorCalendarApplication.php +++ b/src/applications/calendar/application/PhabricatorCalendarApplication.php @@ -28,6 +28,10 @@ final class PhabricatorCalendarApplication extends PhabricatorApplication { 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 index 912ddd9b6b..ab5eb1960f 100644 --- a/src/applications/chatlog/application/PhabricatorChatLogApplication.php +++ b/src/applications/chatlog/application/PhabricatorChatLogApplication.php @@ -11,7 +11,7 @@ final class PhabricatorChatLogApplication extends PhabricatorApplication { } public function getShortDescription() { - return pht('(Deprecated)'); + return pht('IRC Logs'); } public function getIcon() { @@ -22,6 +22,10 @@ final class PhabricatorChatLogApplication extends PhabricatorApplication { return true; } + public function isDeprecated() { + return true; + } + public function getTitleGlyph() { return "\xE0\xBC\x84"; } @@ -30,7 +34,7 @@ final class PhabricatorChatLogApplication extends PhabricatorApplication { 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 index a0c21bd33a..f3118be9bf 100644 --- a/src/applications/conpherence/application/PhabricatorConpherenceApplication.php +++ b/src/applications/conpherence/application/PhabricatorConpherenceApplication.php @@ -28,6 +28,10 @@ final class PhabricatorConpherenceApplication extends PhabricatorApplication { ); } + 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 index e205ba64c3..5f06e6ef9f 100644 --- a/src/applications/countdown/application/PhabricatorCountdownApplication.php +++ b/src/applications/countdown/application/PhabricatorCountdownApplication.php @@ -36,6 +36,10 @@ final class PhabricatorCountdownApplication extends PhabricatorApplication { ); } + 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 index 3cdb932514..aeb2f43195 100644 --- a/src/applications/dashboard/application/PhabricatorDashboardApplication.php +++ b/src/applications/dashboard/application/PhabricatorDashboardApplication.php @@ -30,6 +30,10 @@ final class PhabricatorDashboardApplication extends PhabricatorApplication { 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 index 5980f738b0..16b3193dac 100644 --- a/src/applications/differential/application/PhabricatorDifferentialApplication.php +++ b/src/applications/differential/application/PhabricatorDifferentialApplication.php @@ -42,6 +42,10 @@ final class PhabricatorDifferentialApplication '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 index ccd311fa7e..a2b9f81aee 100644 --- a/src/applications/diffusion/application/PhabricatorDiffusionApplication.php +++ b/src/applications/diffusion/application/PhabricatorDiffusionApplication.php @@ -44,6 +44,11 @@ final class PhabricatorDiffusionApplication extends PhabricatorApplication { ); } + 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 index e246d4c90c..4014a6ce62 100644 --- a/src/applications/files/application/PhabricatorFilesApplication.php +++ b/src/applications/files/application/PhabricatorFilesApplication.php @@ -67,6 +67,10 @@ final class PhabricatorFilesApplication extends PhabricatorApplication { ); } + 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 index 58ce4f8922..5e2d33c1a4 100644 --- a/src/applications/fund/application/PhabricatorFundApplication.php +++ b/src/applications/fund/application/PhabricatorFundApplication.php @@ -36,6 +36,10 @@ final class PhabricatorFundApplication extends PhabricatorApplication { ); } + 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 index 6c499bf63a..7de2a658c2 100644 --- a/src/applications/harbormaster/application/PhabricatorHarbormasterApplication.php +++ b/src/applications/harbormaster/application/PhabricatorHarbormasterApplication.php @@ -51,6 +51,10 @@ final class PhabricatorHarbormasterApplication extends PhabricatorApplication { ); } + 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 index 0de1c02737..7808820818 100644 --- a/src/applications/herald/application/PhabricatorHeraldApplication.php +++ b/src/applications/herald/application/PhabricatorHeraldApplication.php @@ -49,6 +49,10 @@ final class PhabricatorHeraldApplication extends PhabricatorApplication { ); } + 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 index a3eaff5792..47a8f4ebef 100644 --- a/src/applications/legalpad/application/PhabricatorLegalpadApplication.php +++ b/src/applications/legalpad/application/PhabricatorLegalpadApplication.php @@ -48,6 +48,10 @@ final class PhabricatorLegalpadApplication extends PhabricatorApplication { '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 index 8ed20416bb..9296060d81 100644 --- a/src/applications/maniphest/application/PhabricatorManiphestApplication.php +++ b/src/applications/maniphest/application/PhabricatorManiphestApplication.php @@ -42,6 +42,10 @@ final class PhabricatorManiphestApplication extends PhabricatorApplication { ); } + 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 index 8cceeb7396..1bf6734db3 100644 --- a/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php +++ b/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php @@ -38,6 +38,30 @@ final class PhabricatorApplicationDetailViewController $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 @@ final class PhabricatorApplicationDetailViewController phutil_tag('em', array(), $application->getFlavorText())); } + $phids = PhabricatorPHIDType::getAllTypesForApplication( + get_class($application)); + + $user_friendly_phids = array(); + foreach ($phids as $phid => $type) { + $user_friendly_phids[] = "PHID-{$phid} ({$type->getTypeName()})"; + } + + if ($user_friendly_phids) { + $properties->addProperty( + 'PHIDs', + phutil_implode_html(phutil_tag('br'), $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 index e68570fe1c..08283afc2e 100644 --- a/src/applications/meta/query/PhabricatorAppSearchEngine.php +++ b/src/applications/meta/query/PhabricatorAppSearchEngine.php @@ -231,13 +231,13 @@ final class PhabricatorAppSearchEngine ->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 @@ final class PhabricatorAppSearchEngine $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 index 3ef5f974d9..34bbc4b7b5 100644 --- a/src/applications/owners/application/PhabricatorOwnersApplication.php +++ b/src/applications/owners/application/PhabricatorOwnersApplication.php @@ -45,6 +45,10 @@ final class PhabricatorOwnersApplication extends PhabricatorApplication { ); } + 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 index 2ab4f1e33d..ae79e5c8b5 100644 --- a/src/applications/passphrase/application/PhabricatorPassphraseApplication.php +++ b/src/applications/passphrase/application/PhabricatorPassphraseApplication.php @@ -34,6 +34,10 @@ final class PhabricatorPassphraseApplication extends PhabricatorApplication { 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 index 26e4b1740e..f6b6f7cf65 100644 --- a/src/applications/paste/application/PhabricatorPasteApplication.php +++ b/src/applications/paste/application/PhabricatorPasteApplication.php @@ -32,6 +32,10 @@ final class PhabricatorPasteApplication extends PhabricatorApplication { ); } + 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 index cd2eb4b487..b030673d1f 100644 --- a/src/applications/phame/application/PhabricatorPhameApplication.php +++ b/src/applications/phame/application/PhabricatorPhameApplication.php @@ -31,6 +31,10 @@ final class PhabricatorPhameApplication extends PhabricatorApplication { ); } + 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 index 2f82dcf169..f15df7f886 100644 --- a/src/applications/phid/type/PhabricatorPHIDType.php +++ b/src/applications/phid/type/PhabricatorPHIDType.php @@ -205,4 +205,28 @@ abstract class PhabricatorPHIDType extends Phobject { 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( + string $application) { + $all_types = self::getAllTypes(); + + $application_types = array(); + + foreach ($all_types as $key => $type) { + if ($type->getPHIDTypeApplicationClass() != $application) { + continue; + } + + $application_types[$key] = $type; + } + + return $application_types; + } } diff --git a/src/applications/pholio/application/PhabricatorPholioApplication.php b/src/applications/pholio/application/PhabricatorPholioApplication.php index 4d80dd12ae..5ac650cc20 100644 --- a/src/applications/pholio/application/PhabricatorPholioApplication.php +++ b/src/applications/pholio/application/PhabricatorPholioApplication.php @@ -32,6 +32,10 @@ final class PhabricatorPholioApplication extends PhabricatorApplication { ); } + 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 index 14ffda77f1..56290ef5e1 100644 --- a/src/applications/phurl/application/PhabricatorPhurlApplication.php +++ b/src/applications/phurl/application/PhabricatorPhurlApplication.php @@ -37,6 +37,10 @@ final class PhabricatorPhurlApplication extends PhabricatorApplication { ); } + 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 index 56973447f9..e6f4ef8867 100644 --- a/src/applications/ponder/application/PhabricatorPonderApplication.php +++ b/src/applications/ponder/application/PhabricatorPonderApplication.php @@ -47,6 +47,10 @@ final class PhabricatorPonderApplication extends PhabricatorApplication { 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 index 1e4bd78419..8fa4edc6f6 100644 --- a/src/applications/slowvote/application/PhabricatorSlowvoteApplication.php +++ b/src/applications/slowvote/application/PhabricatorSlowvoteApplication.php @@ -45,6 +45,10 @@ final class PhabricatorSlowvoteApplication extends PhabricatorApplication { ); } + 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 index d542551ae4..f40538b69b 100644 --- a/src/applications/spaces/application/PhabricatorSpacesApplication.php +++ b/src/applications/spaces/application/PhabricatorSpacesApplication.php @@ -49,6 +49,10 @@ final class PhabricatorSpacesApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('S'); + } + public function getRoutes() { return array( '/S(?P[1-9]\d*)' => 'PhabricatorSpacesViewController',