mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-22 06:42:42 +01:00
Implements a more informative hovercard for wiki documents
Summary: The current hovercard of a wiki document has no further information except the title. This commit adds object type, project tags, parent documents, last author and last edited time to the card. Preview: {F313614} Preview in a pessimistic case: {F325478} Closes T15433 Test Plan: Edit a wiki document with/without project tags and parent documents and see the hovercard in the feed. Reviewers: O1 Blessed Committers, valerio.bozzolan, avivey, Cigaryno Reviewed By: O1 Blessed Committers, valerio.bozzolan, avivey, Cigaryno Subscribers: avivey, speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15433 Differential Revision: https://we.phorge.it/D25303
This commit is contained in:
parent
4cedb928aa
commit
df3ac50cb7
4 changed files with 194 additions and 2 deletions
|
@ -159,7 +159,7 @@ return array(
|
||||||
'rsrc/css/phui/phui-formation-view.css' => 'd2dec8ed',
|
'rsrc/css/phui/phui-formation-view.css' => 'd2dec8ed',
|
||||||
'rsrc/css/phui/phui-head-thing.css' => 'd7f293df',
|
'rsrc/css/phui/phui-head-thing.css' => 'd7f293df',
|
||||||
'rsrc/css/phui/phui-header-view.css' => '36c86a58',
|
'rsrc/css/phui/phui-header-view.css' => '36c86a58',
|
||||||
'rsrc/css/phui/phui-hovercard.css' => '6ca90fa0',
|
'rsrc/css/phui/phui-hovercard.css' => '39fd2e14',
|
||||||
'rsrc/css/phui/phui-icon-set-selector.css' => '7aa5f3ec',
|
'rsrc/css/phui/phui-icon-set-selector.css' => '7aa5f3ec',
|
||||||
'rsrc/css/phui/phui-icon.css' => '084ac612',
|
'rsrc/css/phui/phui-icon.css' => '084ac612',
|
||||||
'rsrc/css/phui/phui-image-mask.css' => '62c7f4d2',
|
'rsrc/css/phui/phui-image-mask.css' => '62c7f4d2',
|
||||||
|
@ -855,7 +855,7 @@ return array(
|
||||||
'phui-header-view-css' => '36c86a58',
|
'phui-header-view-css' => '36c86a58',
|
||||||
'phui-hovercard' => '6199f752',
|
'phui-hovercard' => '6199f752',
|
||||||
'phui-hovercard-list' => 'de4b4919',
|
'phui-hovercard-list' => 'de4b4919',
|
||||||
'phui-hovercard-view-css' => '6ca90fa0',
|
'phui-hovercard-view-css' => '39fd2e14',
|
||||||
'phui-icon-set-selector-css' => '7aa5f3ec',
|
'phui-icon-set-selector-css' => '7aa5f3ec',
|
||||||
'phui-icon-view-css' => '084ac612',
|
'phui-icon-view-css' => '084ac612',
|
||||||
'phui-image-mask-css' => '62c7f4d2',
|
'phui-image-mask-css' => '62c7f4d2',
|
||||||
|
|
|
@ -5644,6 +5644,7 @@ phutil_register_library_map(array(
|
||||||
'PhrictionEditEngineController' => 'applications/phriction/controller/PhrictionEditEngineController.php',
|
'PhrictionEditEngineController' => 'applications/phriction/controller/PhrictionEditEngineController.php',
|
||||||
'PhrictionHistoryConduitAPIMethod' => 'applications/phriction/conduit/PhrictionHistoryConduitAPIMethod.php',
|
'PhrictionHistoryConduitAPIMethod' => 'applications/phriction/conduit/PhrictionHistoryConduitAPIMethod.php',
|
||||||
'PhrictionHistoryController' => 'applications/phriction/controller/PhrictionHistoryController.php',
|
'PhrictionHistoryController' => 'applications/phriction/controller/PhrictionHistoryController.php',
|
||||||
|
'PhrictionHovercardEngineExtension' => 'applications/phriction/engineextension/PhrictionHovercardEngineExtension.php',
|
||||||
'PhrictionInfoConduitAPIMethod' => 'applications/phriction/conduit/PhrictionInfoConduitAPIMethod.php',
|
'PhrictionInfoConduitAPIMethod' => 'applications/phriction/conduit/PhrictionInfoConduitAPIMethod.php',
|
||||||
'PhrictionListController' => 'applications/phriction/controller/PhrictionListController.php',
|
'PhrictionListController' => 'applications/phriction/controller/PhrictionListController.php',
|
||||||
'PhrictionMarkupPreviewController' => 'applications/phriction/controller/PhrictionMarkupPreviewController.php',
|
'PhrictionMarkupPreviewController' => 'applications/phriction/controller/PhrictionMarkupPreviewController.php',
|
||||||
|
@ -12545,6 +12546,7 @@ phutil_register_library_map(array(
|
||||||
'PhrictionEditEngineController' => 'PhrictionController',
|
'PhrictionEditEngineController' => 'PhrictionController',
|
||||||
'PhrictionHistoryConduitAPIMethod' => 'PhrictionConduitAPIMethod',
|
'PhrictionHistoryConduitAPIMethod' => 'PhrictionConduitAPIMethod',
|
||||||
'PhrictionHistoryController' => 'PhrictionController',
|
'PhrictionHistoryController' => 'PhrictionController',
|
||||||
|
'PhrictionHovercardEngineExtension' => 'PhabricatorHovercardEngineExtension',
|
||||||
'PhrictionInfoConduitAPIMethod' => 'PhrictionConduitAPIMethod',
|
'PhrictionInfoConduitAPIMethod' => 'PhrictionConduitAPIMethod',
|
||||||
'PhrictionListController' => 'PhrictionController',
|
'PhrictionListController' => 'PhrictionController',
|
||||||
'PhrictionMarkupPreviewController' => 'PhabricatorController',
|
'PhrictionMarkupPreviewController' => 'PhabricatorController',
|
||||||
|
|
|
@ -0,0 +1,169 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhrictionHovercardEngineExtension
|
||||||
|
extends PhabricatorHovercardEngineExtension {
|
||||||
|
|
||||||
|
const EXTENSIONKEY = 'phriction';
|
||||||
|
|
||||||
|
public function isExtensionEnabled() {
|
||||||
|
return PhabricatorApplication::isClassInstalled(
|
||||||
|
'PhabricatorPhrictionApplication');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getExtensionName() {
|
||||||
|
return pht('Wiki Documents');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canRenderObjectHovercard($object) {
|
||||||
|
return ($object instanceof PhrictionDocument);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function willRenderHovercards(array $objects) {
|
||||||
|
return array(
|
||||||
|
'projects' => $this->getProjectHandlesOfDocuments($objects),
|
||||||
|
'ancestors' => $this->getAncestorHandlesOfDocuments($objects),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function renderHovercard(
|
||||||
|
PHUIHovercardView $hovercard,
|
||||||
|
PhabricatorObjectHandle $handle,
|
||||||
|
$object,
|
||||||
|
$data) {
|
||||||
|
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
$phid = $object->getPHID();
|
||||||
|
|
||||||
|
$detail_content = array(
|
||||||
|
id(new PHUIIconView())->setIcon('fa-book'),
|
||||||
|
);
|
||||||
|
|
||||||
|
$ancestor_handles = $data['ancestors'][$phid];
|
||||||
|
if ($ancestor_handles) {
|
||||||
|
foreach ($ancestor_handles as $ancestor_handle) {
|
||||||
|
$detail_content[] = phutil_tag(
|
||||||
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => $ancestor_handle->getUri(),
|
||||||
|
),
|
||||||
|
$ancestor_handle->getName());
|
||||||
|
|
||||||
|
$detail_content[] = id(new PHUIIconView())
|
||||||
|
->setIcon('fa-angle-right')
|
||||||
|
->addClass('phui-crumb-divider');
|
||||||
|
}
|
||||||
|
array_pop($detail_content);
|
||||||
|
} else {
|
||||||
|
$detail_content[] = pht('Wiki Document');
|
||||||
|
}
|
||||||
|
|
||||||
|
$project_handles = $data['projects'][$phid];
|
||||||
|
if ($project_handles) {
|
||||||
|
$list = id(new PHUIHandleTagListView())
|
||||||
|
->setHandles($project_handles)
|
||||||
|
->setSlim(true)
|
||||||
|
->setShowHovercards(false);
|
||||||
|
|
||||||
|
$detail_content[] = $list;
|
||||||
|
}
|
||||||
|
|
||||||
|
$hovercard->setDetail(
|
||||||
|
phutil_tag(
|
||||||
|
'div',
|
||||||
|
array(
|
||||||
|
'class' => 'phui-hovercard-object-type',
|
||||||
|
),
|
||||||
|
$detail_content));
|
||||||
|
|
||||||
|
$content = $object->getContent();
|
||||||
|
|
||||||
|
if ($content) {
|
||||||
|
$hovercard->addField(
|
||||||
|
pht('Last Author'),
|
||||||
|
$viewer->renderHandle($content->getAuthorPHID()));
|
||||||
|
|
||||||
|
$hovercard->addField(
|
||||||
|
pht('Last Edited'),
|
||||||
|
phabricator_dual_datetime($content->getDateCreated(), $viewer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getProjectHandlesOfDocuments($documents) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
$project_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
|
||||||
|
$project_phids = array();
|
||||||
|
$project_map = array();
|
||||||
|
|
||||||
|
$project_edges = id(new PhabricatorEdgeQuery())
|
||||||
|
->withSourcePHIDs(mpull($documents, 'getPHID'))
|
||||||
|
->withEdgeTypes(array($project_edge_type))
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
foreach ($project_edges as $document_phid => $edge_types) {
|
||||||
|
$document_project_phids = array_keys($edge_types[$project_edge_type]);
|
||||||
|
|
||||||
|
$project_map[$document_phid] = array_reverse($document_project_phids);
|
||||||
|
foreach ($document_project_phids as $project_phid) {
|
||||||
|
if (!in_array($project_phid, $project_phids, true)) {
|
||||||
|
$project_phids[] = $project_phid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($project_phids) {
|
||||||
|
$project_handles = $viewer->loadHandles($project_phids);
|
||||||
|
$project_handles = iterator_to_array($project_handles);
|
||||||
|
$project_handles = mpull($project_handles, null, 'getPHID');
|
||||||
|
|
||||||
|
foreach ($project_map as $key => $document_project_phids) {
|
||||||
|
$project_map[$key] = array_select_keys(
|
||||||
|
$project_handles,
|
||||||
|
$document_project_phids);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $project_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getAncestorHandlesOfDocuments($documents) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
$ancestor_slugs = array();
|
||||||
|
$ancestor_map = array();
|
||||||
|
|
||||||
|
foreach ($documents as $document) {
|
||||||
|
$document_phid = $document->getPHID();
|
||||||
|
$document_ancestor_slugs = PhabricatorSlug::getAncestry(
|
||||||
|
$document->getSlug());
|
||||||
|
|
||||||
|
$ancestor_map[$document_phid] = $document_ancestor_slugs;
|
||||||
|
foreach ($document_ancestor_slugs as $slug) {
|
||||||
|
if (!in_array($slug, $ancestor_slugs, true)) {
|
||||||
|
$ancestor_slugs[] = $slug;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($ancestor_slugs) {
|
||||||
|
$ancestors = id(new PhrictionDocumentQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withSlugs($ancestor_slugs)
|
||||||
|
->execute();
|
||||||
|
$ancestor_phids = mpull($ancestors, 'getPHID', 'getSlug');
|
||||||
|
$ancestor_handles = $viewer->loadHandles($ancestor_phids);
|
||||||
|
$ancestor_handles = iterator_to_array($ancestor_handles);
|
||||||
|
$ancestor_handles = mpull($ancestor_handles, null, 'getPHID');
|
||||||
|
|
||||||
|
foreach ($ancestor_map as $key => $document_ancestor_slugs) {
|
||||||
|
$document_ancestor_phids = array_select_keys(
|
||||||
|
$ancestor_phids,
|
||||||
|
$document_ancestor_slugs);
|
||||||
|
$ancestor_map[$key] = array_select_keys(
|
||||||
|
$ancestor_handles,
|
||||||
|
$document_ancestor_phids);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ancestor_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -115,3 +115,24 @@
|
||||||
.hovercard-task-view .phui-oi-disabled.phui-workcard {
|
.hovercard-task-view .phui-oi-disabled.phui-workcard {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.phui-hovercard-object-type {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phui-hovercard-object-type .phui-icon-view {
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phui-hovercard-object-type .phui-crumb-divider {
|
||||||
|
margin: 0px 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phui-hovercard-object-type .phabricator-handle-tag-list {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phui-hovercard-object-type .phabricator-handle-tag-list-item {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 4px 2px 0;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue