From 194dc40672e206473d7048b09eedcd4b378991c4 Mon Sep 17 00:00:00 2001 From: epriestley Date: Thu, 2 Aug 2012 14:07:21 -0700 Subject: [PATCH] Add a meta-application Summary: - Adds a new "Applications" application. - Builds an application list via application config instead of via hard-coding, so we can move toward better concepts of installing/uninstalling applications, etc. - Applications indicate that they need attention with notice counts and brief status messages rathern than 50 giant tables of all sorts of app data. I want to try replacing the home screen with this screen, pretty much. Not sure if this is totally crazy or not. What does everyone else think? Test Plan: Will add screenshots. Reviewers: btrahan, chad, vrana, alanh Reviewed By: vrana CC: aran, davidreuss, champo Maniphest Tasks: T1569 Differential Revision: https://secure.phabricator.com/D3129 --- src/__celerity_resource_map__.php | 86 ++++++++++++ src/__phutil_library_map__.php | 18 +++ .../PhabricatorApplicationAudit.php | 73 ++++++++++ .../base/PhabricatorApplication.php | 12 ++ .../PhabricatorApplicationDifferential.php | 46 +++++- .../PhabricatorApplicationDiffusion.php | 34 +++++ .../PhabricatorApplicationFact.php | 12 ++ .../PhabricatorApplicationFlags.php | 53 +++++++ .../PhabricatorApplicationManiphest.php | 49 +++++++ .../PhabricatorApplicationApplications.php | 42 ++++++ .../PhabricatorApplicationsController.php | 35 +++++ .../PhabricatorApplicationsListController.php | 63 +++++++++ .../view/PhabricatorApplicationLaunchView.php | 88 ++++++++++++ .../view/PhabricatorApplicationStatusView.php | 64 +++++++++ .../PhabricatorApplicationPhriction.php | 35 +++++ .../PhabricatorBaseEnglishTranslation.php | 35 +++++ .../phabricator-application-launch-view.css | 131 ++++++++++++++++++ webroot/rsrc/image/app/app_audit.png | Bin 0 -> 545 bytes webroot/rsrc/image/app/app_differential.png | Bin 0 -> 526 bytes webroot/rsrc/image/app/app_diffusion.png | Bin 0 -> 397 bytes webroot/rsrc/image/app/app_fact.png | Bin 0 -> 536 bytes webroot/rsrc/image/app/app_flags.png | Bin 0 -> 309 bytes webroot/rsrc/image/app/app_maniphest.png | Bin 0 -> 520 bytes webroot/rsrc/image/app/app_phriction.png | Bin 0 -> 257 bytes webroot/rsrc/image/appstatus_empty.png | Bin 0 -> 774 bytes webroot/rsrc/image/appstatus_info.png | Bin 0 -> 690 bytes webroot/rsrc/image/appstatus_needs.png | Bin 0 -> 719 bytes webroot/rsrc/image/appstatus_okay.png | Bin 0 -> 476 bytes 28 files changed, 871 insertions(+), 5 deletions(-) create mode 100644 src/applications/audit/application/PhabricatorApplicationAudit.php create mode 100644 src/applications/diffusion/application/PhabricatorApplicationDiffusion.php create mode 100644 src/applications/flag/application/PhabricatorApplicationFlags.php create mode 100644 src/applications/meta/application/PhabricatorApplicationApplications.php create mode 100644 src/applications/meta/controller/PhabricatorApplicationsController.php create mode 100644 src/applications/meta/controller/PhabricatorApplicationsListController.php create mode 100644 src/applications/meta/view/PhabricatorApplicationLaunchView.php create mode 100644 src/applications/meta/view/PhabricatorApplicationStatusView.php create mode 100644 src/applications/phriction/application/PhabricatorApplicationPhriction.php create mode 100644 webroot/rsrc/css/application/base/phabricator-application-launch-view.css create mode 100755 webroot/rsrc/image/app/app_audit.png create mode 100755 webroot/rsrc/image/app/app_differential.png create mode 100755 webroot/rsrc/image/app/app_diffusion.png create mode 100755 webroot/rsrc/image/app/app_fact.png create mode 100755 webroot/rsrc/image/app/app_flags.png create mode 100755 webroot/rsrc/image/app/app_maniphest.png create mode 100755 webroot/rsrc/image/app/app_phriction.png create mode 100644 webroot/rsrc/image/appstatus_empty.png create mode 100644 webroot/rsrc/image/appstatus_info.png create mode 100644 webroot/rsrc/image/appstatus_needs.png create mode 100755 webroot/rsrc/image/appstatus_okay.png diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index 20f86ef121..f8a68e53c2 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -7,6 +7,55 @@ */ celerity_register_resource_map(array( + '/rsrc/image/app/app_audit.png' => + array( + 'hash' => '5f5b4a7c48fe921532bef4c986328bdc', + 'uri' => '/res/5f5b4a7c/rsrc/image/app/app_audit.png', + 'disk' => '/rsrc/image/app/app_audit.png', + 'type' => 'png', + ), + '/rsrc/image/app/app_differential.png' => + array( + 'hash' => 'b2e42893b64791f8382f7f5a0350b44d', + 'uri' => '/res/b2e42893/rsrc/image/app/app_differential.png', + 'disk' => '/rsrc/image/app/app_differential.png', + 'type' => 'png', + ), + '/rsrc/image/app/app_diffusion.png' => + array( + 'hash' => 'e9e4b1c380e19a2908730ad397ae5eca', + 'uri' => '/res/e9e4b1c3/rsrc/image/app/app_diffusion.png', + 'disk' => '/rsrc/image/app/app_diffusion.png', + 'type' => 'png', + ), + '/rsrc/image/app/app_fact.png' => + array( + 'hash' => '8b4da94b07e2aad9f741beca9519df98', + 'uri' => '/res/8b4da94b/rsrc/image/app/app_fact.png', + 'disk' => '/rsrc/image/app/app_fact.png', + 'type' => 'png', + ), + '/rsrc/image/app/app_flags.png' => + array( + 'hash' => 'e75e1047a6bc2ff428161d2130526367', + 'uri' => '/res/e75e1047/rsrc/image/app/app_flags.png', + 'disk' => '/rsrc/image/app/app_flags.png', + 'type' => 'png', + ), + '/rsrc/image/app/app_maniphest.png' => + array( + 'hash' => '88b6a06029b1ce38d5e7a70c1d2ebd97', + 'uri' => '/res/88b6a060/rsrc/image/app/app_maniphest.png', + 'disk' => '/rsrc/image/app/app_maniphest.png', + 'type' => 'png', + ), + '/rsrc/image/app/app_phriction.png' => + array( + 'hash' => '68f2387363a26c15653a39bd847157f3', + 'uri' => '/res/68f23873/rsrc/image/app/app_phriction.png', + 'disk' => '/rsrc/image/app/app_phriction.png', + 'type' => 'png', + ), '/rsrc/image/apps.png' => array( 'hash' => 'f7cb4abeb73245fea4098a02fd784653', @@ -14,6 +63,34 @@ celerity_register_resource_map(array( 'disk' => '/rsrc/image/apps.png', 'type' => 'png', ), + '/rsrc/image/appstatus_empty.png' => + array( + 'hash' => '2f8102e0a0f5a0980d87d4ab4ba8c8fd', + 'uri' => '/res/2f8102e0/rsrc/image/appstatus_empty.png', + 'disk' => '/rsrc/image/appstatus_empty.png', + 'type' => 'png', + ), + '/rsrc/image/appstatus_info.png' => + array( + 'hash' => '407de6daf2edc4a8b68e2e369f4fc8cb', + 'uri' => '/res/407de6da/rsrc/image/appstatus_info.png', + 'disk' => '/rsrc/image/appstatus_info.png', + 'type' => 'png', + ), + '/rsrc/image/appstatus_needs.png' => + array( + 'hash' => '2c1e193bc786ca4fca0b851ed9cd3d92', + 'uri' => '/res/2c1e193b/rsrc/image/appstatus_needs.png', + 'disk' => '/rsrc/image/appstatus_needs.png', + 'type' => 'png', + ), + '/rsrc/image/appstatus_okay.png' => + array( + 'hash' => 'd00e683ee1c61d0ccced1200775cdbb5', + 'uri' => '/res/d00e683e/rsrc/image/appstatus_okay.png', + 'disk' => '/rsrc/image/appstatus_okay.png', + 'type' => 'png', + ), '/rsrc/image/avatar.png' => array( 'hash' => '1c5f255071537f05406adee86717ff27', @@ -2142,6 +2219,15 @@ celerity_register_resource_map(array( ), 'disk' => '/rsrc/css/application/directory/phabricator-app-buttons.css', ), + 'phabricator-application-launch-view-css' => + array( + 'uri' => '/res/e157830a/rsrc/css/application/base/phabricator-application-launch-view.css', + 'type' => 'css', + 'requires' => + array( + ), + 'disk' => '/rsrc/css/application/base/phabricator-application-launch-view.css', + ), 'phabricator-chatlog-css' => array( 'uri' => '/res/f6631adc/rsrc/css/application/chatlog/chatlog.css', diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index adc3122af6..4b8013417d 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -536,9 +536,18 @@ phutil_register_library_map(array( 'Phabricator404Controller' => 'applications/base/controller/Phabricator404Controller.php', 'PhabricatorAccessLog' => 'infrastructure/PhabricatorAccessLog.php', 'PhabricatorApplication' => 'applications/base/PhabricatorApplication.php', + 'PhabricatorApplicationApplications' => 'applications/meta/application/PhabricatorApplicationApplications.php', + 'PhabricatorApplicationAudit' => 'applications/audit/application/PhabricatorApplicationAudit.php', 'PhabricatorApplicationDifferential' => 'applications/differential/application/PhabricatorApplicationDifferential.php', + 'PhabricatorApplicationDiffusion' => 'applications/diffusion/application/PhabricatorApplicationDiffusion.php', 'PhabricatorApplicationFact' => 'applications/fact/application/PhabricatorApplicationFact.php', + 'PhabricatorApplicationFlags' => 'applications/flag/application/PhabricatorApplicationFlags.php', + 'PhabricatorApplicationLaunchView' => 'applications/meta/view/PhabricatorApplicationLaunchView.php', 'PhabricatorApplicationManiphest' => 'applications/maniphest/application/PhabricatorApplicationManiphest.php', + 'PhabricatorApplicationPhriction' => 'applications/phriction/application/PhabricatorApplicationPhriction.php', + 'PhabricatorApplicationStatusView' => 'applications/meta/view/PhabricatorApplicationStatusView.php', + 'PhabricatorApplicationsController' => 'applications/meta/controller/PhabricatorApplicationsController.php', + 'PhabricatorApplicationsListController' => 'applications/meta/controller/PhabricatorApplicationsListController.php', 'PhabricatorAuditActionConstants' => 'applications/audit/constants/PhabricatorAuditActionConstants.php', 'PhabricatorAuditAddCommentController' => 'applications/audit/controller/PhabricatorAuditAddCommentController.php', 'PhabricatorAuditComment' => 'applications/audit/storage/PhabricatorAuditComment.php', @@ -1602,9 +1611,18 @@ phutil_register_library_map(array( 'PackageDeleteMail' => 'PackageMail', 'PackageModifyMail' => 'PackageMail', 'Phabricator404Controller' => 'PhabricatorController', + 'PhabricatorApplicationApplications' => 'PhabricatorApplication', + 'PhabricatorApplicationAudit' => 'PhabricatorApplication', 'PhabricatorApplicationDifferential' => 'PhabricatorApplication', + 'PhabricatorApplicationDiffusion' => 'PhabricatorApplication', 'PhabricatorApplicationFact' => 'PhabricatorApplication', + 'PhabricatorApplicationFlags' => 'PhabricatorApplication', + 'PhabricatorApplicationLaunchView' => 'AphrontView', 'PhabricatorApplicationManiphest' => 'PhabricatorApplication', + 'PhabricatorApplicationPhriction' => 'PhabricatorApplication', + 'PhabricatorApplicationStatusView' => 'AphrontView', + 'PhabricatorApplicationsController' => 'PhabricatorController', + 'PhabricatorApplicationsListController' => 'PhabricatorApplicationsController', 'PhabricatorAuditAddCommentController' => 'PhabricatorAuditController', 'PhabricatorAuditComment' => 'PhabricatorAuditDAO', 'PhabricatorAuditCommitListView' => 'AphrontView', diff --git a/src/applications/audit/application/PhabricatorApplicationAudit.php b/src/applications/audit/application/PhabricatorApplicationAudit.php new file mode 100644 index 0000000000..6bfd190515 --- /dev/null +++ b/src/applications/audit/application/PhabricatorApplicationAudit.php @@ -0,0 +1,73 @@ +withAuditorPHIDs($phids) + ->withStatus(PhabricatorAuditQuery::STATUS_OPEN) + ->withAwaitingUser($user) + ->execute(); + + $count = count($audits); + $type = $count + ? PhabricatorApplicationStatusView::TYPE_INFO + : PhabricatorApplicationStatusView::TYPE_EMPTY; + $status[] = id(new PhabricatorApplicationStatusView()) + ->setType($type) + ->setText(pht('%d Commit(s) Awaiting Audit', $count)) + ->setCount($count); + + + $commits = id(new PhabricatorAuditCommitQuery()) + ->withAuthorPHIDs($phids) + ->withStatus(PhabricatorAuditQuery::STATUS_OPEN) + ->execute(); + + $count = count($commits); + $type = $count + ? PhabricatorApplicationStatusView::TYPE_NEEDS_ATTENTION + : PhabricatorApplicationStatusView::TYPE_EMPTY; + $status[] = id(new PhabricatorApplicationStatusView()) + ->setType($type) + ->setText(pht('%d Problem Commit(s)', $count)) + ->setCount($count); + + return $status; + } + +} + diff --git a/src/applications/base/PhabricatorApplication.php b/src/applications/base/PhabricatorApplication.php index 65f86362c0..93ce67fa21 100644 --- a/src/applications/base/PhabricatorApplication.php +++ b/src/applications/base/PhabricatorApplication.php @@ -57,6 +57,10 @@ abstract class PhabricatorApplication { return PhabricatorUser::getDefaultProfileImageURI(); } + public function shouldAppearInLaunchView() { + return true; + } + /* -( URI Routing )-------------------------------------------------------- */ @@ -74,6 +78,14 @@ abstract class PhabricatorApplication { } +/* -( Launch Integration )------------------------------------------------- */ + + + public function loadStatus(PhabricatorUser $user) { + return array(); + } + + /* -( Application Management )--------------------------------------------- */ diff --git a/src/applications/differential/application/PhabricatorApplicationDifferential.php b/src/applications/differential/application/PhabricatorApplicationDifferential.php index 1df206c4ad..7f22c36a7b 100644 --- a/src/applications/differential/application/PhabricatorApplicationDifferential.php +++ b/src/applications/differential/application/PhabricatorApplicationDifferential.php @@ -18,18 +18,54 @@ final class PhabricatorApplicationDifferential extends PhabricatorApplication { + public function getBaseURI() { + return '/differential/'; + } + + public function getShortDescription() { + return 'Review Code'; + } + + public function getIconURI() { + return celerity_get_resource_uri('/rsrc/image/app/app_differential.png'); + } + public function getFactObjectsForAnalysis() { return array( new DifferentialRevision(), ); } - public function getBaseURI() { - return '/differential/'; - } + public function loadStatus(PhabricatorUser $user) { + $revisions = id(new DifferentialRevisionQuery()) + ->withResponsibleUsers(array($user->getPHID())) + ->withStatus(DifferentialRevisionQuery::STATUS_OPEN) + ->execute(); - public function getShortDescription() { - return 'Code Review Application'; + list($active, $waiting) = DifferentialRevisionQuery::splitResponsible( + $revisions, + $user->getPHID()); + + $status = array(); + + $active = count($active); + $type = $active + ? PhabricatorApplicationStatusView::TYPE_NEEDS_ATTENTION + : PhabricatorApplicationStatusView::TYPE_EMPTY; + $status[] = id(new PhabricatorApplicationStatusView()) + ->setType($type) + ->setText(pht('%d Review(s) Need Attention', $active)) + ->setCount($active); + + $waiting = count($waiting); + $type = $waiting + ? PhabricatorApplicationStatusView::TYPE_INFO + : PhabricatorApplicationStatusView::TYPE_EMPTY; + $status[] = id(new PhabricatorApplicationStatusView()) + ->setType($type) + ->setText(pht('%d Review(s) Waiting on Others', $waiting)); + + return $status; } } diff --git a/src/applications/diffusion/application/PhabricatorApplicationDiffusion.php b/src/applications/diffusion/application/PhabricatorApplicationDiffusion.php new file mode 100644 index 0000000000..da1924d46c --- /dev/null +++ b/src/applications/diffusion/application/PhabricatorApplicationDiffusion.php @@ -0,0 +1,34 @@ + array( diff --git a/src/applications/flag/application/PhabricatorApplicationFlags.php b/src/applications/flag/application/PhabricatorApplicationFlags.php new file mode 100644 index 0000000000..b60f441c8e --- /dev/null +++ b/src/applications/flag/application/PhabricatorApplicationFlags.php @@ -0,0 +1,53 @@ +withOwnerPHIDs(array($user->getPHID())) + ->execute(); + + $count = count($flags); + $type = $count + ? PhabricatorApplicationStatusView::TYPE_INFO + : PhabricatorApplicationStatusView::TYPE_EMPTY; + $status[] = id(new PhabricatorApplicationStatusView()) + ->setType($type) + ->setText(pht('%d Flagged Object(s)', $count)) + ->setCount($count); + + return $status; + } + +} + diff --git a/src/applications/maniphest/application/PhabricatorApplicationManiphest.php b/src/applications/maniphest/application/PhabricatorApplicationManiphest.php index b459d4f157..98c0035d32 100644 --- a/src/applications/maniphest/application/PhabricatorApplicationManiphest.php +++ b/src/applications/maniphest/application/PhabricatorApplicationManiphest.php @@ -18,15 +18,64 @@ final class PhabricatorApplicationManiphest extends PhabricatorApplication { + public function getShortDescription() { + return 'Tasks and Bugs'; + } + + public function getBaseURI() { + return '/maniphest/'; + } + public function isEnabled() { return PhabricatorEnv::getEnvConfig('maniphest.enabled'); } + public function getIconURI() { + return celerity_get_resource_uri('/rsrc/image/app/app_maniphest.png'); + } + public function getFactObjectsForAnalysis() { return array( new ManiphestTask(), ); } + public function loadStatus(PhabricatorUser $user) { + $status = array(); + + $query = id(new ManiphestTaskQuery()) + ->withStatus(ManiphestTaskQuery::STATUS_OPEN) + ->withPriority(ManiphestTaskPriority::PRIORITY_UNBREAK_NOW) + ->setLimit(1) + ->setCalculateRows(true); + $query->execute(); + + $count = $query->getRowCount(); + $type = $count + ? PhabricatorApplicationStatusView::TYPE_NEEDS_ATTENTION + : PhabricatorApplicationStatusView::TYPE_EMPTY; + $status[] = id(new PhabricatorApplicationStatusView()) + ->setType($type) + ->setText(pht('%d Unbreak Now Task(s)!', $count)) + ->setCount($count); + + $query = id(new ManiphestTaskQuery()) + ->withStatus(ManiphestTaskQuery::STATUS_OPEN) + ->withOwners(array($user->getPHID())) + ->setLimit(1) + ->setCalculateRows(true); + $query->execute(); + + $count = $query->getRowCount(); + $type = $count + ? PhabricatorApplicationStatusView::TYPE_INFO + : PhabricatorApplicationStatusView::TYPE_EMPTY; + $status[] = id(new PhabricatorApplicationStatusView()) + ->setType($type) + ->setText(pht('%d Assigned Task(s)', $count)); + + return $status; + } + } diff --git a/src/applications/meta/application/PhabricatorApplicationApplications.php b/src/applications/meta/application/PhabricatorApplicationApplications.php new file mode 100644 index 0000000000..f9360be2cf --- /dev/null +++ b/src/applications/meta/application/PhabricatorApplicationApplications.php @@ -0,0 +1,42 @@ + array( + '' => 'PhabricatorApplicationsListController' + ), + ); + } + + public function shouldAppearInLaunchView() { + return false; + } + +} + diff --git a/src/applications/meta/controller/PhabricatorApplicationsController.php b/src/applications/meta/controller/PhabricatorApplicationsController.php new file mode 100644 index 0000000000..b0805c8f1a --- /dev/null +++ b/src/applications/meta/controller/PhabricatorApplicationsController.php @@ -0,0 +1,35 @@ +buildStandardPageView(); + + $page->setApplicationName('Applications'); + $page->setBaseURI('/applications/'); + $page->setTitle(idx($data, 'title')); + $page->setGlyph("\xE0\xBC\x84"); + $page->appendChild($view); + + $response = new AphrontWebpageResponse(); + return $response->setContent($page->render()); + + } +} diff --git a/src/applications/meta/controller/PhabricatorApplicationsListController.php b/src/applications/meta/controller/PhabricatorApplicationsListController.php new file mode 100644 index 0000000000..59ad41fec5 --- /dev/null +++ b/src/applications/meta/controller/PhabricatorApplicationsListController.php @@ -0,0 +1,63 @@ +getRequest(); + $user = $request->getUser(); + + $applications = PhabricatorApplication::getAllInstalledApplications(); + $applications = msort($applications, 'getName'); + + foreach ($applications as $key => $application) { + if (!$application->shouldAppearInLaunchView()) { + unset($applications[$key]); + } + } + + $status = array(); + foreach ($applications as $key => $application) { + $status[$key] = $application->loadStatus($user); + } + + $views = array(); + foreach ($applications as $key => $application) { + $views[] = id(new PhabricatorApplicationLaunchView()) + ->setApplication($application) + ->setApplicationStatus(idx($status, $key, array())) + ->setUser($user); + } + + $view = phutil_render_tag( + 'div', + array( + 'class' => 'phabricator-application-list', + ), + id(new AphrontNullView())->appendChild($views)->render()); + + return $this->buildStandardPageResponse( + $view, + array( + 'title' => 'Applications', + )); + } + +} + diff --git a/src/applications/meta/view/PhabricatorApplicationLaunchView.php b/src/applications/meta/view/PhabricatorApplicationLaunchView.php new file mode 100644 index 0000000000..4b0c852f35 --- /dev/null +++ b/src/applications/meta/view/PhabricatorApplicationLaunchView.php @@ -0,0 +1,88 @@ +application = $application; + return $this; + } + + public function setUser(PhabricatorUser $user) { + $this->user = $user; + return $this; + } + + public function setApplicationStatus(array $status) { + $this->status = $status; + return $this; + } + + public function render() { + $application = $this->application; + + require_celerity_resource('phabricator-application-launch-view-css'); + + $content = array(); + $content[] = phutil_render_tag( + 'span', + array( + 'class' => 'phabricator-application-launch-name', + ), + phutil_escape_html($application->getName())); + $content[] = phutil_render_tag( + 'span', + array( + 'class' => 'phabricator-application-launch-description', + ), + phutil_escape_html($application->getShortDescription())); + + + $count = 0; + if ($this->status) { + $content[] = ''; + foreach ($this->status as $status) { + $count += $status->getCount(); + $content[] = $status; + } + $content[] = ''; + } + + if ($count) { + $content[] = phutil_render_tag( + 'span', + array( + 'class' => 'phabricator-application-launch-attention', + ), + phutil_escape_html($count)); + } + + return phutil_render_tag( + 'a', + array( + 'class' => 'phabricator-application-launch-container', + 'style' => 'background-image: url('.$application->getIconURI().')', + 'href' => $application->getBaseURI(), + ), + $this->renderSingleView($content)); + } +} diff --git a/src/applications/meta/view/PhabricatorApplicationStatusView.php b/src/applications/meta/view/PhabricatorApplicationStatusView.php new file mode 100644 index 0000000000..bb2d4f24f2 --- /dev/null +++ b/src/applications/meta/view/PhabricatorApplicationStatusView.php @@ -0,0 +1,64 @@ +type = $type; + return $this; + } + + public function setText($text) { + $this->text = $text; + return $this; + } + + public function setCount($count) { + $this->count = $count; + return $this; + } + + public function getCount() { + return $this->count; + } + + public function render() { + $classes = array( + 'phabricator-application-status', + 'phabricator-application-status-type-'.$this->type, + ); + + return phutil_render_tag( + 'span', + array( + 'class' => implode(' ', $classes), + ), + phutil_escape_html($this->text)); + } + +} diff --git a/src/applications/phriction/application/PhabricatorApplicationPhriction.php b/src/applications/phriction/application/PhabricatorApplicationPhriction.php new file mode 100644 index 0000000000..80e94b29db --- /dev/null +++ b/src/applications/phriction/application/PhabricatorApplicationPhriction.php @@ -0,0 +1,35 @@ + array( + '%d Commit Awaiting Audit', + '%d Commits Awaiting Audit', + ), + + '%d Problem Commit(s)' => array( + '%d Problem Commit', + '%d Problem Commits', + ), + + '%d Review(s) Need Attention' => array( + '%d Review Needs Attention', + '%d Reviews Need Attention', + ), + + '%d Review(s) Waiting on Others' => array( + '%d Review Waiting on Others', + '%d Reviews Waiting on Others', + ), + + '%d Flagged Object(s)' => array( + '%d Flagged Object', + '%d Flagged Objects', + ), + + '%d Unbreak Now Task(s)!' => array( + '%d Unbreak Now Task!', + '%d Unbreak Now Tasks!', + ), + + '%d Assigned Task(s)' => array( + '%d Assigned Task', + '%d Assigned Tasks', + ), + ); } diff --git a/webroot/rsrc/css/application/base/phabricator-application-launch-view.css b/webroot/rsrc/css/application/base/phabricator-application-launch-view.css new file mode 100644 index 0000000000..499cc45466 --- /dev/null +++ b/webroot/rsrc/css/application/base/phabricator-application-launch-view.css @@ -0,0 +1,131 @@ +/** + * @provides phabricator-application-launch-view-css + */ + + +/* - Application List ---------------------------------------------------------- + + Spacing container for the list of large application buttons. + +*/ + +/* On desktops, put some space around the whole grid. */ +.device-desktop .phabricator-application-list { + padding: .5em; +} + +/* On tablets, show two columns in the center. */ +.device-tablet .phabricator-application-list { + width: 660px; + margin: auto; + padding: .5em 0; +} + + +/* - Application Launch Button ------------------------------------------------- + + Spacing container for the list of large application buttons. + +*/ + +a.phabricator-application-launch-container { + display: inline-block; + width: 210px; + min-height: 90px; + background-repeat: no-repeat; + padding: 5px 15px 5px 80px; + background-position: 15px 10px; + margin: 3px 6px; + overflow: hidden; + position: relative; + + text-decoration: none; + border: 1px solid #737373; + background-color: #f3f3f3; + + border-radius: 4px; + box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.10), + inset -1px -1px 2px rgba(0, 0, 0, 0.15); +} + +a.phabricator-application-launch-container:hover { + text-decoration: none; +} + +/* The hover effect looks awful on phones/tablets when scrolling. */ +.device-desktop a.phabricator-application-launch-container:hover { + background-color: #3875d7; + border-color: #223366; + color: #eeeeee; +} + +.phabricator-application-launch-name, +.phabricator-application-launch-description, +.phabricator-application-launch-status { + display: block; +} + +.phabricator-application-launch-name { + font-weight: bold; +} + +.phabricator-application-launch-description { + color: #666666; +} + +.device-desktop a.phabricator-application-launch-container:hover + .phabricator-application-launch-description { + color: #dddddd; +} + +.phabricator-application-launch-attention { + position: absolute; + left: 45px; + top: 10px; + background: red; + border-radius: 10px; + color: white; + font-weight: normal; + padding: 2px 6px; + border: 1px solid #aa0000; + box-shadow: 0px 0px 3px rgba(255, 255, 255, 0.5), + inset 0 0 3px #aa0000; +} + +.phabricator-application-status-block { + margin-top: 0.5em; + padding-top: 0.5em; + border-top: 1px solid #dfdfdf; + display: block; +} + +.phabricator-application-status { + float: left; + display: block; + position: relative; + font-size: 11px; + height: 20px; + padding-left: 22px; + color: #666666; + + background-repeat: no-repeat; + background-size: 16px auto; + padding-top: 1px; +} + +.device-desktop a.phabricator-application-launch-container:hover + .phabricator-application-status { + color: #eeeeee; +} + +.phabricator-application-status-type-needs { + background-image: url(/rsrc/image/appstatus_needs.png); +} + +.phabricator-application-status-type-empty { + background-image: url(/rsrc/image/appstatus_empty.png); +} + +.phabricator-application-status-type-info { + background-image: url(/rsrc/image/appstatus_info.png); +} diff --git a/webroot/rsrc/image/app/app_audit.png b/webroot/rsrc/image/app/app_audit.png new file mode 100755 index 0000000000000000000000000000000000000000..4bd098c0243e5fc89e49b33ad9ae9f5ba7a60d82 GIT binary patch literal 545 zcmV++0^a?JP)PD8&-41WT|4jt6J!KdVDizL3ro;qa#~VbZR@=>IEPaV0QzYwOfH|AtnQW z6=<@7a4Q5kz*(WxI;9Ywe}{lRB``D^!Ii3`(R2}dr>f`%?JT-6OY9XnAKy>Ow>Hhn&Z4B;4ta1X`6fVUVTZC1Ei){cwqvT~7L?ke5kOzR| z-D*}sP#A8N1t9s{r&mF67|fMiZU+$Zk`#h_0Uhk)_wGf^riI`Zq3(Y$bYtd)v9ObC z(ky@|O`XO%5Z=jI0g;4$dOU zt*)f_02n~1ix0YT5LV${T@GrdK-Wacw22~iTgM9RAN1&t-rPrT&td4V98W(N27ciR j$8)Ksfoo1}Ts->%y6j;GSDc^T00000NkvXXu0mjfDZu1M literal 0 HcmV?d00001 diff --git a/webroot/rsrc/image/app/app_differential.png b/webroot/rsrc/image/app/app_differential.png new file mode 100755 index 0000000000000000000000000000000000000000..6afefd7aa2b991472448ea4354c28b8b1c2fb779 GIT binary patch literal 526 zcmV+p0`dKcP)$yC9AgHmBz=cGRgr3W z`~@2+EssqBG{8}%GH)*N;b=mfGqUn&M6_x)oIve&nK(<-12AAJlu`r2$v~(~{IvWR z=*C6b_l$H+Trt;Pj^OB)I==QqdUQSA8TqwE{OHJOeL`G=FuI1J(!`IZh+xWi;=7+E z>rkys1tF=0n+Gk}ZUq5h>rCM6PyJ1<|9UMaX{3f?hJuK($U-F18BqAf`Rh#Ad`uKhV z(8U9x>@aA$@jz(Jddl8^K7RiZ-2Bo*&${?_f%qgLen<(+-vP+7NbcIgXR)3y0c^DFWe=)14P&71D>75DG_0CHlTf3-^y Q;s5{u07*qoM6N<$g7~!XzW@LL literal 0 HcmV?d00001 diff --git a/webroot/rsrc/image/app/app_diffusion.png b/webroot/rsrc/image/app/app_diffusion.png new file mode 100755 index 0000000000000000000000000000000000000000..b6961ef48ae434069c84722dcdab58110893b666 GIT binary patch literal 397 zcmeAS@N?(olHy`uVBq!ia0vp^MnG)B!3HExq-C#RU|o+1me`^E zPgdx(90s&|x@q}8{|KYgaZU=8Bflvzoz$roYz)cUAJ5vt)}oN2px!j0Va|n3{Q=D} z7uB7AJTAU1=)NY-(PrNF)cKix59<9_D_F3!b51*=*cZ^cL`IR}VYzywN8Luo%BQ^U id;6v@QII*foB8ANS4}bVqw0Xc%;4$j=d#Wzp$Py4s-z$Q literal 0 HcmV?d00001 diff --git a/webroot/rsrc/image/app/app_fact.png b/webroot/rsrc/image/app/app_fact.png new file mode 100755 index 0000000000000000000000000000000000000000..7d95d490a7fe52b4010214491e5b3e3b967c9eb4 GIT binary patch literal 536 zcmV+z0_XjSP);yMejzABBSkjh4cU}IyEQY%wjc}1|Xu@J#Nh!3#- zfe~a_vcqBab|ed5v)R4O2Rl2vxf5%xD$o*8f{G|X^7DLb_BRthWJZqs`~nO-X6h@n z37rG$A=4zZ7YKElgsg-`NSzQcF(S<&O+s6NP_Ajo-A;%Mpj1XziPuB0gIq@zz_fpG! z^J5U=H_#iRVKLR?I2A%@1-pTA-aw*3h;PYm=s2TAs1pdanuM$bK0oFT3f$}G10fiO%!}@UwOejJKnUKt#L%nN$j5)Ld zy+EkYBJ?0V@@o*{G6NOQj(7xX8Xvb1S~+nnVK0na2(9oetGI<6pOe1W^Lt=oLn5?x z$n1boB}AQxV|#w(*8?><Xzc(n6_Pi2u3tUxXSOq)|vei_ju; aB%yDI{a|ZF0!CE;00009K-E1r7g)_;kp$y>*4kzJJa zPu1!Cgcbd1R_rl%S{Q>F(?0B7t(JdlYs1ZR>1|ATyE5OYC9G#Nr47C_qy^d% zF@6L9lQKpUiCCS8RlNa@gek*VD{F56cLvDB>vKh#0G(6F^afZf7V#T#-OFhBql_w) zQQK-quKxp=W9l{9QR2lhPZFa62$IX0M~oQnGz#SaK5-LZ0!)AjFaajO1egF5U;_LT z09^k($)SU0aSc?X0Kkuix1HqR`^Y}@0!|hJ@J;3~NC@IfJp};6p+H;IoMH(5oCg79 z;Y3={^UXI%AyojeaN8oLSBL zjj8%YtPAqrMF6}XBi_^kVAfq}35@|<%H+*W&X5ELfQDuo_gBr~m? literal 0 HcmV?d00001 diff --git a/webroot/rsrc/image/app/app_phriction.png b/webroot/rsrc/image/app/app_phriction.png new file mode 100755 index 0000000000000000000000000000000000000000..3b8ccbd245183a315eda410d7b412fd17584fde0 GIT binary patch literal 257 zcmeAS@N?(olHy`uVBq!ia0vp^IzVi|!3HF=Cd_yUq)vFcIEGZ*dVBLA=V1e$)`xi$ z1Z|w$K4{1;RZd~)oiNd=$*mxML4tE?jYf!2ZQFl=4-XIT^xS@JmSo?8XE!=uwP$yJ zeJ_!_aigu_L5p_%oWGZpzuE0vk+J{XAEi0Jwyj89S$D&<#`wZ={j%OViFFM(_|~c2 zFm!D?CGwVk-v5g>5Bl^h57?e$yB3q+VsMZ}*awaHFu%!EI>M+?bZSAu7T*KEzs^m( v^Gjy==SKEhWf#NQ{yoUQp3`_eu1vp7VO#H>94CLEpBOw{{an^LB{Ts5_d9Mi literal 0 HcmV?d00001 diff --git a/webroot/rsrc/image/appstatus_empty.png b/webroot/rsrc/image/appstatus_empty.png new file mode 100644 index 0000000000000000000000000000000000000000..e1a48b5841d052346485bb9589147a2b63faaff6 GIT binary patch literal 774 zcmV+h1Nr=kP)bY=}d@> zSir0Y0w*|D2pwHOsCi-TM)RK-bpNqPidn-I1XG8!3xef6C&v(!4haXOnzJ`7K?I;f zg@Qn%0Lx^ZLU43Z3?Y$uR-Qn#38PNpaDi6P5)jyVf@Z(IL68#u1qf>(t|2%ekw*{_ z1=0`|nJ<>WbZJ7Op`3W+PFh_QLr9z#3DhZ0AwY)&JL@QrUkRn7jh#}5cF0J|3J;=F zK_#`_QuhN%SF%nEXjKSe@l>t!I1Im-lEM+hmas-Sc8&<5K6Y`~3B*gs7A0Zv2}8kj;(Fc`G*BDAXm5IZ=_Z ziXB5M)C`C^(Db?f_KTj*WcUB-ZLo4x;Q7l?vOvZ{U(4Ks0h5jRb;L z0MyScAPRtNYvKrLCCm^Yej&soKDjlU)+A60Fdw8K=!F8qXik$4Epzb>cT}JX6WNDJ zLD<-ojytH)euhwT3ALn8-MGaQ^#UMNnAqeQ(UTL^f*=^qrNX(nfnbuwYvE>ByI?Ge?xt zBNWTj#20gVV*(Y+xwDcs|aRskgm?js=gP6)2GumTg(Fop zEI%6E>+)L?B;9Vn--@x`&_N0xQaqv>Zq2C-TGpsc*aLPR-z}YXIK8$fdO6nS?EVN3_vLh@lcHcD%@jE7O>e5p8X0i Y04oyl0wAhv#Q*>R07*qoM6N<$g7P~z^Z)<= literal 0 HcmV?d00001 diff --git a/webroot/rsrc/image/appstatus_needs.png b/webroot/rsrc/image/appstatus_needs.png new file mode 100644 index 0000000000000000000000000000000000000000..cdd5542f910fb2b3482b058ed10f7be8ee1c229d GIT binary patch literal 719 zcmV;=0xE_u%(u-)z}(r6@qO>1Hr-1@h2yMWZ*cq z5(ry~P{}V-FD$rVkKwgm|XeD;OXm>QnZ;C0%YULROHbe~J9cQo62$s*MdcQQeclmp$Yv~n#YZVnFi^7xa1cX-2BtVelxZ(qcHL&xCKF@|&1(by*R9UDXspHPmHpQ-W zflZ0rca}VX912`u3UaR?k^vaA$=oAI1l&Q$oUy!sq`s`--6H=WmLS4oz;l6Y4|{f0 z_|3HeQYzGZz+Sy=*Eu`7R?S$Q3Tg$Dj#`b8Cg57DQ9-JJK@Ma8{jP;^^5w8x;rgz1 z5#*@n_B{Po4ug;DyO!1(=O86xDpn!)j=B=+q`;YiGN9NvISc}g*+l>l;(XFUWA-cn zkc-0~(D?9b;^}xvW3(z7^C62QrC8nnbJMd9i=WnGjAw|nmzOWb6N-z(l=a|Bn%vRm zNK6DGy_UM6CFgIb^d7SoJDg#*-HvG8SSglSj#NjbHg{J#-F%>vqRKQ$E)|L&z415~)zoLa!VUp)H}U;v3+{$wjg2;X93CQ`2S}EBFfzNs$rOP%k zpzC7EwC_c1{kDSbwn7&hJzZ?QJ)5DeY)?N223k16@f@nT;FweLJm%ER!LuLBxA~1( S$I