mirror of
https://we.phorge.it/source/phorge.git
synced 2025-02-24 20:49:06 +01:00
(stable) Promote 2019 Week 44
This commit is contained in:
commit
7585b1212b
22 changed files with 696 additions and 185 deletions
|
@ -9,10 +9,10 @@ return array(
|
|||
'names' => array(
|
||||
'conpherence.pkg.css' => '3c8a0668',
|
||||
'conpherence.pkg.js' => '020aebcf',
|
||||
'core.pkg.css' => '686ae87c',
|
||||
'core.pkg.css' => '77de226f',
|
||||
'core.pkg.js' => '6e5c894f',
|
||||
'differential.pkg.css' => '607c84be',
|
||||
'differential.pkg.js' => 'a0212a0b',
|
||||
'differential.pkg.js' => '1b97518d',
|
||||
'diffusion.pkg.css' => '42c75c37',
|
||||
'diffusion.pkg.js' => 'a98c0bf7',
|
||||
'maniphest.pkg.css' => '35995d6d',
|
||||
|
@ -30,7 +30,7 @@ return array(
|
|||
'rsrc/css/aphront/notification.css' => '30240bd2',
|
||||
'rsrc/css/aphront/panel-view.css' => '46923d46',
|
||||
'rsrc/css/aphront/phabricator-nav-view.css' => 'f8a0c1bf',
|
||||
'rsrc/css/aphront/table-view.css' => '5f13a9e4',
|
||||
'rsrc/css/aphront/table-view.css' => '0bb61df1',
|
||||
'rsrc/css/aphront/tokenizer.css' => 'b52d0668',
|
||||
'rsrc/css/aphront/tooltip.css' => 'e3f2412f',
|
||||
'rsrc/css/aphront/typeahead-browse.css' => 'b7ed02d2',
|
||||
|
@ -428,7 +428,7 @@ return array(
|
|||
'rsrc/js/application/releeph/releeph-preview-branch.js' => '75184d68',
|
||||
'rsrc/js/application/releeph/releeph-request-state-change.js' => '9f081f05',
|
||||
'rsrc/js/application/releeph/releeph-request-typeahead.js' => 'aa3a100c',
|
||||
'rsrc/js/application/repository/repository-crossreference.js' => 'c15122b4',
|
||||
'rsrc/js/application/repository/repository-crossreference.js' => '1c95ea63',
|
||||
'rsrc/js/application/search/behavior-reorder-profile-menu-items.js' => 'e5bdb730',
|
||||
'rsrc/js/application/search/behavior-reorder-queries.js' => 'b86f297f',
|
||||
'rsrc/js/application/transactions/behavior-comment-actions.js' => '4dffaeb2',
|
||||
|
@ -535,7 +535,7 @@ return array(
|
|||
'aphront-list-filter-view-css' => 'feb64255',
|
||||
'aphront-multi-column-view-css' => 'fbc00ba3',
|
||||
'aphront-panel-view-css' => '46923d46',
|
||||
'aphront-table-view-css' => '5f13a9e4',
|
||||
'aphront-table-view-css' => '0bb61df1',
|
||||
'aphront-tokenizer-control-css' => 'b52d0668',
|
||||
'aphront-tooltip-css' => 'e3f2412f',
|
||||
'aphront-typeahead-control-css' => '8779483d',
|
||||
|
@ -682,7 +682,7 @@ return array(
|
|||
'javelin-behavior-reorder-applications' => 'aa371860',
|
||||
'javelin-behavior-reorder-columns' => '8ac32fd9',
|
||||
'javelin-behavior-reorder-profile-menu-items' => 'e5bdb730',
|
||||
'javelin-behavior-repository-crossreference' => 'c15122b4',
|
||||
'javelin-behavior-repository-crossreference' => '1c95ea63',
|
||||
'javelin-behavior-scrollbar' => '92388bae',
|
||||
'javelin-behavior-search-reorder-queries' => 'b86f297f',
|
||||
'javelin-behavior-select-content' => 'e8240b50',
|
||||
|
@ -1034,6 +1034,12 @@ return array(
|
|||
'javelin-install',
|
||||
'javelin-util',
|
||||
),
|
||||
'1c95ea63' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-dom',
|
||||
'javelin-stratcom',
|
||||
'javelin-uri',
|
||||
),
|
||||
'1cab0e9a' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-dom',
|
||||
|
@ -1977,12 +1983,6 @@ return array(
|
|||
'c03f2fb4' => array(
|
||||
'javelin-install',
|
||||
),
|
||||
'c15122b4' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-dom',
|
||||
'javelin-stratcom',
|
||||
'javelin-uri',
|
||||
),
|
||||
'c2c500a7' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
|
||||
PhabricatorRebuildIndexesWorker::rebuildObjectsWithQuery(
|
||||
'PhabricatorRepositoryQuery');
|
|
@ -1338,6 +1338,8 @@ phutil_register_library_map(array(
|
|||
'HarbormasterArcLintBuildStepImplementation' => 'applications/harbormaster/step/HarbormasterArcLintBuildStepImplementation.php',
|
||||
'HarbormasterArcUnitBuildStepImplementation' => 'applications/harbormaster/step/HarbormasterArcUnitBuildStepImplementation.php',
|
||||
'HarbormasterArtifact' => 'applications/harbormaster/artifact/HarbormasterArtifact.php',
|
||||
'HarbormasterArtifactSearchConduitAPIMethod' => 'applications/harbormaster/conduit/HarbormasterArtifactSearchConduitAPIMethod.php',
|
||||
'HarbormasterArtifactSearchEngine' => 'applications/harbormaster/query/HarbormasterArtifactSearchEngine.php',
|
||||
'HarbormasterAutotargetsTestCase' => 'applications/harbormaster/__tests__/HarbormasterAutotargetsTestCase.php',
|
||||
'HarbormasterBuild' => 'applications/harbormaster/storage/build/HarbormasterBuild.php',
|
||||
'HarbormasterBuildAbortedException' => 'applications/harbormaster/exception/HarbormasterBuildAbortedException.php',
|
||||
|
@ -4650,6 +4652,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorSearchHovercardController' => 'applications/search/controller/PhabricatorSearchHovercardController.php',
|
||||
'PhabricatorSearchIndexVersion' => 'applications/search/storage/PhabricatorSearchIndexVersion.php',
|
||||
'PhabricatorSearchIndexVersionDestructionEngineExtension' => 'applications/search/engineextension/PhabricatorSearchIndexVersionDestructionEngineExtension.php',
|
||||
'PhabricatorSearchIntField' => 'applications/search/field/PhabricatorSearchIntField.php',
|
||||
'PhabricatorSearchManagementIndexWorkflow' => 'applications/search/management/PhabricatorSearchManagementIndexWorkflow.php',
|
||||
'PhabricatorSearchManagementInitWorkflow' => 'applications/search/management/PhabricatorSearchManagementInitWorkflow.php',
|
||||
'PhabricatorSearchManagementNgramsWorkflow' => 'applications/search/management/PhabricatorSearchManagementNgramsWorkflow.php',
|
||||
|
@ -7369,6 +7372,8 @@ phutil_register_library_map(array(
|
|||
'HarbormasterArcLintBuildStepImplementation' => 'HarbormasterBuildStepImplementation',
|
||||
'HarbormasterArcUnitBuildStepImplementation' => 'HarbormasterBuildStepImplementation',
|
||||
'HarbormasterArtifact' => 'Phobject',
|
||||
'HarbormasterArtifactSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
|
||||
'HarbormasterArtifactSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'HarbormasterAutotargetsTestCase' => 'PhabricatorTestCase',
|
||||
'HarbormasterBuild' => array(
|
||||
'HarbormasterDAO',
|
||||
|
@ -7384,6 +7389,7 @@ phutil_register_library_map(array(
|
|||
'HarbormasterDAO',
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorDestructibleInterface',
|
||||
'PhabricatorConduitResultInterface',
|
||||
),
|
||||
'HarbormasterBuildArtifactPHIDType' => 'PhabricatorPHIDType',
|
||||
'HarbormasterBuildArtifactQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
|
@ -11268,6 +11274,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorSearchHovercardController' => 'PhabricatorSearchBaseController',
|
||||
'PhabricatorSearchIndexVersion' => 'PhabricatorSearchDAO',
|
||||
'PhabricatorSearchIndexVersionDestructionEngineExtension' => 'PhabricatorDestructionEngineExtension',
|
||||
'PhabricatorSearchIntField' => 'PhabricatorSearchField',
|
||||
'PhabricatorSearchManagementIndexWorkflow' => 'PhabricatorSearchManagementWorkflow',
|
||||
'PhabricatorSearchManagementInitWorkflow' => 'PhabricatorSearchManagementWorkflow',
|
||||
'PhabricatorSearchManagementNgramsWorkflow' => 'PhabricatorSearchManagementWorkflow',
|
||||
|
|
|
@ -44,15 +44,6 @@ final class DifferentialRevisionPHIDType extends PhabricatorPHIDType {
|
|||
if ($revision->isClosed()) {
|
||||
$handle->setStatus(PhabricatorObjectHandle::STATUS_CLOSED);
|
||||
}
|
||||
|
||||
$icon = $revision->getStatusIcon();
|
||||
$color = $revision->getStatusIconColor();
|
||||
$name = $revision->getStatusDisplayName();
|
||||
|
||||
$handle
|
||||
->setStateIcon($icon)
|
||||
->setStateColor($color)
|
||||
->setStateName($name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,20 +26,45 @@ final class DiffusionHovercardEngineExtension
|
|||
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$author_phid = $commit->getAuthorPHID();
|
||||
if ($author_phid) {
|
||||
$author = $viewer->renderHandle($author_phid);
|
||||
} else {
|
||||
$commit_data = $commit->loadCommitData();
|
||||
$author = phutil_tag('em', array(), $commit_data->getAuthorName());
|
||||
$commit = id(new DiffusionCommitQuery())
|
||||
->setViewer($viewer)
|
||||
->needIdentities(true)
|
||||
->needCommitData(true)
|
||||
->withPHIDs(array($commit->getPHID()))
|
||||
->executeOne();
|
||||
if (!$commit) {
|
||||
return;
|
||||
}
|
||||
|
||||
$author_phid = $commit->getAuthorDisplayPHID();
|
||||
$committer_phid = $commit->getCommitterDisplayPHID();
|
||||
$repository_phid = $commit->getRepository()->getPHID();
|
||||
|
||||
$phids = array();
|
||||
$phids[] = $author_phid;
|
||||
$phids[] = $committer_phid;
|
||||
$phids[] = $repository_phid;
|
||||
|
||||
$handles = $viewer->loadHandles($phids);
|
||||
|
||||
$hovercard->setTitle($handle->getName());
|
||||
$hovercard->setDetail($commit->getSummary());
|
||||
|
||||
$repository = $handles[$repository_phid]->renderLink();
|
||||
$hovercard->addField(pht('Repository'), $repository);
|
||||
|
||||
$author = $handles[$author_phid]->renderLink();
|
||||
if ($author_phid) {
|
||||
$hovercard->addField(pht('Author'), $author);
|
||||
$hovercard->addField(pht('Date'),
|
||||
phabricator_date($commit->getEpoch(), $viewer));
|
||||
}
|
||||
|
||||
if ($committer_phid && ($committer_phid !== $author_phid)) {
|
||||
$committer = $handles[$committer_phid]->renderLink();
|
||||
$hovercard->addField(pht('Committer'), $committer);
|
||||
}
|
||||
|
||||
$date = phabricator_date($commit->getEpoch(), $viewer);
|
||||
$hovercard->addField(pht('Date'), $date);
|
||||
|
||||
if (!$commit->isAuditStatusNoAudit()) {
|
||||
$status = $commit->getAuditStatusObject();
|
||||
|
|
|
@ -29,6 +29,7 @@ final class PhabricatorFactChartFunction
|
|||
$key_id = id(new PhabricatorFactKeyDimension())
|
||||
->newDimensionID($fact->getKey());
|
||||
if (!$key_id) {
|
||||
$this->map = array();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
final class HarbormasterArtifactSearchConduitAPIMethod
|
||||
extends PhabricatorSearchEngineAPIMethod {
|
||||
|
||||
public function getAPIMethodName() {
|
||||
return 'harbormaster.artifact.search';
|
||||
}
|
||||
|
||||
public function newSearchEngine() {
|
||||
return new HarbormasterArtifactSearchEngine();
|
||||
}
|
||||
|
||||
public function getMethodSummary() {
|
||||
return pht('Query information about build artifacts.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
<?php
|
||||
|
||||
final class HarbormasterArtifactSearchEngine
|
||||
extends PhabricatorApplicationSearchEngine {
|
||||
|
||||
public function getResultTypeDescription() {
|
||||
return pht('Harbormaster Artifacts');
|
||||
}
|
||||
|
||||
public function getApplicationClassName() {
|
||||
return 'PhabricatorHarbormasterApplication';
|
||||
}
|
||||
|
||||
public function newQuery() {
|
||||
return new HarbormasterBuildArtifactQuery();
|
||||
}
|
||||
|
||||
protected function buildCustomSearchFields() {
|
||||
return array(
|
||||
id(new PhabricatorPHIDsSearchField())
|
||||
->setLabel(pht('Targets'))
|
||||
->setKey('buildTargetPHIDs')
|
||||
->setAliases(
|
||||
array(
|
||||
'buildTargetPHID',
|
||||
'buildTargets',
|
||||
'buildTarget',
|
||||
'targetPHIDs',
|
||||
'targetPHID',
|
||||
'targets',
|
||||
'target',
|
||||
))
|
||||
->setDescription(
|
||||
pht('Search for artifacts attached to particular build targets.')),
|
||||
);
|
||||
}
|
||||
|
||||
protected function buildQueryFromParameters(array $map) {
|
||||
$query = $this->newQuery();
|
||||
|
||||
if ($map['buildTargetPHIDs']) {
|
||||
$query->withBuildTargetPHIDs($map['buildTargetPHIDs']);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
protected function getURI($path) {
|
||||
return '/harbormaster/artifact/'.$path;
|
||||
}
|
||||
|
||||
protected function getBuiltinQueryNames() {
|
||||
return array(
|
||||
'all' => pht('All Artifacts'),
|
||||
);
|
||||
}
|
||||
|
||||
public function buildSavedQueryFromBuiltin($query_key) {
|
||||
$query = $this->newSavedQuery();
|
||||
$query->setQueryKey($query_key);
|
||||
|
||||
switch ($query_key) {
|
||||
case 'all':
|
||||
return $query;
|
||||
}
|
||||
|
||||
return parent::buildSavedQueryFromBuiltin($query_key);
|
||||
}
|
||||
|
||||
protected function renderResultList(
|
||||
array $artifacts,
|
||||
PhabricatorSavedQuery $query,
|
||||
array $handles) {
|
||||
assert_instances_of($artifacts, 'HarbormasterBuildArtifact');
|
||||
|
||||
$viewer = $this->requireViewer();
|
||||
|
||||
$list = new PHUIObjectItemListView();
|
||||
foreach ($artifacts as $artifact) {
|
||||
$id = $artifact->getID();
|
||||
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setObjectName(pht('Artifact %d', $id));
|
||||
|
||||
$list->addItem($item);
|
||||
}
|
||||
|
||||
return id(new PhabricatorApplicationSearchResultView())
|
||||
->setObjectList($list)
|
||||
->setNoDataString(pht('No artifacts found.'));
|
||||
}
|
||||
|
||||
}
|
|
@ -4,7 +4,8 @@ final class HarbormasterBuildArtifact
|
|||
extends HarbormasterDAO
|
||||
implements
|
||||
PhabricatorPolicyInterface,
|
||||
PhabricatorDestructibleInterface {
|
||||
PhabricatorDestructibleInterface,
|
||||
PhabricatorConduitResultInterface {
|
||||
|
||||
protected $buildTargetPHID;
|
||||
protected $artifactType;
|
||||
|
@ -18,6 +19,7 @@ final class HarbormasterBuildArtifact
|
|||
|
||||
public static function initializeNewBuildArtifact(
|
||||
HarbormasterBuildTarget $build_target) {
|
||||
|
||||
return id(new HarbormasterBuildArtifact())
|
||||
->attachBuildTarget($build_target)
|
||||
->setBuildTargetPHID($build_target->getPHID());
|
||||
|
@ -53,9 +55,8 @@ final class HarbormasterBuildArtifact
|
|||
) + parent::getConfiguration();
|
||||
}
|
||||
|
||||
public function generatePHID() {
|
||||
return PhabricatorPHID::generateNewPHID(
|
||||
HarbormasterBuildArtifactPHIDType::TYPECONST);
|
||||
public function getPHIDType() {
|
||||
return HarbormasterBuildArtifactPHIDType::TYPECONST;
|
||||
}
|
||||
|
||||
public function attachBuildTarget(HarbormasterBuildTarget $build_target) {
|
||||
|
@ -147,7 +148,8 @@ final class HarbormasterBuildArtifact
|
|||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return pht('Users must be able to see a buildable to see its artifacts.');
|
||||
return pht(
|
||||
'Users must be able to see a build target to see its artifacts.');
|
||||
}
|
||||
|
||||
|
||||
|
@ -165,4 +167,40 @@ final class HarbormasterBuildArtifact
|
|||
$this->saveTransaction();
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorConduitResultInterface )---------------------------------- */
|
||||
|
||||
public function getFieldSpecificationsForConduit() {
|
||||
return array(
|
||||
id(new PhabricatorConduitSearchFieldSpecification())
|
||||
->setKey('buildTargetPHID')
|
||||
->setType('phid')
|
||||
->setDescription(pht('The build target this artifact is attached to.')),
|
||||
id(new PhabricatorConduitSearchFieldSpecification())
|
||||
->setKey('artifactType')
|
||||
->setType('string')
|
||||
->setDescription(pht('The artifact type.')),
|
||||
id(new PhabricatorConduitSearchFieldSpecification())
|
||||
->setKey('artifactKey')
|
||||
->setType('string')
|
||||
->setDescription(pht('The artifact key.')),
|
||||
id(new PhabricatorConduitSearchFieldSpecification())
|
||||
->setKey('isReleased')
|
||||
->setType('bool')
|
||||
->setDescription(pht('True if this artifact has been released.')),
|
||||
);
|
||||
}
|
||||
|
||||
public function getFieldValuesForConduit() {
|
||||
return array(
|
||||
'buildTargetPHID' => $this->getBuildTargetPHID(),
|
||||
'artifactType' => $this->getArtifactType(),
|
||||
'artifactKey' => $this->getArtifactKey(),
|
||||
'isReleased' => (bool)$this->getIsReleased(),
|
||||
);
|
||||
}
|
||||
|
||||
public function getConduitSearchAttachments() {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -179,11 +179,14 @@ final class ManiphestTaskDetailController extends ManiphestController {
|
|||
->addTabGroup($tab_group);
|
||||
}
|
||||
|
||||
$changes_view = $this->newChangesView($task, $edges);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setCurtain($curtain)
|
||||
->setMainColumn(
|
||||
array(
|
||||
$changes_view,
|
||||
$tab_view,
|
||||
$timeline,
|
||||
$comment_view,
|
||||
|
@ -395,58 +398,6 @@ final class ManiphestTaskDetailController extends ManiphestController {
|
|||
$source));
|
||||
}
|
||||
|
||||
$edge_types = array(
|
||||
ManiphestTaskHasRevisionEdgeType::EDGECONST
|
||||
=> pht('Differential Revisions'),
|
||||
);
|
||||
|
||||
$revisions_commits = array();
|
||||
|
||||
$commit_phids = array_keys(
|
||||
$edges[ManiphestTaskHasCommitEdgeType::EDGECONST]);
|
||||
if ($commit_phids) {
|
||||
$commit_drev = DiffusionCommitHasRevisionEdgeType::EDGECONST;
|
||||
$drev_edges = id(new PhabricatorEdgeQuery())
|
||||
->withSourcePHIDs($commit_phids)
|
||||
->withEdgeTypes(array($commit_drev))
|
||||
->execute();
|
||||
|
||||
foreach ($commit_phids as $phid) {
|
||||
$revisions_commits[$phid] = $handles->renderHandle($phid)
|
||||
->setShowHovercard(true)
|
||||
->setShowStateIcon(true);
|
||||
$revision_phid = key($drev_edges[$phid][$commit_drev]);
|
||||
$revision_handle = $handles->getHandleIfExists($revision_phid);
|
||||
if ($revision_handle) {
|
||||
$task_drev = ManiphestTaskHasRevisionEdgeType::EDGECONST;
|
||||
unset($edges[$task_drev][$revision_phid]);
|
||||
$revisions_commits[$phid] = hsprintf(
|
||||
'%s / %s',
|
||||
$revision_handle->renderHovercardLink($revision_handle->getName()),
|
||||
$revisions_commits[$phid]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($edge_types as $edge_type => $edge_name) {
|
||||
if (!$edges[$edge_type]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$edge_handles = $viewer->loadHandles(array_keys($edges[$edge_type]));
|
||||
|
||||
$edge_list = $edge_handles->renderList()
|
||||
->setShowStateIcons(true);
|
||||
|
||||
$view->addProperty($edge_name, $edge_list);
|
||||
}
|
||||
|
||||
if ($revisions_commits) {
|
||||
$view->addProperty(
|
||||
pht('Commits'),
|
||||
phutil_implode_html(phutil_tag('br'), $revisions_commits));
|
||||
}
|
||||
|
||||
$field_list->appendFieldsToPropertyList(
|
||||
$task,
|
||||
$viewer,
|
||||
|
@ -596,5 +547,291 @@ final class ManiphestTaskDetailController extends ManiphestController {
|
|||
return $handles->newSublist($phids);
|
||||
}
|
||||
|
||||
private function newChangesView(ManiphestTask $task, array $edges) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$revision_type = ManiphestTaskHasRevisionEdgeType::EDGECONST;
|
||||
$commit_type = ManiphestTaskHasCommitEdgeType::EDGECONST;
|
||||
|
||||
$revision_phids = idx($edges, $revision_type, array());
|
||||
$revision_phids = array_keys($revision_phids);
|
||||
$revision_phids = array_fuse($revision_phids);
|
||||
|
||||
$commit_phids = idx($edges, $commit_type, array());
|
||||
$commit_phids = array_keys($commit_phids);
|
||||
$commit_phids = array_fuse($commit_phids);
|
||||
|
||||
if (!$revision_phids && !$commit_phids) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($commit_phids) {
|
||||
$link_type = DiffusionCommitHasRevisionEdgeType::EDGECONST;
|
||||
$link_query = id(new PhabricatorEdgeQuery())
|
||||
->withSourcePHIDs($commit_phids)
|
||||
->withEdgeTypes(array($link_type));
|
||||
$link_query->execute();
|
||||
|
||||
$commits = id(new DiffusionCommitQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs($commit_phids)
|
||||
->execute();
|
||||
$commits = mpull($commits, null, 'getPHID');
|
||||
} else {
|
||||
$commits = array();
|
||||
}
|
||||
|
||||
if ($revision_phids) {
|
||||
$revisions = id(new DifferentialRevisionQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs($revision_phids)
|
||||
->execute();
|
||||
$revisions = mpull($revisions, null, 'getPHID');
|
||||
} else {
|
||||
$revisions = array();
|
||||
}
|
||||
|
||||
$handle_phids = array();
|
||||
$any_linked = false;
|
||||
$any_status = false;
|
||||
|
||||
$idx = 0;
|
||||
$objects = array();
|
||||
foreach ($commit_phids as $commit_phid) {
|
||||
$handle_phids[] = $commit_phid;
|
||||
|
||||
$link_phids = $link_query->getDestinationPHIDs(array($commit_phid));
|
||||
foreach ($link_phids as $link_phid) {
|
||||
$handle_phids[] = $link_phid;
|
||||
unset($revision_phids[$link_phid]);
|
||||
$any_linked = true;
|
||||
}
|
||||
|
||||
$commit = idx($commits, $commit_phid);
|
||||
if ($commit) {
|
||||
$repository_phid = $commit->getRepository()->getPHID();
|
||||
$handle_phids[] = $repository_phid;
|
||||
} else {
|
||||
$repository_phid = null;
|
||||
}
|
||||
|
||||
$status_view = null;
|
||||
if ($commit) {
|
||||
$status = $commit->getAuditStatusObject();
|
||||
if (!$status->isNoAudit()) {
|
||||
$status_view = id(new PHUITagView())
|
||||
->setType(PHUITagView::TYPE_SHADE)
|
||||
->setIcon($status->getIcon())
|
||||
->setColor($status->getColor())
|
||||
->setName($status->getName());
|
||||
}
|
||||
}
|
||||
|
||||
$object_link = null;
|
||||
if ($commit) {
|
||||
$commit_monogram = $commit->getDisplayName();
|
||||
$commit_monogram = phutil_tag(
|
||||
'span',
|
||||
array(
|
||||
'class' => 'object-name',
|
||||
),
|
||||
$commit_monogram);
|
||||
|
||||
$commit_link = javelin_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $commit->getURI(),
|
||||
'sigil' => 'hovercard',
|
||||
'meta' => array(
|
||||
'hoverPHID' => $commit->getPHID(),
|
||||
),
|
||||
),
|
||||
$commit->getSummary());
|
||||
|
||||
$object_link = array(
|
||||
$commit_monogram,
|
||||
' ',
|
||||
$commit_link,
|
||||
);
|
||||
}
|
||||
|
||||
$objects[] = array(
|
||||
'objectPHID' => $commit_phid,
|
||||
'objectLink' => $object_link,
|
||||
'repositoryPHID' => $repository_phid,
|
||||
'revisionPHIDs' => $link_phids,
|
||||
'status' => $status_view,
|
||||
'order' => id(new PhutilSortVector())
|
||||
->addInt($repository_phid ? 1 : 0)
|
||||
->addString((string)$repository_phid)
|
||||
->addInt(1)
|
||||
->addInt($idx++),
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($revision_phids as $revision_phid) {
|
||||
$handle_phids[] = $revision_phid;
|
||||
|
||||
$revision = idx($revisions, $revision_phid);
|
||||
if ($revision) {
|
||||
$repository_phid = $revision->getRepositoryPHID();
|
||||
$handle_phids[] = $repository_phid;
|
||||
} else {
|
||||
$repository_phid = null;
|
||||
}
|
||||
|
||||
if ($revision) {
|
||||
$icon = $revision->getStatusIcon();
|
||||
$color = $revision->getStatusIconColor();
|
||||
$name = $revision->getStatusDisplayName();
|
||||
|
||||
$status_view = id(new PHUITagView())
|
||||
->setType(PHUITagView::TYPE_SHADE)
|
||||
->setIcon($icon)
|
||||
->setColor($color)
|
||||
->setName($name);
|
||||
} else {
|
||||
$status_view = null;
|
||||
}
|
||||
|
||||
$object_link = null;
|
||||
if ($revision) {
|
||||
$revision_monogram = $revision->getMonogram();
|
||||
$revision_monogram = phutil_tag(
|
||||
'span',
|
||||
array(
|
||||
'class' => 'object-name',
|
||||
),
|
||||
$revision_monogram);
|
||||
|
||||
$revision_link = javelin_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $revision->getURI(),
|
||||
'sigil' => 'hovercard',
|
||||
'meta' => array(
|
||||
'hoverPHID' => $revision->getPHID(),
|
||||
),
|
||||
),
|
||||
$revision->getTitle());
|
||||
|
||||
$object_link = array(
|
||||
$revision_monogram,
|
||||
' ',
|
||||
$revision_link,
|
||||
);
|
||||
}
|
||||
|
||||
$objects[] = array(
|
||||
'objectPHID' => $revision_phid,
|
||||
'objectLink' => $object_link,
|
||||
'repositoryPHID' => $repository_phid,
|
||||
'revisionPHIDs' => array(),
|
||||
'status' => $status_view,
|
||||
'order' => id(new PhutilSortVector())
|
||||
->addInt($repository_phid ? 1 : 0)
|
||||
->addString((string)$repository_phid)
|
||||
->addInt(0)
|
||||
->addInt($idx++),
|
||||
);
|
||||
}
|
||||
|
||||
$handles = $viewer->loadHandles($handle_phids);
|
||||
|
||||
$order = ipull($objects, 'order');
|
||||
$order = msortv($order, 'getSelf');
|
||||
$objects = array_select_keys($objects, array_keys($order));
|
||||
|
||||
$last_repository = false;
|
||||
$rows = array();
|
||||
$rowd = array();
|
||||
foreach ($objects as $object) {
|
||||
$repository_phid = $object['repositoryPHID'];
|
||||
if ($repository_phid !== $last_repository) {
|
||||
$repository_link = null;
|
||||
if ($repository_phid) {
|
||||
$repository_handle = $handles[$repository_phid];
|
||||
$rows[] = array(
|
||||
$repository_handle->renderLink(),
|
||||
);
|
||||
$rowd[] = true;
|
||||
}
|
||||
|
||||
$last_repository = $repository_phid;
|
||||
}
|
||||
|
||||
$object_phid = $object['objectPHID'];
|
||||
$handle = $handles[$object_phid];
|
||||
|
||||
$object_link = $object['objectLink'];
|
||||
if ($object_link === null) {
|
||||
$object_link = $handle->renderLink();
|
||||
}
|
||||
|
||||
$object_icon = id(new PHUIIconView())
|
||||
->setIcon($handle->getIcon());
|
||||
|
||||
$status_view = $object['status'];
|
||||
if ($status_view) {
|
||||
$any_status = true;
|
||||
}
|
||||
|
||||
$revision_tags = array();
|
||||
foreach ($object['revisionPHIDs'] as $link_phid) {
|
||||
$revision_handle = $handles[$link_phid];
|
||||
|
||||
$revision_name = $revision_handle->getName();
|
||||
$revision_tags[] = $revision_handle
|
||||
->renderHovercardLink($revision_name);
|
||||
}
|
||||
$revision_tags = phutil_implode_html(
|
||||
phutil_tag('br'),
|
||||
$revision_tags);
|
||||
|
||||
$rowd[] = false;
|
||||
$rows[] = array(
|
||||
$object_icon,
|
||||
$status_view,
|
||||
$revision_tags,
|
||||
$object_link,
|
||||
);
|
||||
}
|
||||
|
||||
$changes_table = id(new AphrontTableView($rows))
|
||||
->setNoDataString(pht('This task has no related commits or revisions.'))
|
||||
->setRowDividers($rowd)
|
||||
->setColumnClasses(
|
||||
array(
|
||||
'indent center',
|
||||
null,
|
||||
null,
|
||||
'wide pri object-link',
|
||||
))
|
||||
->setColumnVisibility(
|
||||
array(
|
||||
true,
|
||||
$any_status,
|
||||
$any_linked,
|
||||
true,
|
||||
))
|
||||
->setDeviceVisibility(
|
||||
array(
|
||||
false,
|
||||
$any_status,
|
||||
false,
|
||||
true,
|
||||
));
|
||||
|
||||
$changes_header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Revisions and Commits'));
|
||||
|
||||
$changes_view = id(new PHUIObjectBoxView())
|
||||
->setHeader($changes_header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setTable($changes_table);
|
||||
|
||||
return $changes_view;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -33,10 +33,6 @@ final class PhabricatorObjectHandle
|
|||
private $commandLineObjectName;
|
||||
private $mailStampName;
|
||||
|
||||
private $stateIcon;
|
||||
private $stateColor;
|
||||
private $stateName;
|
||||
|
||||
public function setIcon($icon) {
|
||||
$this->icon = $icon;
|
||||
return $this;
|
||||
|
@ -299,55 +295,6 @@ final class PhabricatorObjectHandle
|
|||
return $this->complete;
|
||||
}
|
||||
|
||||
public function setStateIcon($state_icon) {
|
||||
$this->stateIcon = $state_icon;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getStateIcon() {
|
||||
return $this->stateIcon;
|
||||
}
|
||||
|
||||
public function setStateColor($state_color) {
|
||||
$this->stateColor = $state_color;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getStateColor() {
|
||||
return $this->stateColor;
|
||||
}
|
||||
|
||||
public function setStateName($state_name) {
|
||||
$this->stateName = $state_name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getStateName() {
|
||||
return $this->stateName;
|
||||
}
|
||||
|
||||
public function renderStateIcon() {
|
||||
$icon = $this->getStateIcon();
|
||||
if ($icon === null) {
|
||||
$icon = 'fa-question-circle-o';
|
||||
}
|
||||
|
||||
$color = $this->getStateColor();
|
||||
|
||||
$name = $this->getStateName();
|
||||
if ($name === null) {
|
||||
$name = pht('Unknown');
|
||||
}
|
||||
|
||||
return id(new PHUIIconView())
|
||||
->setIcon($icon, $color)
|
||||
->addSigil('has-tooltip')
|
||||
->setMetadata(
|
||||
array(
|
||||
'tip' => $name,
|
||||
));
|
||||
}
|
||||
|
||||
public function renderLink($name = null) {
|
||||
return $this->renderLinkWithAttributes($name, array());
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ final class PHUIHandleListView
|
|||
private $handleList;
|
||||
private $asInline;
|
||||
private $asText;
|
||||
private $showStateIcons;
|
||||
private $glyphLimit;
|
||||
|
||||
public function setHandleList(PhabricatorHandleList $list) {
|
||||
|
@ -39,15 +38,6 @@ final class PHUIHandleListView
|
|||
return $this->asText;
|
||||
}
|
||||
|
||||
public function setShowStateIcons($show_state_icons) {
|
||||
$this->showStateIcons = $show_state_icons;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getShowStateIcons() {
|
||||
return $this->showStateIcons;
|
||||
}
|
||||
|
||||
public function setGlyphLimit($glyph_limit) {
|
||||
$this->glyphLimit = $glyph_limit;
|
||||
return $this;
|
||||
|
@ -70,7 +60,6 @@ final class PHUIHandleListView
|
|||
protected function getTagContent() {
|
||||
$list = $this->handleList;
|
||||
|
||||
$show_state_icons = $this->getShowStateIcons();
|
||||
$glyph_limit = $this->getGlyphLimit();
|
||||
|
||||
$items = array();
|
||||
|
@ -79,10 +68,6 @@ final class PHUIHandleListView
|
|||
->setShowHovercard(true)
|
||||
->setAsText($this->getAsText());
|
||||
|
||||
if ($show_state_icons) {
|
||||
$view->setShowStateIcon(true);
|
||||
}
|
||||
|
||||
if ($glyph_limit) {
|
||||
$view->setGlyphLimit($glyph_limit);
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ final class PHUIHandleView
|
|||
private $asText;
|
||||
private $useShortName;
|
||||
private $showHovercard;
|
||||
private $showStateIcon;
|
||||
private $glyphLimit;
|
||||
|
||||
public function setHandleList(PhabricatorHandleList $list) {
|
||||
|
@ -50,15 +49,6 @@ final class PHUIHandleView
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function setShowStateIcon($show_state_icon) {
|
||||
$this->showStateIcon = $show_state_icon;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getShowStateIcon() {
|
||||
return $this->showStateIcon;
|
||||
}
|
||||
|
||||
public function setGlyphLimit($glyph_limit) {
|
||||
$this->glyphLimit = $glyph_limit;
|
||||
return $this;
|
||||
|
@ -104,11 +94,6 @@ final class PHUIHandleView
|
|||
$link = $handle->renderLink($name);
|
||||
}
|
||||
|
||||
if ($this->showStateIcon) {
|
||||
$icon = $handle->renderStateIcon();
|
||||
$link = array($icon, ' ', $link);
|
||||
}
|
||||
|
||||
return $link;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,11 @@ final class PhabricatorProjectBurndownChartEngine
|
|||
$open_function = $this->newFunction(
|
||||
array(
|
||||
'accumulate',
|
||||
array(
|
||||
'sum',
|
||||
array('fact', 'tasks.open-count.create'),
|
||||
array('fact', 'tasks.open-count.status'),
|
||||
),
|
||||
));
|
||||
|
||||
$closed_function = $this->newFunction(
|
||||
|
|
|
@ -65,6 +65,35 @@ final class PhabricatorProjectSearchEngine
|
|||
pht(
|
||||
'Pass true to find only milestones, or false to omit '.
|
||||
'milestones.')),
|
||||
id(new PhabricatorSearchThreeStateField())
|
||||
->setLabel(pht('Root Projects'))
|
||||
->setKey('isRoot')
|
||||
->setOptions(
|
||||
pht('(Show All)'),
|
||||
pht('Show Only Root Projects'),
|
||||
pht('Hide Root Projects'))
|
||||
->setDescription(
|
||||
pht(
|
||||
'Pass true to find only root projects, or false to omit '.
|
||||
'root projects.')),
|
||||
id(new PhabricatorSearchIntField())
|
||||
->setLabel(pht('Minimum Depth'))
|
||||
->setKey('minDepth')
|
||||
->setIsHidden(true)
|
||||
->setDescription(
|
||||
pht(
|
||||
'Find projects with a given minimum depth. Root projects '.
|
||||
'have depth 0, their immediate children have depth 1, and '.
|
||||
'so on.')),
|
||||
id(new PhabricatorSearchIntField())
|
||||
->setLabel(pht('Maximum Depth'))
|
||||
->setKey('maxDepth')
|
||||
->setIsHidden(true)
|
||||
->setDescription(
|
||||
pht(
|
||||
'Find projects with a given maximum depth. Root projects '.
|
||||
'have depth 0, their immediate children have depth 1, and '.
|
||||
'so on.')),
|
||||
id(new PhabricatorSearchDatasourceField())
|
||||
->setLabel(pht('Subtypes'))
|
||||
->setKey('subtypes')
|
||||
|
@ -137,6 +166,42 @@ final class PhabricatorProjectSearchEngine
|
|||
$query->withIsMilestone($map['isMilestone']);
|
||||
}
|
||||
|
||||
$min_depth = $map['minDepth'];
|
||||
$max_depth = $map['maxDepth'];
|
||||
|
||||
if ($min_depth !== null || $max_depth !== null) {
|
||||
if ($min_depth !== null && $max_depth !== null) {
|
||||
if ($min_depth > $max_depth) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Search constraint "minDepth" must be no larger than '.
|
||||
'search constraint "maxDepth".'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($map['isRoot'] !== null) {
|
||||
if ($map['isRoot']) {
|
||||
if ($max_depth === null) {
|
||||
$max_depth = 0;
|
||||
} else {
|
||||
$max_depth = min(0, $max_depth);
|
||||
}
|
||||
|
||||
$query->withDepthBetween(null, 0);
|
||||
} else {
|
||||
if ($min_depth === null) {
|
||||
$min_depth = 1;
|
||||
} else {
|
||||
$min_depth = max($min_depth, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($min_depth !== null || $max_depth !== null) {
|
||||
$query->withDepthBetween($min_depth, $max_depth);
|
||||
}
|
||||
|
||||
if ($map['parentPHIDs']) {
|
||||
$query->withParentProjectPHIDs($map['parentPHIDs']);
|
||||
}
|
||||
|
|
|
@ -130,10 +130,35 @@ final class PhabricatorRepositoryURINormalizer extends Phobject {
|
|||
$domain = $uri->getDomain();
|
||||
|
||||
if (!strlen($domain)) {
|
||||
$domain = '<void>';
|
||||
return '<void>';
|
||||
}
|
||||
|
||||
return phutil_utf8_strtolower($domain);
|
||||
$domain = phutil_utf8_strtolower($domain);
|
||||
|
||||
// See T13435. If the domain for a repository URI is same as the install
|
||||
// base URI, store it as a "<base-uri>" token instead of the actual domain
|
||||
// so that the index does not fall out of date if the install moves.
|
||||
|
||||
$base_uri = PhabricatorEnv::getURI('/');
|
||||
$base_uri = new PhutilURI($base_uri);
|
||||
$base_domain = $base_uri->getDomain();
|
||||
$base_domain = phutil_utf8_strtolower($base_domain);
|
||||
if ($domain === $base_domain) {
|
||||
return '<base-uri>';
|
||||
}
|
||||
|
||||
// Likewise, store a token for the "SSH Host" domain so it can be changed
|
||||
// without requiring an index rebuild.
|
||||
|
||||
$ssh_host = PhabricatorEnv::getEnvConfig('diffusion.ssh-host');
|
||||
if (strlen($ssh_host)) {
|
||||
$ssh_host = phutil_utf8_strtolower($ssh_host);
|
||||
if ($domain === $ssh_host) {
|
||||
return '<ssh-host>';
|
||||
}
|
||||
}
|
||||
|
||||
return $domain;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -31,6 +31,36 @@ final class PhabricatorRepositoryURINormalizerTestCase
|
|||
}
|
||||
}
|
||||
|
||||
public function testDomainURINormalizer() {
|
||||
$base_domain = 'base.phabricator.example.com';
|
||||
$ssh_domain = 'ssh.phabricator.example.com';
|
||||
|
||||
$env = PhabricatorEnv::beginScopedEnv();
|
||||
$env->overrideEnvConfig('phabricator.base-uri', 'http://'.$base_domain);
|
||||
$env->overrideEnvConfig('diffusion.ssh-host', $ssh_domain);
|
||||
|
||||
$cases = array(
|
||||
'/' => '<void>',
|
||||
'/path/to/local/repo.git' => '<void>',
|
||||
'ssh://user@domain.com/path.git' => 'domain.com',
|
||||
'ssh://user@DOMAIN.COM/path.git' => 'domain.com',
|
||||
'http://'.$base_domain.'/diffusion/X/' => '<base-uri>',
|
||||
'ssh://'.$ssh_domain.'/diffusion/X/' => '<ssh-host>',
|
||||
'git@'.$ssh_domain.':bananas.git' => '<ssh-host>',
|
||||
);
|
||||
|
||||
$type_git = PhabricatorRepositoryURINormalizer::TYPE_GIT;
|
||||
|
||||
foreach ($cases as $input => $expect) {
|
||||
$normal = new PhabricatorRepositoryURINormalizer($type_git, $input);
|
||||
|
||||
$this->assertEqual(
|
||||
$expect,
|
||||
$normal->getNormalizedDomain(),
|
||||
pht('Normalized domain for "%s".', $input));
|
||||
}
|
||||
}
|
||||
|
||||
public function testSVNURINormalizer() {
|
||||
$cases = array(
|
||||
'file:///path/to/repo' => 'path/to/repo',
|
||||
|
|
|
@ -81,16 +81,6 @@ final class PhabricatorRepositoryCommitPHIDType extends PhabricatorPHIDType {
|
|||
$handle->setFullName($full_name);
|
||||
$handle->setURI($commit->getURI());
|
||||
$handle->setTimestamp($commit->getEpoch());
|
||||
|
||||
$status = $commit->getAuditStatusObject();
|
||||
$icon = $status->getIcon();
|
||||
$color = $status->getColor();
|
||||
$name = $status->getName();
|
||||
|
||||
$handle
|
||||
->setStateIcon($icon)
|
||||
->setStateColor($color)
|
||||
->setStateName($name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
22
src/applications/search/field/PhabricatorSearchIntField.php
Normal file
22
src/applications/search/field/PhabricatorSearchIntField.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorSearchIntField
|
||||
extends PhabricatorSearchField {
|
||||
|
||||
protected function getDefaultValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function getValueFromRequest(AphrontRequest $request, $key) {
|
||||
return $request->getInt($key);
|
||||
}
|
||||
|
||||
protected function newControl() {
|
||||
return new AphrontFormTextControl();
|
||||
}
|
||||
|
||||
protected function newConduitParameterType() {
|
||||
return new ConduitIntParameterType();
|
||||
}
|
||||
|
||||
}
|
|
@ -24,6 +24,8 @@ final class AphrontTableView extends AphrontView {
|
|||
protected $sortValues = array();
|
||||
private $deviceReadyTable;
|
||||
|
||||
private $rowDividers = array();
|
||||
|
||||
public function __construct(array $data) {
|
||||
$this->data = $data;
|
||||
}
|
||||
|
@ -53,6 +55,11 @@ final class AphrontTableView extends AphrontView {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function setRowDividers(array $dividers) {
|
||||
$this->rowDividers = $dividers;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setNoDataString($no_data_string) {
|
||||
$this->noDataString = $no_data_string;
|
||||
return $this;
|
||||
|
@ -258,10 +265,15 @@ final class AphrontTableView extends AphrontView {
|
|||
}
|
||||
}
|
||||
|
||||
$dividers = $this->rowDividers;
|
||||
|
||||
$data = $this->data;
|
||||
if ($data) {
|
||||
$row_num = 0;
|
||||
$row_idx = 0;
|
||||
foreach ($data as $row) {
|
||||
$is_divider = !empty($dividers[$row_num]);
|
||||
|
||||
$row_size = count($row);
|
||||
while (count($row) > count($col_classes)) {
|
||||
$col_classes[] = null;
|
||||
|
@ -289,6 +301,18 @@ final class AphrontTableView extends AphrontView {
|
|||
$class = trim($class.' '.$this->cellClasses[$row_num][$col_num]);
|
||||
}
|
||||
|
||||
if ($is_divider) {
|
||||
$tr[] = phutil_tag(
|
||||
'td',
|
||||
array(
|
||||
'class' => 'row-divider',
|
||||
'colspan' => count($visibility),
|
||||
),
|
||||
$value);
|
||||
$row_idx = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
$tr[] = phutil_tag(
|
||||
'td',
|
||||
array(
|
||||
|
@ -299,7 +323,7 @@ final class AphrontTableView extends AphrontView {
|
|||
}
|
||||
|
||||
$class = idx($this->rowClasses, $row_num);
|
||||
if ($this->zebraStripes && ($row_num % 2)) {
|
||||
if ($this->zebraStripes && ($row_idx % 2)) {
|
||||
if ($class !== null) {
|
||||
$class = 'alt alt-'.$class;
|
||||
} else {
|
||||
|
@ -309,6 +333,7 @@ final class AphrontTableView extends AphrontView {
|
|||
|
||||
$table[] = phutil_tag('tr', array('class' => $class), $tr);
|
||||
++$row_num;
|
||||
++$row_idx;
|
||||
}
|
||||
} else {
|
||||
$colspan = max(count(array_filter($visibility)), 1);
|
||||
|
|
|
@ -55,6 +55,16 @@
|
|||
background-color: {$lightbluebackground};
|
||||
}
|
||||
|
||||
.aphront-table-view td.row-divider {
|
||||
background-color: {$bluebackground};
|
||||
font-weight: bold;
|
||||
padding: 8px 12px;
|
||||
}
|
||||
|
||||
.aphront-table-view td.indent {
|
||||
padding-left: 24px;
|
||||
}
|
||||
|
||||
.aphront-table-view th {
|
||||
border-bottom: 1px solid {$thinblueborder};
|
||||
}
|
||||
|
|
|
@ -152,7 +152,16 @@ JX.behavior('repository-crossreference', function(config, statics) {
|
|||
query.char = char;
|
||||
}
|
||||
|
||||
var uri = JX.$U('/diffusion/symbol/' + symbol + '/');
|
||||
var uri_symbol = symbol;
|
||||
|
||||
// In some cases, lexers may include whitespace in symbol tags. Trim it,
|
||||
// since symbols with semantic whitespace aren't supported.
|
||||
uri_symbol = uri_symbol.trim();
|
||||
|
||||
// See T13437. Symbols like "#define" need to be encoded.
|
||||
uri_symbol = encodeURIComponent(uri_symbol);
|
||||
|
||||
var uri = JX.$U('/diffusion/symbol/' + uri_symbol + '/');
|
||||
uri.addQueryParams(query);
|
||||
|
||||
window.open(uri.toString());
|
||||
|
|
Loading…
Add table
Reference in a new issue