mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-26 08:42:41 +01:00
Project list and profile view modifications
Summary: Added some change on the project's list view, to show information about active tasks, population, etc. Also modified the "profile view", and added a class "PhabricatorProfileView" to render the profile, both on projects and users. Test Plan: play around the project directory :) Reviewers: epriestley ericfrenkiel CC: Differential Revision: 477
This commit is contained in:
parent
565cc43f27
commit
7851b6573f
27 changed files with 664 additions and 263 deletions
2
resources/sql/patches/047.projectstatus.sql
Normal file
2
resources/sql/patches/047.projectstatus.sql
Normal file
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE phabricator_project.project
|
||||
ADD status varchar(32) not null;
|
|
@ -63,7 +63,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'aphront-headsup-action-list-view-css' =>
|
||||
array(
|
||||
'uri' => '/res/c0ef93b6/rsrc/css/aphront/headsup-action-list-view.css',
|
||||
'uri' => '/res/af3dff49/rsrc/css/aphront/headsup-action-list-view.css',
|
||||
'type' => 'css',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -154,7 +154,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'differential-core-view-css' =>
|
||||
array(
|
||||
'uri' => '/res/dd6b4ca9/rsrc/css/application/differential/core.css',
|
||||
'uri' => '/res/438fe316/rsrc/css/application/differential/core.css',
|
||||
'type' => 'css',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -1048,12 +1048,12 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'phabricator-profile-css' =>
|
||||
array(
|
||||
'uri' => '/res/adcdb5f3/rsrc/css/application/people/profile.css',
|
||||
'uri' => '/res/4cb0251e/rsrc/css/application/profile/profile-view.css',
|
||||
'type' => 'css',
|
||||
'requires' =>
|
||||
array(
|
||||
),
|
||||
'disk' => '/rsrc/css/application/people/profile.css',
|
||||
'disk' => '/rsrc/css/application/profile/profile-view.css',
|
||||
),
|
||||
'phabricator-remarkup-css' =>
|
||||
array(
|
||||
|
@ -1156,23 +1156,6 @@ celerity_register_resource_map(array(
|
|||
'uri' => '/res/pkg/a452c449/core.pkg.css',
|
||||
'type' => 'css',
|
||||
),
|
||||
'c9226a80' =>
|
||||
array (
|
||||
'name' => 'differential.pkg.css',
|
||||
'symbols' =>
|
||||
array (
|
||||
0 => 'differential-core-view-css',
|
||||
1 => 'differential-changeset-view-css',
|
||||
2 => 'differential-revision-detail-css',
|
||||
3 => 'differential-revision-history-css',
|
||||
4 => 'differential-table-of-contents-css',
|
||||
5 => 'differential-revision-comment-css',
|
||||
6 => 'differential-revision-add-comment-css',
|
||||
7 => 'differential-revision-comment-list-css',
|
||||
),
|
||||
'uri' => '/res/pkg/c9226a80/differential.pkg.css',
|
||||
'type' => 'css',
|
||||
),
|
||||
'da416e1c' =>
|
||||
array (
|
||||
'name' => 'differential.pkg.js',
|
||||
|
@ -1222,6 +1205,23 @@ celerity_register_resource_map(array(
|
|||
'uri' => '/res/pkg/df91920b/workflow.pkg.js',
|
||||
'type' => 'js',
|
||||
),
|
||||
55967526 =>
|
||||
array (
|
||||
'name' => 'differential.pkg.css',
|
||||
'symbols' =>
|
||||
array (
|
||||
0 => 'differential-core-view-css',
|
||||
1 => 'differential-changeset-view-css',
|
||||
2 => 'differential-revision-detail-css',
|
||||
3 => 'differential-revision-history-css',
|
||||
4 => 'differential-table-of-contents-css',
|
||||
5 => 'differential-revision-comment-css',
|
||||
6 => 'differential-revision-add-comment-css',
|
||||
7 => 'differential-revision-comment-list-css',
|
||||
),
|
||||
'uri' => '/res/pkg/55967526/differential.pkg.css',
|
||||
'type' => 'css',
|
||||
),
|
||||
),
|
||||
'reverse' =>
|
||||
array (
|
||||
|
@ -1234,14 +1234,14 @@ celerity_register_resource_map(array(
|
|||
'aphront-table-view-css' => 'a452c449',
|
||||
'aphront-tokenizer-control-css' => 'a452c449',
|
||||
'aphront-typeahead-control-css' => 'a452c449',
|
||||
'differential-changeset-view-css' => 'c9226a80',
|
||||
'differential-core-view-css' => 'c9226a80',
|
||||
'differential-revision-add-comment-css' => 'c9226a80',
|
||||
'differential-revision-comment-css' => 'c9226a80',
|
||||
'differential-revision-comment-list-css' => 'c9226a80',
|
||||
'differential-revision-detail-css' => 'c9226a80',
|
||||
'differential-revision-history-css' => 'c9226a80',
|
||||
'differential-table-of-contents-css' => 'c9226a80',
|
||||
'differential-changeset-view-css' => '55967526',
|
||||
'differential-core-view-css' => '55967526',
|
||||
'differential-revision-add-comment-css' => '55967526',
|
||||
'differential-revision-comment-css' => '55967526',
|
||||
'differential-revision-comment-list-css' => '55967526',
|
||||
'differential-revision-detail-css' => '55967526',
|
||||
'differential-revision-history-css' => '55967526',
|
||||
'differential-table-of-contents-css' => '55967526',
|
||||
'diffusion-commit-view-css' => '03ef179e',
|
||||
'javelin-behavior' => 'db95a6d0',
|
||||
'javelin-behavior-aphront-basic-tokenizer' => '2892314d',
|
||||
|
|
|
@ -419,16 +419,19 @@ phutil_register_library_map(array(
|
|||
'PhabricatorPeopleProfileController' => 'applications/people/controller/profile',
|
||||
'PhabricatorPeopleProfileEditController' => 'applications/people/controller/profileedit',
|
||||
'PhabricatorPreferencesController' => 'applications/preferences/controller/base',
|
||||
'PhabricatorProfileView' => 'view/layout/profile',
|
||||
'PhabricatorProject' => 'applications/project/storage/project',
|
||||
'PhabricatorProjectAffiliation' => 'applications/project/storage/affiliation',
|
||||
'PhabricatorProjectAffiliationEditController' => 'applications/project/controller/editaffiliation',
|
||||
'PhabricatorProjectController' => 'applications/project/controller/base',
|
||||
'PhabricatorProjectDAO' => 'applications/project/storage/base',
|
||||
'PhabricatorProjectEditController' => 'applications/project/controller/edit',
|
||||
'PhabricatorProjectListController' => 'applications/project/controller/list',
|
||||
'PhabricatorProjectProfile' => 'applications/project/storage/profile',
|
||||
'PhabricatorProjectProfileController' => 'applications/project/controller/profile',
|
||||
'PhabricatorProjectProfileEditController' => 'applications/project/controller/profileedit',
|
||||
'PhabricatorProjectQuickCreateController' => 'applications/project/controller/quickcreate',
|
||||
'PhabricatorProjectStatus' => 'applications/project/constants/status',
|
||||
'PhabricatorProjectTransactionSearch' => 'applications/project/transactions/search',
|
||||
'PhabricatorRedirectController' => 'applications/base/controller/redirect',
|
||||
'PhabricatorRemarkupRuleDifferential' => 'infrastructure/markup/remarkup/markuprule/differential',
|
||||
'PhabricatorRemarkupRuleDiffusion' => 'infrastructure/markup/remarkup/markuprule/diffusion',
|
||||
|
@ -877,15 +880,16 @@ phutil_register_library_map(array(
|
|||
'PhabricatorPeopleProfileController' => 'PhabricatorPeopleController',
|
||||
'PhabricatorPeopleProfileEditController' => 'PhabricatorPeopleController',
|
||||
'PhabricatorPreferencesController' => 'PhabricatorController',
|
||||
'PhabricatorProfileView' => 'AphrontView',
|
||||
'PhabricatorProject' => 'PhabricatorProjectDAO',
|
||||
'PhabricatorProjectAffiliation' => 'PhabricatorProjectDAO',
|
||||
'PhabricatorProjectAffiliationEditController' => 'PhabricatorProjectController',
|
||||
'PhabricatorProjectController' => 'PhabricatorController',
|
||||
'PhabricatorProjectDAO' => 'PhabricatorLiskDAO',
|
||||
'PhabricatorProjectEditController' => 'PhabricatorProjectController',
|
||||
'PhabricatorProjectListController' => 'PhabricatorProjectController',
|
||||
'PhabricatorProjectProfile' => 'PhabricatorProjectDAO',
|
||||
'PhabricatorProjectProfileController' => 'PhabricatorProjectController',
|
||||
'PhabricatorProjectProfileEditController' => 'PhabricatorProjectController',
|
||||
'PhabricatorProjectQuickCreateController' => 'PhabricatorProjectController',
|
||||
'PhabricatorRedirectController' => 'PhabricatorController',
|
||||
'PhabricatorRemarkupRuleDifferential' => 'PhabricatorRemarkupRuleObjectName',
|
||||
|
|
|
@ -76,7 +76,8 @@ class AphrontDefaultApplicationConfiguration
|
|||
'edit/(?:(?P<id>\d+)/(?:(?P<view>\w+)/)?)?$'
|
||||
=> 'PhabricatorPeopleEditController',
|
||||
),
|
||||
'/p/(?P<username>\w+)/$' => 'PhabricatorPeopleProfileController',
|
||||
'/p/(?P<username>\w+)/(?:(?P<page>\w+)/)?$'
|
||||
=> 'PhabricatorPeopleProfileController',
|
||||
'/profile/' => array(
|
||||
'edit/$' => 'PhabricatorPeopleProfileEditController',
|
||||
),
|
||||
|
@ -196,8 +197,9 @@ class AphrontDefaultApplicationConfiguration
|
|||
|
||||
'/project/' => array(
|
||||
'$' => 'PhabricatorProjectListController',
|
||||
'edit/(?:(?P<id>\d+)/)?$' => 'PhabricatorProjectEditController',
|
||||
'view/(?P<id>\d+)/$' => 'PhabricatorProjectProfileController',
|
||||
'edit/(?:(?P<id>\d+)/)?$' => 'PhabricatorProjectProfileEditController',
|
||||
'view/(?P<id>\d+)/(?:(?P<page>\w+)/)?$'
|
||||
=> 'PhabricatorProjectProfileController',
|
||||
'affiliation/(?P<id>\d+)/$'
|
||||
=> 'PhabricatorProjectAffiliationEditController',
|
||||
'quickcreate/$' => 'PhabricatorProjectQuickCreateController',
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
phutil_require_module('phabricator', 'aphront/response/webpage');
|
||||
phutil_require_module('phabricator', 'applications/base/controller/base');
|
||||
phutil_require_module('phabricator', 'infrastructure/env');
|
||||
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
|
|
@ -19,9 +19,11 @@
|
|||
class PhabricatorPeopleProfileController extends PhabricatorPeopleController {
|
||||
|
||||
private $username;
|
||||
private $page;
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->username = $data['username'];
|
||||
$this->username = idx($data, 'username');
|
||||
$this->page = idx($data, 'page');
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
|
@ -83,44 +85,56 @@ class PhabricatorPeopleProfileController extends PhabricatorPeopleController {
|
|||
}
|
||||
}
|
||||
|
||||
foreach ($links as $k => $link) {
|
||||
$links[$k] = '<li>'.$link.'</li>';
|
||||
// TODO: perhaps, if someone wants to add to the profile of the user the
|
||||
// ability to show the task/revisions where he is working/commenting
|
||||
// on, this has to be changed to something like
|
||||
// |$this->page = key($pages)|, since the "page" regexp was added to
|
||||
// the aphrontconfiguration.
|
||||
if (empty($links[$this->page])) {
|
||||
$this->page = 'action';
|
||||
}
|
||||
$links =
|
||||
'<ul class="profile-nav-links">'.
|
||||
implode("\n", $links).
|
||||
'</ul>';
|
||||
|
||||
$title = nonempty($profile->getTitle(), 'Untitled Document');
|
||||
|
||||
$username_tag =
|
||||
'<h1 class="profile-username">'.
|
||||
phutil_escape_html($user->getUserName()).
|
||||
'</h1>';
|
||||
$realname_tag =
|
||||
'<h2 class="profile-realname">'.
|
||||
'('.phutil_escape_html($user->getRealName()).')'.
|
||||
'</h2>';
|
||||
$title_tag =
|
||||
'<h2 class="profile-usertitle">'.
|
||||
phutil_escape_html($title).
|
||||
'</h2>';
|
||||
switch ($this->page) {
|
||||
default:
|
||||
$content = $this->renderBasicInformation($user, $profile);
|
||||
break;
|
||||
}
|
||||
|
||||
$src_phid = $profile->getProfileImagePHID();
|
||||
if (!$src_phid) {
|
||||
$src_phid = $user->getProfileImagePHID();
|
||||
}
|
||||
$src = PhabricatorFileURI::getViewURIForPHID($src_phid);
|
||||
$picture = PhabricatorFileURI::getViewURIForPHID($src_phid);
|
||||
$title = nonempty($profile->getTitle(), 'Untitled Document');
|
||||
$realname = '('.$user->getRealName().')';
|
||||
|
||||
$picture = phutil_render_tag(
|
||||
'img',
|
||||
$profile = new PhabricatorProfileView();
|
||||
$profile->setProfilePicture($picture);
|
||||
$profile->setProfileNames(
|
||||
$user->getUserName(),
|
||||
$realname,
|
||||
$title);
|
||||
foreach ($links as $page => $name) {
|
||||
if (is_integer($page)) {
|
||||
$profile->addProfileItem(
|
||||
phutil_render_tag(
|
||||
'span',
|
||||
array(),
|
||||
$name));
|
||||
} else {
|
||||
$profile->addProfileItem($page);
|
||||
}
|
||||
}
|
||||
|
||||
$profile->appendChild($content);
|
||||
return $this->buildStandardPageResponse(
|
||||
$profile,
|
||||
array(
|
||||
'class' => 'profile-image',
|
||||
'src' => $src,
|
||||
'title' => $user->getUsername(),
|
||||
));
|
||||
}
|
||||
|
||||
require_celerity_resource('phabricator-profile-css');
|
||||
|
||||
private function renderBasicInformation($user, $profile) {
|
||||
$blurb = nonempty(
|
||||
$profile->getBlurb(),
|
||||
'//Nothing is known about this rare specimen.//');
|
||||
|
@ -158,30 +172,6 @@ class PhabricatorPeopleProfileController extends PhabricatorPeopleController {
|
|||
</div>
|
||||
</div>';
|
||||
|
||||
$profile =
|
||||
'<table class="phabricator-profile-master-layout">
|
||||
<tr>
|
||||
<td class="phabricator-profile-navigation">'.
|
||||
$username_tag.
|
||||
$realname_tag.
|
||||
$title_tag.
|
||||
'<hr />'.
|
||||
$picture.
|
||||
'<hr />'.
|
||||
$links.
|
||||
'<hr />'.
|
||||
'</td>
|
||||
<td class="phabricator-profile-content">'.
|
||||
$content.
|
||||
'</td>
|
||||
</tr>
|
||||
</table>';
|
||||
|
||||
return $this->buildStandardPageResponse(
|
||||
$profile,
|
||||
array(
|
||||
'title' => $user->getUsername(),
|
||||
));
|
||||
return $content;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ phutil_require_module('phabricator', 'applications/people/controller/base');
|
|||
phutil_require_module('phabricator', 'applications/people/storage/profile');
|
||||
phutil_require_module('phabricator', 'applications/people/storage/user');
|
||||
phutil_require_module('phabricator', 'applications/people/storage/useroauthinfo');
|
||||
phutil_require_module('phabricator', 'infrastructure/celerity/api');
|
||||
phutil_require_module('phabricator', 'view/layout/profile');
|
||||
phutil_require_module('phabricator', 'view/utils');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
|
|
|
@ -60,6 +60,7 @@ class PhabricatorPeopleProfileEditController
|
|||
}
|
||||
}
|
||||
|
||||
$error_view = null;
|
||||
if ($errors) {
|
||||
$error_view = new AphrontErrorView();
|
||||
$error_view->setTitle('Form Errors');
|
||||
|
@ -112,4 +113,4 @@ class PhabricatorPeopleProfileEditController
|
|||
));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
final class PhabricatorProjectStatus {
|
||||
|
||||
const UNKNOWN = 0;
|
||||
const NOT_STARTED = 1;
|
||||
const IN_PROGRESS = 2;
|
||||
const REVIEW_PROCESS = 3;
|
||||
const RELEASED = 4;
|
||||
const COMPLETED = 5;
|
||||
const DEFERRED = 6;
|
||||
const ONGOING = 7;
|
||||
|
||||
|
||||
public static function getNameForStatus($status) {
|
||||
static $map = array(
|
||||
self::UNKNOWN => 'Who knows?',
|
||||
self::NOT_STARTED => 'Not started',
|
||||
self::IN_PROGRESS => 'In progress',
|
||||
self::ONGOING => 'Ongoing',
|
||||
self::REVIEW_PROCESS => 'Review process',
|
||||
self::RELEASED => 'Released',
|
||||
self::COMPLETED => 'Completed',
|
||||
self::DEFERRED => 'Deferred',
|
||||
);
|
||||
|
||||
return idx($map, coalesce($status, '?'), $map[self::UNKNOWN]);
|
||||
}
|
||||
|
||||
public static function getStatusMap() {
|
||||
return array(
|
||||
self::UNKNOWN => 'Who knows?',
|
||||
self::NOT_STARTED => 'Not started',
|
||||
self::IN_PROGRESS => 'In progress',
|
||||
self::ONGOING => 'Ongoing',
|
||||
self::REVIEW_PROCESS => 'Review process',
|
||||
self::RELEASED => 'Released',
|
||||
self::COMPLETED => 'Completed',
|
||||
self::DEFERRED => 'Deferred',
|
||||
);
|
||||
}
|
||||
}
|
12
src/applications/project/constants/status/__init__.php
Normal file
12
src/applications/project/constants/status/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorProjectStatus.php');
|
|
@ -24,10 +24,50 @@ class PhabricatorProjectListController
|
|||
$projects = id(new PhabricatorProject())->loadAllWhere(
|
||||
'1 = 1 ORDER BY id DESC limit 100');
|
||||
|
||||
$author_phids = mpull($projects, 'getAuthorPHID');
|
||||
$handles = id(new PhabricatorObjectHandleData($author_phids))
|
||||
->loadHandles();
|
||||
|
||||
$rows = array();
|
||||
foreach ($projects as $project) {
|
||||
$documents = new PhabricatorProjectTransactionSearch($project->getPHID());
|
||||
// search all open documents by default
|
||||
$documents->setSearchOptions();
|
||||
$documents = $documents->executeSearch();
|
||||
|
||||
$documents_types = igroup($documents,'documentType');
|
||||
$tasks = idx(
|
||||
$documents_types,
|
||||
PhabricatorPHIDConstants::PHID_TYPE_TASK);
|
||||
$tasks_amount = count($tasks);
|
||||
|
||||
// TODO: set up a relationship between the project and the arcanist's
|
||||
// project, to be able get the revisions.
|
||||
$revisions = idx(
|
||||
$documents_types,
|
||||
PhabricatorPHIDConstants::PHID_TYPE_DREV);
|
||||
$revisions_amount = count($revisions);
|
||||
|
||||
$profile = $project->getProfile();
|
||||
$affiliations = $project->loadAffiliations();
|
||||
$population = count($affiliations);
|
||||
|
||||
$status = PhabricatorProjectStatus::getNameForStatus(
|
||||
$project->getStatus());
|
||||
|
||||
$blurb = nonempty(
|
||||
$profile->getBlurb(),
|
||||
'Oops!, nothing is known about this elusive project.');
|
||||
$blurb = $this->textWrap($blurb, $columns = 100);
|
||||
|
||||
$rows[] = array(
|
||||
phutil_escape_html($project->getName()),
|
||||
phutil_escape_html($blurb),
|
||||
$handles[$project->getAuthorPHID()]->renderLink(),
|
||||
phutil_escape_html($population),
|
||||
phutil_escape_html($status),
|
||||
phutil_escape_html($tasks_amount),
|
||||
// phutil_escape_html($revisions_amount),
|
||||
phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
|
@ -42,11 +82,23 @@ class PhabricatorProjectListController
|
|||
$table->setHeaders(
|
||||
array(
|
||||
'Project',
|
||||
'Blurb',
|
||||
'Mastermind',
|
||||
'Population',
|
||||
'Status',
|
||||
'Open Tasks',
|
||||
// 'Open Revisions',
|
||||
'',
|
||||
));
|
||||
$table->setColumnClasses(
|
||||
array(
|
||||
'pri',
|
||||
'wide',
|
||||
'',
|
||||
'right',
|
||||
'pri',
|
||||
'right',
|
||||
// 'right',
|
||||
'action',
|
||||
));
|
||||
|
||||
|
@ -62,4 +114,17 @@ class PhabricatorProjectListController
|
|||
));
|
||||
}
|
||||
|
||||
private function textWrap($text, $length) {
|
||||
if (strlen($text) <= $length) {
|
||||
return $text;
|
||||
} else {
|
||||
// TODO: perhaps this could be improved, adding the ability to get the
|
||||
// last letter and suppress it, if it is one of [(,:; ,etc.
|
||||
// making "blurb" looks a little bit better. :)
|
||||
$wrapped = wordwrap($text, $length, '__#END#__');
|
||||
$end_position = strpos($wrapped, '__#END#__');
|
||||
$wrapped = substr($text, 0, $end_position).'...';
|
||||
return $wrapped;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,12 @@
|
|||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'applications/phid/constants');
|
||||
phutil_require_module('phabricator', 'applications/phid/handle/data');
|
||||
phutil_require_module('phabricator', 'applications/project/constants/status');
|
||||
phutil_require_module('phabricator', 'applications/project/controller/base');
|
||||
phutil_require_module('phabricator', 'applications/project/storage/project');
|
||||
phutil_require_module('phabricator', 'applications/project/transactions/search');
|
||||
phutil_require_module('phabricator', 'view/control/table');
|
||||
phutil_require_module('phabricator', 'view/layout/panel');
|
||||
|
||||
|
|
|
@ -20,139 +20,168 @@ class PhabricatorProjectProfileController
|
|||
extends PhabricatorProjectController {
|
||||
|
||||
private $id;
|
||||
private $page;
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->id = $data['id'];
|
||||
$this->id = idx($data, 'id');
|
||||
$this->page = idx($data, 'page');
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
$uri = $request->getRequestURI();
|
||||
|
||||
$project = id(new PhabricatorProject())->load($this->id);
|
||||
if (!$project) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$profile = id(new PhabricatorProjectProfile())->loadOneWhere(
|
||||
'projectPHID = %s',
|
||||
$project->getPHID());
|
||||
$profile = $project->getProfile();
|
||||
if (!$profile) {
|
||||
$profile = new PhabricatorProjectProfile();
|
||||
}
|
||||
|
||||
require_celerity_resource('phabricator-profile-css');
|
||||
|
||||
$src_phid = $profile->getProfileImagePHID();
|
||||
$src = PhabricatorFileURI::getViewURIForPHID($src_phid);
|
||||
if (!$src_phid) {
|
||||
$src_phid = $user->getProfileImagePHID();
|
||||
}
|
||||
$picture = PhabricatorFileURI::getViewURIForPHID($src_phid);
|
||||
|
||||
$picture = phutil_render_tag(
|
||||
'img',
|
||||
array(
|
||||
'class' => 'profile-image',
|
||||
'src' => $src,
|
||||
));
|
||||
$pages = array(
|
||||
/*
|
||||
'<h2>Active Documents</h2>',
|
||||
'tasks' => 'Maniphest Tasks',
|
||||
'revisions' => 'Differential Revisions',
|
||||
'<hr />',
|
||||
'<h2>Workflow</h2>',
|
||||
'goals' => 'Goals',
|
||||
'statistics' => 'Statistics',
|
||||
'<hr />', */
|
||||
'<h2>Information</h2>',
|
||||
'edit' => 'Edit Profile',
|
||||
'affiliation' => 'Edit Affiliation',
|
||||
);
|
||||
|
||||
$links =
|
||||
'<ul class="profile-nav-links">'.
|
||||
'<li><a href="/project/edit/'.$project->getID().'/">'.
|
||||
'Edit Project</a></li>'.
|
||||
'<li><a href="/project/affiliation/'.$project->getID().'/">'.
|
||||
'Edit Affiliation</a></li>'.
|
||||
'</ul>';
|
||||
if (empty($pages[$this->page])) {
|
||||
$this->page = 'action'; // key($pages);
|
||||
}
|
||||
|
||||
$blurb = nonempty(
|
||||
$profile->getBlurb(),
|
||||
'//Nothing is known about this elusive project.//');
|
||||
switch ($this->page) {
|
||||
default:
|
||||
$content = $this->renderBasicInformation($project, $profile);
|
||||
break;
|
||||
}
|
||||
|
||||
$factory = new DifferentialMarkupEngineFactory();
|
||||
$engine = $factory->newDifferentialCommentMarkupEngine();
|
||||
$blurb = $engine->markupText($blurb);
|
||||
|
||||
|
||||
$affiliations = id(new PhabricatorProjectAffiliation())->loadAllWhere(
|
||||
'projectPHID = %s ORDER BY IF(status = "former", 1, 0), dateCreated',
|
||||
$project->getPHID());
|
||||
|
||||
$phids = array_merge(
|
||||
array($project->getAuthorPHID()),
|
||||
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());
|
||||
|
||||
$status = null;
|
||||
if ($affiliation->getStatus() == 'former') {
|
||||
$role = '<em>Former '.$role.'</em>';
|
||||
$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)));
|
||||
}
|
||||
|
||||
$affiliated[] = '<li>'.$user.' — '.$role.$status.'</li>';
|
||||
}
|
||||
if ($affiliated) {
|
||||
$affiliated = '<ul>'.implode("\n", $affiliated).'</ul>';
|
||||
} else {
|
||||
$affiliated = '<p><em>No one is affiliated with this project.</em></p>';
|
||||
}
|
||||
|
||||
$timestamp = phabricator_format_timestamp($project->getDateCreated());
|
||||
|
||||
$content =
|
||||
'<div class="phabricator-profile-info-group">
|
||||
<h1 class="phabricator-profile-info-header">Basic Information</h1>
|
||||
<div class="phabricator-profile-info-pane">
|
||||
<table class="phabricator-profile-info-table">
|
||||
<tr>
|
||||
<th>Creator</th>
|
||||
<td>'.$handles[$project->getAuthorPHID()]->renderLink().'</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Created</th>
|
||||
<td>'.$timestamp.'</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>PHID</th>
|
||||
<td>'.phutil_escape_html($project->getPHID()).'</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Blurb</th>
|
||||
<td>'.$blurb.'</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>';
|
||||
|
||||
$content .=
|
||||
'<div class="phabricator-profile-info-group">
|
||||
<h1 class="phabricator-profile-info-header">Resources</h1>
|
||||
<div class="phabricator-profile-info-pane">'.
|
||||
$affiliated.
|
||||
'</div>
|
||||
</div>';
|
||||
|
||||
|
||||
$profile_markup =
|
||||
'<table class="phabricator-profile-master-layout">
|
||||
<tr>
|
||||
<td class="phabricator-profile-navigation">'.
|
||||
'<h1>'.phutil_escape_html($project->getName()).'</h1>'.
|
||||
'<hr />'.
|
||||
$picture.
|
||||
'<hr />'.
|
||||
$links.
|
||||
'<hr />'.
|
||||
'</td>
|
||||
<td class="phabricator-profile-content">'.
|
||||
$content.
|
||||
'</td>
|
||||
</tr>
|
||||
</table>';
|
||||
$profile->appendChild($content);
|
||||
|
||||
return $this->buildStandardPageResponse(
|
||||
$profile_markup,
|
||||
$profile,
|
||||
array(
|
||||
'title' => $project->getName(),
|
||||
));
|
||||
));
|
||||
}
|
||||
|
||||
private function renderBasicInformation($project, $profile) {
|
||||
$blurb = nonempty(
|
||||
$profile->getBlurb(),
|
||||
'//Nothing is known about this elusive project.//');
|
||||
|
||||
$factory = new DifferentialMarkupEngineFactory();
|
||||
$engine = $factory->newDifferentialCommentMarkupEngine();
|
||||
$blurb = $engine->markupText($blurb);
|
||||
|
||||
$affiliations = $project->loadAffiliations();
|
||||
|
||||
$phids = array_merge(
|
||||
array($project->getAuthorPHID()),
|
||||
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());
|
||||
|
||||
$status = null;
|
||||
if ($affiliation->getStatus() == 'former') {
|
||||
$role = '<em>Former '.$role.'</em>';
|
||||
}
|
||||
|
||||
$affiliated[] = '<li>'.$user.' — '.$role.$status.'</li>';
|
||||
}
|
||||
if ($affiliated) {
|
||||
$affiliated = '<ul>'.implode("\n", $affiliated).'</ul>';
|
||||
} else {
|
||||
$affiliated = '<p><em>No one is affiliated with this project.</em></p>';
|
||||
}
|
||||
|
||||
$timestamp = phabricator_format_timestamp($project->getDateCreated());
|
||||
$status = PhabricatorProjectStatus::getNameForStatus(
|
||||
$project->getStatus());
|
||||
|
||||
$content =
|
||||
'<div class="phabricator-profile-info-group">
|
||||
<h1 class="phabricator-profile-info-header">Basic Information</h1>
|
||||
<div class="phabricator-profile-info-pane">
|
||||
<table class="phabricator-profile-info-table">
|
||||
<tr>
|
||||
<th>Creator</th>
|
||||
<td>'.$handles[$project->getAuthorPHID()]->renderLink().'</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Status</th>
|
||||
<td><strong>'.phutil_escape_html($status).'</strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Created</th>
|
||||
<td>'.$timestamp.'</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>PHID</th>
|
||||
<td>'.phutil_escape_html($project->getPHID()).'</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Blurb</th>
|
||||
<td>'.$blurb.'</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>';
|
||||
|
||||
$content .=
|
||||
'<div class="phabricator-profile-info-group">
|
||||
<h1 class="phabricator-profile-info-header">Resources</h1>
|
||||
<div class="phabricator-profile-info-pane">'.
|
||||
$affiliated.
|
||||
'</div>
|
||||
</div>';
|
||||
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,11 +10,11 @@ phutil_require_module('phabricator', 'aphront/response/404');
|
|||
phutil_require_module('phabricator', 'applications/differential/parser/markup');
|
||||
phutil_require_module('phabricator', 'applications/files/uri');
|
||||
phutil_require_module('phabricator', 'applications/phid/handle/data');
|
||||
phutil_require_module('phabricator', 'applications/project/constants/status');
|
||||
phutil_require_module('phabricator', 'applications/project/controller/base');
|
||||
phutil_require_module('phabricator', 'applications/project/storage/affiliation');
|
||||
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/layout/profile');
|
||||
phutil_require_module('phabricator', 'view/utils');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
class PhabricatorProjectEditController
|
||||
class PhabricatorProjectProfileEditController
|
||||
extends PhabricatorProjectController {
|
||||
|
||||
private $id;
|
||||
|
@ -35,9 +35,7 @@ class PhabricatorProjectEditController
|
|||
if (!$project) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$profile = id(new PhabricatorProjectProfile())->loadOneWhere(
|
||||
'projectPHID = %s',
|
||||
$project->getPHID());
|
||||
$profile = $project->getProfile();
|
||||
} else {
|
||||
$project = new PhabricatorProject();
|
||||
$project->setAuthorPHID($user->getPHID());
|
||||
|
@ -47,12 +45,13 @@ class PhabricatorProjectEditController
|
|||
$profile = new PhabricatorProjectProfile();
|
||||
}
|
||||
|
||||
$options = PhabricatorProjectStatus::getStatusMap();
|
||||
|
||||
$e_name = true;
|
||||
$errors = array();
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
|
||||
$project->setName($request->getStr('name'));
|
||||
$project->setStatus($request->getStr('status'));
|
||||
$profile->setBlurb($request->getStr('blurb'));
|
||||
|
||||
if (!strlen($project->getName())) {
|
||||
|
@ -62,6 +61,21 @@ class PhabricatorProjectEditController
|
|||
$e_name = null;
|
||||
}
|
||||
|
||||
if (!empty($_FILES['image'])) {
|
||||
$err = idx($_FILES['image'], 'error');
|
||||
if ($err != UPLOAD_ERR_NO_FILE) {
|
||||
$file = PhabricatorFile::newFromPHPUpload($_FILES['image']);
|
||||
$okay = $file->isTransformableImage();
|
||||
if ($okay) {
|
||||
$profile->setProfileImagePHID($file->getPHID());
|
||||
} else {
|
||||
$errors[] =
|
||||
'Only valid image files (jpg, jpeg, png or gif) '.
|
||||
'will be accepted.';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$errors) {
|
||||
$project->save();
|
||||
$profile->setProjectPHID($project->getPHID());
|
||||
|
@ -92,20 +106,32 @@ class PhabricatorProjectEditController
|
|||
$form
|
||||
->setUser($user)
|
||||
->setAction($action)
|
||||
->setEncType('multipart/form-data')
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel('Name')
|
||||
->setName('name')
|
||||
->setValue($project->getName())
|
||||
->setError($e_name))
|
||||
->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
->setLabel('Project Status')
|
||||
->setName('status')
|
||||
->setOptions($options)
|
||||
->setValue($project->getStatus()))
|
||||
->appendChild(
|
||||
id(new AphrontFormTextAreaControl())
|
||||
->setLabel('Blurb')
|
||||
->setName('blurb')
|
||||
->setValue($profile->getBlurb()))
|
||||
->appendChild(
|
||||
id(new AphrontFormFileControl())
|
||||
->setLabel('Change Image')
|
||||
->setName('image')
|
||||
->setCaption('Upload a 280px-wide image.'))
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->addCancelButton('/project/')
|
||||
->addCancelButton('/project/view/'.$project->getID().'/')
|
||||
->setValue('Save'));
|
||||
|
||||
$panel = new AphrontPanelView();
|
||||
|
@ -122,5 +148,4 @@ class PhabricatorProjectEditController
|
|||
'title' => $title,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
|
@ -8,10 +8,14 @@
|
|||
|
||||
phutil_require_module('phabricator', 'aphront/response/404');
|
||||
phutil_require_module('phabricator', 'aphront/response/redirect');
|
||||
phutil_require_module('phabricator', 'applications/files/storage/file');
|
||||
phutil_require_module('phabricator', 'applications/project/constants/status');
|
||||
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', 'view/form/base');
|
||||
phutil_require_module('phabricator', 'view/form/control/file');
|
||||
phutil_require_module('phabricator', 'view/form/control/select');
|
||||
phutil_require_module('phabricator', 'view/form/control/submit');
|
||||
phutil_require_module('phabricator', 'view/form/control/text');
|
||||
phutil_require_module('phabricator', 'view/form/control/textarea');
|
||||
|
@ -21,4 +25,4 @@ phutil_require_module('phabricator', 'view/layout/panel');
|
|||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorProjectEditController.php');
|
||||
phutil_require_source('PhabricatorProjectProfileEditController.php');
|
|
@ -28,10 +28,10 @@ class PhabricatorProjectQuickCreateController
|
|||
$project = new PhabricatorProject();
|
||||
$project->setAuthorPHID($user->getPHID());
|
||||
$profile = new PhabricatorProjectProfile();
|
||||
$options = PhabricatorProjectStatus::getStatusMap();
|
||||
|
||||
$e_name = true;
|
||||
$errors = array();
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
|
||||
$project->setName($request->getStr('name'));
|
||||
|
@ -46,7 +46,6 @@ class PhabricatorProjectQuickCreateController
|
|||
|
||||
if (!$errors) {
|
||||
$project->save();
|
||||
|
||||
$profile->setProjectPHID($project->getPHID());
|
||||
$profile->save();
|
||||
|
||||
|
@ -91,5 +90,4 @@ class PhabricatorProjectQuickCreateController
|
|||
|
||||
return id(new AphrontDialogResponse())->setDialog($dialog);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
phutil_require_module('phabricator', 'aphront/response/ajax');
|
||||
phutil_require_module('phabricator', 'aphront/response/dialog');
|
||||
phutil_require_module('phabricator', 'applications/project/constants/status');
|
||||
phutil_require_module('phabricator', 'applications/project/controller/base');
|
||||
phutil_require_module('phabricator', 'applications/project/storage/profile');
|
||||
phutil_require_module('phabricator', 'applications/project/storage/project');
|
||||
|
|
|
@ -23,12 +23,8 @@ class PhabricatorProjectProfile extends PhabricatorProjectDAO {
|
|||
protected $profileImagePHID;
|
||||
|
||||
public function getProfileImagePHID() {
|
||||
if ($this->profileImagePHID) {
|
||||
return $this->profileImagePHID;
|
||||
}
|
||||
// TODO: Make a separate one of these for projects.
|
||||
return PhabricatorEnv::getEnvConfig('user.default-profile-image-phid');
|
||||
return nonempty(
|
||||
$this->profileImagePHID,
|
||||
PhabricatorEnv::getEnvConfig('user.default-profile-image-phid'));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -9,5 +9,7 @@
|
|||
phutil_require_module('phabricator', 'applications/project/storage/base');
|
||||
phutil_require_module('phabricator', 'infrastructure/env');
|
||||
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorProjectProfile.php');
|
||||
|
|
|
@ -20,6 +20,7 @@ class PhabricatorProject extends PhabricatorProjectDAO {
|
|||
|
||||
protected $name;
|
||||
protected $phid;
|
||||
protected $status = PhabricatorProjectStatus::UNKNOWN;
|
||||
protected $authorPHID;
|
||||
|
||||
public function getConfiguration() {
|
||||
|
@ -33,4 +34,17 @@ class PhabricatorProject extends PhabricatorProjectDAO {
|
|||
PhabricatorPHIDConstants::PHID_TYPE_PROJ);
|
||||
}
|
||||
|
||||
public function getProfile() {
|
||||
$profile = id(new PhabricatorProjectProfile())->loadOneWhere(
|
||||
'projectPHID = %s',
|
||||
$this->getPHID());
|
||||
return $profile;
|
||||
}
|
||||
|
||||
public function loadAffiliations() {
|
||||
$affiliations = id(new PhabricatorProjectAffiliation())->loadAllWhere(
|
||||
'projectPHID = %s ORDER BY IF(status = "former", 1, 0), dateCreated',
|
||||
$this->getPHID());
|
||||
return $affiliations;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,12 @@
|
|||
|
||||
phutil_require_module('phabricator', 'applications/phid/constants');
|
||||
phutil_require_module('phabricator', 'applications/phid/storage/phid');
|
||||
phutil_require_module('phabricator', 'applications/project/constants/status');
|
||||
phutil_require_module('phabricator', 'applications/project/storage/affiliation');
|
||||
phutil_require_module('phabricator', 'applications/project/storage/base');
|
||||
phutil_require_module('phabricator', 'applications/project/storage/profile');
|
||||
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorProject.php');
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
class PhabricatorProjectTransactionSearch {
|
||||
private $projectPhids;
|
||||
private $documents;
|
||||
private $status;
|
||||
|
||||
public function __construct($project_phids) {
|
||||
if (is_array($project_phids)) {
|
||||
$this->projectPhids = $project_phids;
|
||||
} else {
|
||||
$this->projectPhids = array($project_phids);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
// search all open documents by default
|
||||
public function setSearchOptions($documents = '', $status = true) {
|
||||
$this->documents = $documents;
|
||||
$this->status = $status;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function executeSearch() {
|
||||
$projects = $this->projectPhids;
|
||||
$on_documents = $this->documents;
|
||||
$with_status = $this->status;
|
||||
|
||||
$query = new PhabricatorSearchQuery();
|
||||
$query->setQuery('');
|
||||
$query->setParameter('project', $projects);
|
||||
$query->setParameter('type', $on_documents);
|
||||
$query->setParameter('open', $with_status);
|
||||
|
||||
$executor = new PhabricatorSearchMySQLExecutor();
|
||||
$results = $executor->executeSearch($query);
|
||||
return $results;
|
||||
}
|
||||
}
|
13
src/applications/project/transactions/search/__init__.php
Normal file
13
src/applications/project/transactions/search/__init__.php
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'applications/search/execute/mysql');
|
||||
phutil_require_module('phabricator', 'applications/search/storage/query');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorProjectTransactionSearch.php');
|
93
src/view/layout/profile/PhabricatorProfileView.php
Normal file
93
src/view/layout/profile/PhabricatorProfileView.php
Normal file
|
@ -0,0 +1,93 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
final class PhabricatorProfileView extends AphrontView {
|
||||
|
||||
protected $items = array();
|
||||
protected $profilePicture;
|
||||
protected $profileName;
|
||||
protected $profileRealname;
|
||||
protected $profileTitle;
|
||||
|
||||
public function addProfileItem($item) {
|
||||
$this->items[] = $item;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setProfilePicture($picture) {
|
||||
$this->profilePicture = $picture;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setProfileNames($name, $realname = null, $title = null) {
|
||||
$this->profileName = $name;
|
||||
$this->profileRealname = $realname;
|
||||
$this->profileTitle = $title;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$view = new AphrontNullView();
|
||||
$view->appendChild($this->items);
|
||||
|
||||
$side_links = null;
|
||||
$realname = null;
|
||||
$title = null;
|
||||
if (!empty($this->profileRealname)) {
|
||||
$realname =
|
||||
'<h2 class="phabricator-profile-realname">'.
|
||||
phutil_escape_html($this->profileRealname).
|
||||
'</h2>';
|
||||
}
|
||||
|
||||
if (!empty($this->profileTitle)) {
|
||||
$title =
|
||||
'<h2>'.
|
||||
phutil_escape_html($this->profileTitle).
|
||||
'</h2>';
|
||||
}
|
||||
|
||||
if (!empty($this->items)) {
|
||||
$side_links =
|
||||
$view->render().
|
||||
'<hr />';
|
||||
}
|
||||
|
||||
require_celerity_resource('phabricator-profile-css');
|
||||
|
||||
return
|
||||
'<table class="phabricator-profile-master-layout">'.
|
||||
'<tr>'.
|
||||
'<td class="phabricator-profile-navigation">'.
|
||||
'<h1>'.phutil_escape_html($this->profileName).'</h1>'.
|
||||
$realname.
|
||||
$title.
|
||||
'<hr />'.
|
||||
'<img class="phabricator-profile-image" src="'.
|
||||
$this->profilePicture.
|
||||
'"/>'.
|
||||
'<hr />'.
|
||||
$side_links.
|
||||
'</td>'.
|
||||
'<td class="phabricator-profile-content">'.
|
||||
$this->renderChildren().
|
||||
'</td>'.
|
||||
'</tr>'.
|
||||
'</table>';
|
||||
}
|
||||
}
|
16
src/view/layout/profile/__init__.php
Normal file
16
src/view/layout/profile/__init__.php
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'infrastructure/celerity/api');
|
||||
phutil_require_module('phabricator', 'view/base');
|
||||
phutil_require_module('phabricator', 'view/null');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorProfileView.php');
|
|
@ -2,20 +2,72 @@
|
|||
* @provides phabricator-profile-css
|
||||
*/
|
||||
|
||||
.phabricator-profile-master-layout {
|
||||
table.phabricator-profile-master-layout {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.phabricator-profile-navigation {
|
||||
td.phabricator-profile-navigation {
|
||||
width: 300px;
|
||||
background: #efefef;
|
||||
border-right: 1px solid #cccccc;
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8em;
|
||||
}
|
||||
|
||||
.phabricator-profile-content {
|
||||
td.phabricator-profile-navigation a,
|
||||
td.phabricator-profile-navigation span {
|
||||
display: block;
|
||||
margin: 0 0 2px;
|
||||
min-width: 150px;
|
||||
font-weight: bold;
|
||||
white-space: nowrap;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
td.phabricator-profile-navigation a {
|
||||
padding: 4px 8px 4px 10px;
|
||||
}
|
||||
|
||||
td.phabricator-profile-navigation a:hover {
|
||||
text-decoration: none;
|
||||
background: #cccccc;
|
||||
}
|
||||
|
||||
td.phabricator-profile-navigation a.phabricator-profile-item-selected,
|
||||
td.phabricator-profile-navigation a.phabricator-profile-item-selected :hover {
|
||||
background: #cccccc;
|
||||
}
|
||||
|
||||
td.phabricator-profile-navigation hr {
|
||||
border: none;
|
||||
background: #cccccc;
|
||||
padding: 0;
|
||||
margin: 10px 0;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
td.phabricator-profile-navigation h1,
|
||||
td.phabricator-profile-navigation h2 {
|
||||
padding: 2px 0px 0px 10px;
|
||||
}
|
||||
|
||||
td.phabricator-profile-content {
|
||||
padding: 2em 2%;
|
||||
}
|
||||
|
||||
.phabricator-profile-info-table th {
|
||||
font-weight: bold;
|
||||
text-align: right;
|
||||
color: #666666;
|
||||
width: 10%;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.phabricator-profile-info-table td {
|
||||
width: 100%;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.phabricator-profile-info-group {
|
||||
margin-bottom: 2em;
|
||||
background: #efefef;
|
||||
|
@ -35,52 +87,11 @@
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
.phabricator-profile-info-table th {
|
||||
font-weight: bold;
|
||||
text-align: right;
|
||||
color: #666666;
|
||||
width: 10%;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.phabricator-profile-info-table td {
|
||||
width: 100%;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.phabricator-profile-navigation hr {
|
||||
border: none;
|
||||
background: #cccccc;
|
||||
padding: 0;
|
||||
margin: 10px 0;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
.phabricator-profile-navigation {
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8em;
|
||||
}
|
||||
|
||||
.phabricator-profile-navigation h1,
|
||||
.phabricator-profile-navigation h2 {
|
||||
padding: 2px 8px;
|
||||
}
|
||||
|
||||
h2.profile-realname {
|
||||
h2.phabricator-profile-realname {
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
img.profile-image {
|
||||
img.phabricator-profile-image {
|
||||
width: 280px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
ul.profile-nav-links li a {
|
||||
display: block;
|
||||
padding: 4px 8px 4px 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
ul.profile-nav-links li a:hover {
|
||||
background: #cccccc;
|
||||
}
|
Loading…
Reference in a new issue