From 43430e154d3eea6f0edb0655ef3f9179f0b5e0cb Mon Sep 17 00:00:00 2001 From: epriestley Date: Fri, 16 Dec 2011 20:01:38 -0800 Subject: [PATCH] Rough cut of Project profile improvements Summary: - Old page was useless and dumb. - New page looks a little less bad, functions a little less poorly. - Still lots of work to be done. Test Plan: - Viewed a project. - Clicked all the links on the left nav. - Here is a screenshot: https://secure.phabricator.com/file/view/PHID-FILE-4buzquotb3fo4dhlicrw/ Reviewers: btrahan, jungejason Reviewed By: jungejason CC: aran, jungejason Maniphest Tasks: T681 Differential Revision: 1246 --- src/__celerity_resource_map__.php | 195 +++++++------- src/__phutil_library_map__.php | 2 + .../transform/PhabricatorImageTransformer.php | 9 +- .../PhabricatorProjectProfileController.php | 252 +++++++++++------- .../project/controller/profile/__init__.php | 10 +- ...habricatorProjectProfileEditController.php | 7 +- .../PhabricatorProfileHeaderView.php | 72 +++++ src/view/layout/profileheader/__init__.php | 15 ++ .../AphrontSideNavFilterView.php | 26 +- .../profile/profile-header-view.css | 32 +++ 10 files changed, 407 insertions(+), 213 deletions(-) create mode 100644 src/view/layout/profileheader/PhabricatorProfileHeaderView.php create mode 100644 src/view/layout/profileheader/__init__.php create mode 100644 webroot/rsrc/css/application/profile/profile-header-view.css diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index c64b5c192f..76c6cbaf27 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -211,6 +211,69 @@ celerity_register_resource_map(array( ), 'disk' => '/rsrc/css/application/differential/add-comment.css', ), + 'differential-revision-comment-css' => + array( + 'uri' => '/res/9fb8013b/rsrc/css/application/differential/revision-comment.css', + 'type' => 'css', + 'requires' => + array( + ), + 'disk' => '/rsrc/css/application/differential/revision-comment.css', + ), + 'differential-revision-comment-list-css' => + array( + 'uri' => '/res/3b31faa3/rsrc/css/application/differential/revision-comment-list.css', + 'type' => 'css', + 'requires' => + array( + ), + 'disk' => '/rsrc/css/application/differential/revision-comment-list.css', + ), + 'differential-revision-detail-css' => + array( + 'uri' => '/res/33592453/rsrc/css/application/differential/revision-detail.css', + 'type' => 'css', + 'requires' => + array( + ), + 'disk' => '/rsrc/css/application/differential/revision-detail.css', + ), + 'differential-revision-history-css' => + array( + 'uri' => '/res/0d7d515d/rsrc/css/application/differential/revision-history.css', + 'type' => 'css', + 'requires' => + array( + ), + 'disk' => '/rsrc/css/application/differential/revision-history.css', + ), + 'differential-table-of-contents-css' => + array( + 'uri' => '/res/d173445b/rsrc/css/application/differential/table-of-contents.css', + 'type' => 'css', + 'requires' => + array( + ), + 'disk' => '/rsrc/css/application/differential/table-of-contents.css', + ), + 'diffusion-commit-view-css' => + array( + 'uri' => '/res/bc39d876/rsrc/css/application/diffusion/commit-view.css', + 'type' => 'css', + 'requires' => + array( + ), + 'disk' => '/rsrc/css/application/diffusion/commit-view.css', + ), + 'diffusion-source-css' => + array( + 'uri' => '/res/db4566b6/rsrc/css/application/diffusion/diffusion-source.css', + 'type' => 'css', + 'requires' => + array( + ), + 'disk' => '/rsrc/css/application/diffusion/diffusion-source.css', + ), 'files-css' => array( 'uri' => '/res/a265a77d/rsrc/css/application/files/files.css', @@ -229,6 +292,25 @@ celerity_register_resource_map(array( ), 'disk' => '/rsrc/css/application/herald/herald.css', ), + 'herald-rule-editor' => + array( + 'uri' => '/res/4d6dff2b/rsrc/js/application/herald/HeraldRuleEditor.js', + 'type' => 'js', + 'requires' => + array( + 0 => 'multirow-row-manager', + 1 => 'javelin-install', + 2 => 'javelin-typeahead', + 3 => 'javelin-util', + 4 => 'javelin-dom', + 5 => 'javelin-tokenizer', + 6 => 'javelin-typeahead-preloaded-source', + 7 => 'javelin-stratcom', + 8 => 'javelin-json', + 9 => 'phabricator-prefab', + ), + 'disk' => '/rsrc/js/application/herald/HeraldRuleEditor.js', + ), 'herald-test-css' => array( 'uri' => '/res/c0cd6bdb/rsrc/css/application/herald/herald-test.css', @@ -248,6 +330,17 @@ celerity_register_resource_map(array( ), 'disk' => '/rsrc/js/javelin/lib/behavior.js', ), + 0 => + array( + 'uri' => '/res/b6096fdd/rsrc/js/javelin/lib/__tests__/URI.js', + 'type' => 'js', + 'requires' => + array( + 0 => 'javelin-uri', + 1 => 'javelin-php-serializer', + ), + 'disk' => '/rsrc/js/javelin/lib/__tests__/URI.js', + ), 'javelin-behavior-aphront-basic-tokenizer' => array( 'uri' => '/res/9be30797/rsrc/js/application/core/behavior-tokenizer.js', @@ -313,99 +406,6 @@ celerity_register_resource_map(array( ), 'disk' => '/rsrc/js/application/countdown/timer.js', ), - 0 => - array( - 'uri' => '/res/b6096fdd/rsrc/js/javelin/lib/__tests__/URI.js', - 'type' => 'js', - 'requires' => - array( - 0 => 'javelin-uri', - 1 => 'javelin-php-serializer', - ), - 'disk' => '/rsrc/js/javelin/lib/__tests__/URI.js', - ), - 'differential-revision-comment-css' => - array( - 'uri' => '/res/9fb8013b/rsrc/css/application/differential/revision-comment.css', - 'type' => 'css', - 'requires' => - array( - ), - 'disk' => '/rsrc/css/application/differential/revision-comment.css', - ), - 'differential-revision-comment-list-css' => - array( - 'uri' => '/res/3b31faa3/rsrc/css/application/differential/revision-comment-list.css', - 'type' => 'css', - 'requires' => - array( - ), - 'disk' => '/rsrc/css/application/differential/revision-comment-list.css', - ), - 'differential-revision-detail-css' => - array( - 'uri' => '/res/33592453/rsrc/css/application/differential/revision-detail.css', - 'type' => 'css', - 'requires' => - array( - ), - 'disk' => '/rsrc/css/application/differential/revision-detail.css', - ), - 'differential-revision-history-css' => - array( - 'uri' => '/res/0d7d515d/rsrc/css/application/differential/revision-history.css', - 'type' => 'css', - 'requires' => - array( - ), - 'disk' => '/rsrc/css/application/differential/revision-history.css', - ), - 'differential-table-of-contents-css' => - array( - 'uri' => '/res/d173445b/rsrc/css/application/differential/table-of-contents.css', - 'type' => 'css', - 'requires' => - array( - ), - 'disk' => '/rsrc/css/application/differential/table-of-contents.css', - ), - 'diffusion-commit-view-css' => - array( - 'uri' => '/res/bc39d876/rsrc/css/application/diffusion/commit-view.css', - 'type' => 'css', - 'requires' => - array( - ), - 'disk' => '/rsrc/css/application/diffusion/commit-view.css', - ), - 'diffusion-source-css' => - array( - 'uri' => '/res/db4566b6/rsrc/css/application/diffusion/diffusion-source.css', - 'type' => 'css', - 'requires' => - array( - ), - 'disk' => '/rsrc/css/application/diffusion/diffusion-source.css', - ), - 'herald-rule-editor' => - array( - 'uri' => '/res/4d6dff2b/rsrc/js/application/herald/HeraldRuleEditor.js', - 'type' => 'js', - 'requires' => - array( - 0 => 'multirow-row-manager', - 1 => 'javelin-install', - 2 => 'javelin-typeahead', - 3 => 'javelin-util', - 4 => 'javelin-dom', - 5 => 'javelin-tokenizer', - 6 => 'javelin-typeahead-preloaded-source', - 7 => 'javelin-stratcom', - 8 => 'javelin-json', - 9 => 'phabricator-prefab', - ), - 'disk' => '/rsrc/js/application/herald/HeraldRuleEditor.js', - ), 'javelin-behavior-dark-console' => array( 'uri' => '/res/c80156c4/rsrc/js/application/core/behavior-dark-console.js', @@ -1416,6 +1416,15 @@ celerity_register_resource_map(array( ), 'disk' => '/rsrc/css/application/profile/profile-view.css', ), + 'phabricator-profile-header-css' => + array( + 'uri' => '/res/d39ef6a4/rsrc/css/application/profile/profile-header-view.css', + 'type' => 'css', + 'requires' => + array( + ), + 'disk' => '/rsrc/css/application/profile/profile-header-view.css', + ), 'phabricator-remarkup-css' => array( 'uri' => '/res/78f26382/rsrc/css/core/remarkup.css', diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 144ea887af..6f68cf1bc3 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -567,6 +567,7 @@ phutil_register_library_map(array( 'PhabricatorPeopleListController' => 'applications/people/controller/list', 'PhabricatorPeopleLogsController' => 'applications/people/controller/logs', 'PhabricatorPeopleProfileController' => 'applications/people/controller/profile', + 'PhabricatorProfileHeaderView' => 'view/layout/profileheader', 'PhabricatorProfileView' => 'view/layout/profile', 'PhabricatorProject' => 'applications/project/storage/project', 'PhabricatorProjectAffiliation' => 'applications/project/storage/affiliation', @@ -1214,6 +1215,7 @@ phutil_register_library_map(array( 'PhabricatorPeopleListController' => 'PhabricatorPeopleController', 'PhabricatorPeopleLogsController' => 'PhabricatorPeopleController', 'PhabricatorPeopleProfileController' => 'PhabricatorPeopleController', + 'PhabricatorProfileHeaderView' => 'AphrontView', 'PhabricatorProfileView' => 'AphrontView', 'PhabricatorProject' => 'PhabricatorProjectDAO', 'PhabricatorProjectAffiliation' => 'PhabricatorProjectDAO', diff --git a/src/applications/files/transform/PhabricatorImageTransformer.php b/src/applications/files/transform/PhabricatorImageTransformer.php index 1919e9c4de..f6cc418768 100644 --- a/src/applications/files/transform/PhabricatorImageTransformer.php +++ b/src/applications/files/transform/PhabricatorImageTransformer.php @@ -89,13 +89,18 @@ final class PhabricatorImageTransformer { $scale = min($x / $dx, $y / $dy); $dst = imagecreatetruecolor($dx, $dy); + // If we need to chop off some pixels, chop them off from the sides instead + // of scaling in on <0, 0>. + $sdx = $scale * $dx; + $sdy = $scale * $dy; + imagecopyresampled( $dst, $src, 0, 0, - 0, 0, + ($x - $sdx) / 2, ($y - $sdy) / 2, $dx, $dy, - $scale * $dx, $scale * $dy); + $sdx, $sdy); return $dst; } diff --git a/src/applications/project/controller/profile/PhabricatorProjectProfileController.php b/src/applications/project/controller/profile/PhabricatorProjectProfileController.php index 7f70750460..fc86ffb693 100644 --- a/src/applications/project/controller/profile/PhabricatorProjectProfileController.php +++ b/src/applications/project/controller/profile/PhabricatorProjectProfileController.php @@ -30,7 +30,6 @@ class PhabricatorProjectProfileController public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); - $uri = $request->getRequestURI(); $project = id(new PhabricatorProject())->load($this->id); if (!$project) { @@ -47,128 +46,111 @@ class PhabricatorProjectProfileController } $picture = PhabricatorFileURI::getViewURIForPHID($src_phid); - $pages = array( - /* - '

Active Documents

', - 'tasks' => 'Maniphest Tasks', - 'revisions' => 'Differential Revisions', - '
', - '

Workflow

', - 'goals' => 'Goals', - 'statistics' => 'Statistics', - '
', */ - '

Information

', - 'edit' => 'Edit Project', - 'affiliation' => 'Edit Affiliation', - ); + $nav_view = new AphrontSideNavFilterView(); + $uri = new PhutilURI('/project/view/'.$project->getID().'/'); + $nav_view->setBaseURI($uri); - if (empty($pages[$this->page])) { - $this->page = 'action'; - } + $external_arrow = "\xE2\x86\x97"; + $tasks_uri = '/maniphest/view/all/?projects='.$project->getPHID(); + $slug = PhrictionDocument::normalizeSlug($project->getName()); + $phriction_uri = '/w/projects/'.$slug.'/'; + $edit_uri = '/project/edit/'.$project->getID().'/'; + + $nav_view->addFilter('dashboard', 'Dashboard'); + $nav_view->addSpacer(); + $nav_view->addFilter('feed', 'Feed'); + $nav_view->addFilter(null, 'Tasks '.$external_arrow, $tasks_uri); + $nav_view->addFilter(null, 'Wiki '.$external_arrow, $phriction_uri); + $nav_view->addFilter('people', 'People'); + $nav_view->addFilter('about', 'About'); + $nav_view->addSpacer(); + $nav_view->addFilter(null, "Edit Project\xE2\x80\xA6", $edit_uri); + + $this->page = $nav_view->selectFilter($this->page, 'dashboard'); + + + require_celerity_resource('phabricator-profile-css'); switch ($this->page) { - default: - $content = $this->renderBasicInformation($project, $profile); + case 'dashboard': + $content = $this->renderTasksPage($project, $profile); + + $query = new PhabricatorFeedQuery(); + $query->setFilterPHIDs( + array( + $project->getPHID(), + )); + $stories = $query->execute(); + + $builder = new PhabricatorFeedBuilder($stories); + $builder->setUser($user); + $view = $builder->buildView(); + + $content .= + '
'. + $view->render(). + '
'; break; + case 'about': + $content = $this->renderAboutPage($project, $profile); + break; + case 'people': + $content = $this->renderPeoplePage($project, $profile); + break; + case 'feed': + $content = $this->renderFeedPage($project, $profile); + break; + default: + throw new Exception("Unimplemented filter '{$this->page}'."); } - $profile = new PhabricatorProfileView(); - $profile->setProfilePicture($picture); - $profile->setProfileNames($project->getName()); - foreach ($pages as $page => $name) { - if (is_integer($page)) { - $profile->addProfileItem( - phutil_render_tag( - 'span', - array(), - $name)); - } else { - $uri->setPath('/project/'.$page.'/'.$project->getID().'/'); - $profile->addProfileItem( - phutil_render_tag( - 'a', - array( - 'href' => $uri, - 'class' => ($this->page == $page) - ? 'phabricator-profile-item-selected' - : null, - ), - phutil_escape_html($name))); - } - } + $content = '
'.$content.'
'; + $nav_view->appendChild($content); - $profile->appendChild($content); + $header = new PhabricatorProfileHeaderView(); + $header->setName($project->getName()); + $header->setDescription( + phutil_utf8_shorten($profile->getBlurb(), 1024)); + $header->setProfilePicture($picture); + + $header->appendChild($nav_view); return $this->buildStandardPageResponse( - $profile, + $header, array( - 'title' => $project->getName(), - )); + 'title' => $project->getName().' Project', + )); } - //---------------------------------------------------------------------------- - // Helper functions + private function renderAboutPage( + PhabricatorProject $project, + PhabricatorProjectProfile $profile) { - private function renderBasicInformation($project, $profile) { - $blurb = nonempty( - $profile->getBlurb(), - '//Nothing is known about this elusive project.//'); + $viewer = $this->getRequest()->getUser(); - $engine = PhabricatorMarkupEngine::newProfileMarkupEngine(); - $blurb = $engine->markupText($blurb); - - $affiliations = $project->loadAffiliations(); + $blurb = $profile->getBlurb(); + $blurb = phutil_escape_html($blurb); + $blurb = str_replace("\n", '
', $blurb); $phids = array_merge( array($project->getAuthorPHID()), - $project->getSubprojectPHIDs(), - mpull($affiliations, 'getUserPHID') + $project->getSubprojectPHIDs() ); $phids = array_unique($phids); $handles = id(new PhabricatorObjectHandleData($phids)) ->loadHandles(); - $affiliated = array(); - foreach ($affiliations as $affiliation) { - $user = $handles[$affiliation->getUserPHID()]->renderLink(); - $role = phutil_escape_html($affiliation->getRole()); - $affiliated[] = '
  • '.$user.' — '.$role.'
  • '; - } - - if ($affiliated) { - $affiliated = ''; - } else { - $affiliated = '

    No one is affiliated with this project.

    '; - } - - if ($project->getSubprojectPHIDs()) { - $table = $this->renderSubprojectTable( - $handles, - $project->getSubprojectPHIDs()); - $subproject_list = $table->render(); - } else { - $subproject_list = - '

    There are no projects attached for such specie.

    '; - } - - $viewer = $this->getRequest()->getUser(); $timestamp = phabricator_datetime($project->getDateCreated(), $viewer); - $status = PhabricatorProjectStatus::getNameForStatus( - $project->getStatus()); - $content = + $about = '
    -

    Basic Information

    +

    About

    - - - - @@ -185,20 +167,88 @@ class PhabricatorProjectProfileController '; - $content .= + if ($project->getSubprojectPHIDs()) { + $table = $this->renderSubprojectTable( + $handles, + $project->getSubprojectPHIDs()); + $subproject_list = $table->render(); + } else { + $subproject_list = '

    No subprojects.

    '; + } + + $about .= '
    '. - '

    Resources

    '. + '

    Subprojects

    '. + '
    '. + $subproject_list. + '
    '. + '
    '; + + return $about; + } + + private function renderPeoplePage( + PhabricatorProject $project, + PhabricatorProjectProfile $profile) { + + $affiliations = $project->loadAffiliations(); + + $phids = mpull($affiliations, 'getUserPHID'); + $handles = id(new PhabricatorObjectHandleData($phids)) + ->loadHandles(); + + $affiliated = array(); + foreach ($affiliations as $affiliation) { + $user = $handles[$affiliation->getUserPHID()]->renderLink(); + $role = phutil_escape_html($affiliation->getRole()); + $affiliated[] = '
  • '.$user.' — '.$role.'
  • '; + } + + if ($affiliated) { + $affiliated = '
      '.implode("\n", $affiliated).'
    '; + } else { + $affiliated = '

    No one is affiliated with this project.

    '; + } + + return + '
    '. + '

    People

    '. '
    '. $affiliated. '
    '. '
    '; + } - $content .= '
    '. - '

    Subprojects

    '. - '
    '. - $subproject_list. - '
    '. - '
    '; + private function renderFeedPage( + PhabricatorProject $project, + PhabricatorProjectProfile $profile) { + + $query = new PhabricatorFeedQuery(); + $query->setFilterPHIDs(array($project->getPHID())); + $stories = $query->execute(); + + if (!$stories) { + return 'There are no stories about this project.'; + } + + $query = new PhabricatorFeedQuery(); + $query->setFilterPHIDs( + array( + $project->getPHID(), + )); + $stories = $query->execute(); + + $builder = new PhabricatorFeedBuilder($stories); + $builder->setUser($this->getRequest()->getUser()); + $view = $builder->buildView(); + + return $view->render(); + } + + + private function renderTasksPage( + PhabricatorProject $project, + PhabricatorProjectProfile $profile) { $query = id(new ManiphestTaskQuery()) ->withProjects(array($project->getPHID())) @@ -238,7 +288,7 @@ class PhabricatorProjectProfileController ), "View All Open Tasks \xC2\xBB"); - $content .= + $content = '

    '. "Open Tasks ({$open})". diff --git a/src/applications/project/controller/profile/__init__.php b/src/applications/project/controller/profile/__init__.php index b9241382bc..e73f70338a 100644 --- a/src/applications/project/controller/profile/__init__.php +++ b/src/applications/project/controller/profile/__init__.php @@ -7,20 +7,24 @@ phutil_require_module('phabricator', 'aphront/response/404'); +phutil_require_module('phabricator', 'applications/feed/builder/feed'); +phutil_require_module('phabricator', 'applications/feed/query'); phutil_require_module('phabricator', 'applications/files/uri'); phutil_require_module('phabricator', 'applications/maniphest/query'); phutil_require_module('phabricator', 'applications/maniphest/view/tasksummary'); -phutil_require_module('phabricator', 'applications/markup/engine'); phutil_require_module('phabricator', 'applications/phid/handle/data'); -phutil_require_module('phabricator', 'applications/project/constants/status'); +phutil_require_module('phabricator', 'applications/phriction/storage/document'); phutil_require_module('phabricator', 'applications/project/controller/base'); phutil_require_module('phabricator', 'applications/project/storage/profile'); phutil_require_module('phabricator', 'applications/project/storage/project'); +phutil_require_module('phabricator', 'infrastructure/celerity/api'); phutil_require_module('phabricator', 'view/control/table'); -phutil_require_module('phabricator', 'view/layout/profile'); +phutil_require_module('phabricator', 'view/layout/profileheader'); +phutil_require_module('phabricator', 'view/layout/sidenavfilter'); phutil_require_module('phabricator', 'view/utils'); phutil_require_module('phutil', 'markup'); +phutil_require_module('phutil', 'parser/uri'); phutil_require_module('phutil', 'utils'); diff --git a/src/applications/project/controller/profileedit/PhabricatorProjectProfileEditController.php b/src/applications/project/controller/profileedit/PhabricatorProjectProfileEditController.php index 64e2a79f7b..d8f25d7822 100644 --- a/src/applications/project/controller/profileedit/PhabricatorProjectProfileEditController.php +++ b/src/applications/project/controller/profileedit/PhabricatorProjectProfileEditController.php @@ -89,11 +89,10 @@ class PhabricatorProjectProfileEditController $okay = $file->isTransformableImage(); if ($okay) { $xformer = new PhabricatorImageTransformer(); - $xformed = $xformer->executeProfileTransform( + $xformed = $xformer->executeThumbTransform( $file, - $width = 280, - $min_height = 140, - $max_height = 420); + $x = 50, + $y = 50); $profile->setProfileImagePHID($xformed->getPHID()); } else { $errors[] = diff --git a/src/view/layout/profileheader/PhabricatorProfileHeaderView.php b/src/view/layout/profileheader/PhabricatorProfileHeaderView.php new file mode 100644 index 0000000000..b1c4e667a4 --- /dev/null +++ b/src/view/layout/profileheader/PhabricatorProfileHeaderView.php @@ -0,0 +1,72 @@ +profilePicture = $picture; + return $this; + } + + public function setName($name) { + $this->profileName = $name; + return $this; + } + + public function setDescription($description) { + $this->profileDescription = $description; + return $this; + } + + public function render() { + require_celerity_resource('phabricator-profile-header-css'); + + $image = null; + if ($this->profilePicture) { + $image = phutil_render_tag( + 'div', + array( + 'class' => 'profile-header-picture-frame', + 'style' => 'background-image: url('.$this->profilePicture.');', + ), + ''); + } + + return + '

    Creator '.$handles[$project->getAuthorPHID()]->renderLink().'
    Status'.phutil_escape_html($status).'
    Created '.$timestamp.'
    + + + + + + + +
    '. + phutil_escape_html($this->profileName). + ''. + $image. + '
    '. + phutil_escape_html($this->profileDescription). + '
    '. + $this->renderChildren(); + } +} diff --git a/src/view/layout/profileheader/__init__.php b/src/view/layout/profileheader/__init__.php new file mode 100644 index 0000000000..ee060274a9 --- /dev/null +++ b/src/view/layout/profileheader/__init__.php @@ -0,0 +1,15 @@ +items[] = array('filter', $key, $name); + public function addFilter($key, $name, $uri = null) { + $this->items[] = array('filter', $key, $name, 'uri' => $uri); return $this; } @@ -63,11 +63,13 @@ final class AphrontSideNavFilterView extends AphrontView { public function selectFilter($key, $default) { $this->selectedFilter = $default; - foreach ($this->items as $item) { - if ($item[0] == 'filter') { - if ($item[1] == $key) { - $this->selectedFilter = $key; - break; + if ($key !== null) { + foreach ($this->items as $item) { + if ($item[0] == 'filter') { + if ($item[1] == $key) { + $this->selectedFilter = $key; + break; + } } } } @@ -101,9 +103,13 @@ final class AphrontSideNavFilterView extends AphrontView { ? 'aphront-side-nav-selected' : null; - $href = clone $this->baseURI; - $href->setPath($href->getPath().$key.'/'); - $href = (string)$href; + if (empty($item['uri'])) { + $href = clone $this->baseURI; + $href->setPath($href->getPath().$key.'/'); + $href = (string)$href; + } else { + $href = $item['uri']; + } $view->addNavItem( phutil_render_tag( diff --git a/webroot/rsrc/css/application/profile/profile-header-view.css b/webroot/rsrc/css/application/profile/profile-header-view.css new file mode 100644 index 0000000000..fc49bc87e4 --- /dev/null +++ b/webroot/rsrc/css/application/profile/profile-header-view.css @@ -0,0 +1,32 @@ +/** + * @provides phabricator-profile-header-css + */ + +.phabricator-profile-header { + background: #efefef; + width: 100%; + border-bottom: 1px solid #cccccc; +} + +.phabricator-profile-header .profile-header-name { + font-size: 22px; + font-weight: bold; + padding: 12px 12px 6px; + width: 100%; +} + +.phabricator-profile-header .profile-header-picture-frame { + margin: 11px; + width: 50px; + height: 50px; + position: relative; + + background: no-repeat; + border: 1px solid #ffffff; +} + +.phabricator-profile-header .profile-header-description { + padding: 0 12px 12px; + color: #444444; + font-size: 11px; +}