mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-18 12:52:42 +01:00
Allow search results to be snippeted, roughly
Summary: Ref T8646. This is fairly rough: This interface is very niche, and not really flexible enough to accommodate other result customization (but I don't think we have any plans here)? I'm just //summarizing// the content of documents, basically showing the first paragraph of their content, summary, etc. This isn't what Google does: it shows snippets surrounding the actual search terms. However, this is more involved and might be less useful in structured data: for example, I'd imagine that the first line of most phriciton documents, maniphest tasks and Differential revisions really might be the best machine-generatable summary of them. The actual contextual snippeting in Google doesn't often seem hugely useful to me. But this might also not be very useful. There's not much design, not sure if you had any ideas. I only implemented this for tasks, revisions and the wiki since those seem most useful. I'm generally on the fence about this, but it's not a ton of work to swap out for something else later. Maybe we can see how it feels? But happy to toss it or rethink the approach. Test Plan: {F788026} Reviewers: chad Reviewed By: chad Maniphest Tasks: T8646 Differential Revision: https://secure.phabricator.com/D14095
This commit is contained in:
parent
ae0348aac9
commit
1583738842
9 changed files with 111 additions and 26 deletions
|
@ -11,7 +11,7 @@ return array(
|
||||||
'core.pkg.js' => '47dc9ebb',
|
'core.pkg.js' => '47dc9ebb',
|
||||||
'darkconsole.pkg.js' => 'e7393ebb',
|
'darkconsole.pkg.js' => 'e7393ebb',
|
||||||
'differential.pkg.css' => '2de124c9',
|
'differential.pkg.css' => '2de124c9',
|
||||||
'differential.pkg.js' => '6223dd9d',
|
'differential.pkg.js' => '52d725be',
|
||||||
'diffusion.pkg.css' => '385e85b3',
|
'diffusion.pkg.css' => '385e85b3',
|
||||||
'diffusion.pkg.js' => '0115b37c',
|
'diffusion.pkg.js' => '0115b37c',
|
||||||
'maniphest.pkg.css' => '4845691a',
|
'maniphest.pkg.css' => '4845691a',
|
||||||
|
@ -99,7 +99,7 @@ return array(
|
||||||
'rsrc/css/application/releeph/releeph-preview-branch.css' => 'b7a6f4a5',
|
'rsrc/css/application/releeph/releeph-preview-branch.css' => 'b7a6f4a5',
|
||||||
'rsrc/css/application/releeph/releeph-request-differential-create-dialog.css' => '8d8b92cd',
|
'rsrc/css/application/releeph/releeph-request-differential-create-dialog.css' => '8d8b92cd',
|
||||||
'rsrc/css/application/releeph/releeph-request-typeahead.css' => '667a48ae',
|
'rsrc/css/application/releeph/releeph-request-typeahead.css' => '667a48ae',
|
||||||
'rsrc/css/application/search/search-results.css' => '7dea472c',
|
'rsrc/css/application/search/search-results.css' => '586db3a4',
|
||||||
'rsrc/css/application/slowvote/slowvote.css' => '475b4bd2',
|
'rsrc/css/application/slowvote/slowvote.css' => '475b4bd2',
|
||||||
'rsrc/css/application/tokens/tokens.css' => '3d0f239e',
|
'rsrc/css/application/tokens/tokens.css' => '3d0f239e',
|
||||||
'rsrc/css/application/uiexample/example.css' => '528b19de',
|
'rsrc/css/application/uiexample/example.css' => '528b19de',
|
||||||
|
@ -357,13 +357,13 @@ return array(
|
||||||
'rsrc/js/application/dashboard/behavior-dashboard-query-panel-select.js' => '453c5375',
|
'rsrc/js/application/dashboard/behavior-dashboard-query-panel-select.js' => '453c5375',
|
||||||
'rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js' => 'd4eecc63',
|
'rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js' => 'd4eecc63',
|
||||||
'rsrc/js/application/differential/ChangesetViewManager.js' => '58562350',
|
'rsrc/js/application/differential/ChangesetViewManager.js' => '58562350',
|
||||||
'rsrc/js/application/differential/DifferentialInlineCommentEditor.js' => '64a5550f',
|
'rsrc/js/application/differential/DifferentialInlineCommentEditor.js' => 'd4c87bf4',
|
||||||
'rsrc/js/application/differential/behavior-add-reviewers-and-ccs.js' => 'e10f8e18',
|
'rsrc/js/application/differential/behavior-add-reviewers-and-ccs.js' => 'e10f8e18',
|
||||||
'rsrc/js/application/differential/behavior-comment-jump.js' => '4fdb476d',
|
'rsrc/js/application/differential/behavior-comment-jump.js' => '4fdb476d',
|
||||||
'rsrc/js/application/differential/behavior-comment-preview.js' => 'b064af76',
|
'rsrc/js/application/differential/behavior-comment-preview.js' => 'b064af76',
|
||||||
'rsrc/js/application/differential/behavior-diff-radios.js' => 'e1ff79b1',
|
'rsrc/js/application/differential/behavior-diff-radios.js' => 'e1ff79b1',
|
||||||
'rsrc/js/application/differential/behavior-dropdown-menus.js' => '2035b9cb',
|
'rsrc/js/application/differential/behavior-dropdown-menus.js' => '2035b9cb',
|
||||||
'rsrc/js/application/differential/behavior-edit-inline-comments.js' => '65ef6074',
|
'rsrc/js/application/differential/behavior-edit-inline-comments.js' => '037b59eb',
|
||||||
'rsrc/js/application/differential/behavior-keyboard-nav.js' => '2c426492',
|
'rsrc/js/application/differential/behavior-keyboard-nav.js' => '2c426492',
|
||||||
'rsrc/js/application/differential/behavior-populate.js' => '8694b1df',
|
'rsrc/js/application/differential/behavior-populate.js' => '8694b1df',
|
||||||
'rsrc/js/application/differential/behavior-toggle-files.js' => 'ca3f91eb',
|
'rsrc/js/application/differential/behavior-toggle-files.js' => 'ca3f91eb',
|
||||||
|
@ -517,7 +517,7 @@ return array(
|
||||||
'conpherence-widget-pane-css' => '775eaaba',
|
'conpherence-widget-pane-css' => '775eaaba',
|
||||||
'differential-changeset-view-css' => 'b6b0d1bb',
|
'differential-changeset-view-css' => 'b6b0d1bb',
|
||||||
'differential-core-view-css' => '7ac3cabc',
|
'differential-core-view-css' => '7ac3cabc',
|
||||||
'differential-inline-comment-editor' => '64a5550f',
|
'differential-inline-comment-editor' => 'd4c87bf4',
|
||||||
'differential-revision-add-comment-css' => 'c47f8c40',
|
'differential-revision-add-comment-css' => 'c47f8c40',
|
||||||
'differential-revision-comment-css' => '14b8565a',
|
'differential-revision-comment-css' => '14b8565a',
|
||||||
'differential-revision-history-css' => '0e8eb855',
|
'differential-revision-history-css' => '0e8eb855',
|
||||||
|
@ -568,7 +568,7 @@ return array(
|
||||||
'javelin-behavior-differential-comment-jump' => '4fdb476d',
|
'javelin-behavior-differential-comment-jump' => '4fdb476d',
|
||||||
'javelin-behavior-differential-diff-radios' => 'e1ff79b1',
|
'javelin-behavior-differential-diff-radios' => 'e1ff79b1',
|
||||||
'javelin-behavior-differential-dropdown-menus' => '2035b9cb',
|
'javelin-behavior-differential-dropdown-menus' => '2035b9cb',
|
||||||
'javelin-behavior-differential-edit-inline-comments' => '65ef6074',
|
'javelin-behavior-differential-edit-inline-comments' => '037b59eb',
|
||||||
'javelin-behavior-differential-feedback-preview' => 'b064af76',
|
'javelin-behavior-differential-feedback-preview' => 'b064af76',
|
||||||
'javelin-behavior-differential-keyboard-navigation' => '2c426492',
|
'javelin-behavior-differential-keyboard-navigation' => '2c426492',
|
||||||
'javelin-behavior-differential-populate' => '8694b1df',
|
'javelin-behavior-differential-populate' => '8694b1df',
|
||||||
|
@ -738,7 +738,7 @@ return array(
|
||||||
'phabricator-phtize' => 'd254d646',
|
'phabricator-phtize' => 'd254d646',
|
||||||
'phabricator-prefab' => '6920d200',
|
'phabricator-prefab' => '6920d200',
|
||||||
'phabricator-remarkup-css' => '1c4ac273',
|
'phabricator-remarkup-css' => '1c4ac273',
|
||||||
'phabricator-search-results-css' => '7dea472c',
|
'phabricator-search-results-css' => '586db3a4',
|
||||||
'phabricator-shaped-request' => '7cbe244b',
|
'phabricator-shaped-request' => '7cbe244b',
|
||||||
'phabricator-side-menu-view-css' => 'bec2458e',
|
'phabricator-side-menu-view-css' => 'bec2458e',
|
||||||
'phabricator-slowvote-css' => '475b4bd2',
|
'phabricator-slowvote-css' => '475b4bd2',
|
||||||
|
@ -853,6 +853,14 @@ return array(
|
||||||
'javelin-behavior-device',
|
'javelin-behavior-device',
|
||||||
'phabricator-title',
|
'phabricator-title',
|
||||||
),
|
),
|
||||||
|
'037b59eb' => array(
|
||||||
|
'javelin-behavior',
|
||||||
|
'javelin-stratcom',
|
||||||
|
'javelin-dom',
|
||||||
|
'javelin-util',
|
||||||
|
'javelin-vector',
|
||||||
|
'differential-inline-comment-editor',
|
||||||
|
),
|
||||||
'048330fa' => array(
|
'048330fa' => array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-typeahead-ondemand-source',
|
'javelin-typeahead-ondemand-source',
|
||||||
|
@ -1281,22 +1289,6 @@ return array(
|
||||||
'javelin-workflow',
|
'javelin-workflow',
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
),
|
),
|
||||||
'64a5550f' => array(
|
|
||||||
'javelin-dom',
|
|
||||||
'javelin-util',
|
|
||||||
'javelin-stratcom',
|
|
||||||
'javelin-install',
|
|
||||||
'javelin-request',
|
|
||||||
'javelin-workflow',
|
|
||||||
),
|
|
||||||
'65ef6074' => array(
|
|
||||||
'javelin-behavior',
|
|
||||||
'javelin-stratcom',
|
|
||||||
'javelin-dom',
|
|
||||||
'javelin-util',
|
|
||||||
'javelin-vector',
|
|
||||||
'differential-inline-comment-editor',
|
|
||||||
),
|
|
||||||
'665cf6ac' => array(
|
'665cf6ac' => array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-util',
|
'javelin-util',
|
||||||
|
@ -1825,6 +1817,14 @@ return array(
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
'javelin-view',
|
'javelin-view',
|
||||||
),
|
),
|
||||||
|
'd4c87bf4' => array(
|
||||||
|
'javelin-dom',
|
||||||
|
'javelin-util',
|
||||||
|
'javelin-stratcom',
|
||||||
|
'javelin-install',
|
||||||
|
'javelin-request',
|
||||||
|
'javelin-workflow',
|
||||||
|
),
|
||||||
'd4eecc63' => array(
|
'd4eecc63' => array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
|
|
|
@ -2840,6 +2840,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorSearchResultView' => 'applications/search/view/PhabricatorSearchResultView.php',
|
'PhabricatorSearchResultView' => 'applications/search/view/PhabricatorSearchResultView.php',
|
||||||
'PhabricatorSearchSelectController' => 'applications/search/controller/PhabricatorSearchSelectController.php',
|
'PhabricatorSearchSelectController' => 'applications/search/controller/PhabricatorSearchSelectController.php',
|
||||||
'PhabricatorSearchSelectField' => 'applications/search/field/PhabricatorSearchSelectField.php',
|
'PhabricatorSearchSelectField' => 'applications/search/field/PhabricatorSearchSelectField.php',
|
||||||
|
'PhabricatorSearchSnippetInterface' => 'applications/search/interface/PhabricatorSearchSnippetInterface.php',
|
||||||
'PhabricatorSearchStringListField' => 'applications/search/field/PhabricatorSearchStringListField.php',
|
'PhabricatorSearchStringListField' => 'applications/search/field/PhabricatorSearchStringListField.php',
|
||||||
'PhabricatorSearchSubscribersField' => 'applications/search/field/PhabricatorSearchSubscribersField.php',
|
'PhabricatorSearchSubscribersField' => 'applications/search/field/PhabricatorSearchSubscribersField.php',
|
||||||
'PhabricatorSearchTextField' => 'applications/search/field/PhabricatorSearchTextField.php',
|
'PhabricatorSearchTextField' => 'applications/search/field/PhabricatorSearchTextField.php',
|
||||||
|
@ -4132,6 +4133,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorMentionableInterface',
|
'PhabricatorMentionableInterface',
|
||||||
'PhabricatorDestructibleInterface',
|
'PhabricatorDestructibleInterface',
|
||||||
'PhabricatorProjectInterface',
|
'PhabricatorProjectInterface',
|
||||||
|
'PhabricatorSearchSnippetInterface',
|
||||||
),
|
),
|
||||||
'DifferentialRevisionAffectedFilesHeraldField' => 'DifferentialRevisionHeraldField',
|
'DifferentialRevisionAffectedFilesHeraldField' => 'DifferentialRevisionHeraldField',
|
||||||
'DifferentialRevisionAuthorHeraldField' => 'DifferentialRevisionHeraldField',
|
'DifferentialRevisionAuthorHeraldField' => 'DifferentialRevisionHeraldField',
|
||||||
|
@ -5025,6 +5027,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorApplicationTransactionInterface',
|
'PhabricatorApplicationTransactionInterface',
|
||||||
'PhabricatorProjectInterface',
|
'PhabricatorProjectInterface',
|
||||||
'PhabricatorSpacesInterface',
|
'PhabricatorSpacesInterface',
|
||||||
|
'PhabricatorSearchSnippetInterface',
|
||||||
),
|
),
|
||||||
'ManiphestTaskAssignHeraldAction' => 'HeraldAction',
|
'ManiphestTaskAssignHeraldAction' => 'HeraldAction',
|
||||||
'ManiphestTaskAssignOtherHeraldAction' => 'ManiphestTaskAssignHeraldAction',
|
'ManiphestTaskAssignOtherHeraldAction' => 'ManiphestTaskAssignHeraldAction',
|
||||||
|
@ -7623,6 +7626,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorTokenReceiverInterface',
|
'PhabricatorTokenReceiverInterface',
|
||||||
'PhabricatorDestructibleInterface',
|
'PhabricatorDestructibleInterface',
|
||||||
'PhabricatorApplicationTransactionInterface',
|
'PhabricatorApplicationTransactionInterface',
|
||||||
|
'PhabricatorSearchSnippetInterface',
|
||||||
),
|
),
|
||||||
'PhrictionDocumentAuthorHeraldField' => 'PhrictionDocumentHeraldField',
|
'PhrictionDocumentAuthorHeraldField' => 'PhrictionDocumentHeraldField',
|
||||||
'PhrictionDocumentContentHeraldField' => 'PhrictionDocumentHeraldField',
|
'PhrictionDocumentContentHeraldField' => 'PhrictionDocumentHeraldField',
|
||||||
|
|
|
@ -13,7 +13,8 @@ final class DifferentialRevision extends DifferentialDAO
|
||||||
PhabricatorApplicationTransactionInterface,
|
PhabricatorApplicationTransactionInterface,
|
||||||
PhabricatorMentionableInterface,
|
PhabricatorMentionableInterface,
|
||||||
PhabricatorDestructibleInterface,
|
PhabricatorDestructibleInterface,
|
||||||
PhabricatorProjectInterface {
|
PhabricatorProjectInterface,
|
||||||
|
PhabricatorSearchSnippetInterface {
|
||||||
|
|
||||||
protected $title = '';
|
protected $title = '';
|
||||||
protected $originalTitle;
|
protected $originalTitle;
|
||||||
|
@ -629,4 +630,18 @@ final class DifferentialRevision extends DifferentialDAO
|
||||||
$this->saveTransaction();
|
$this->saveTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -( PhabricatorSearchSnippetInterface )---------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
public function renderSearchResultSnippet(PhabricatorUser $viewer) {
|
||||||
|
$content = $this->getSummary();
|
||||||
|
$content = PhabricatorMarkupEngine::summarize($content);
|
||||||
|
$content = PhabricatorMarkupEngine::renderOneObject(
|
||||||
|
id(new PhabricatorMarkupOneOff())->setContent($content),
|
||||||
|
'default',
|
||||||
|
$viewer);
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,8 @@ final class ManiphestTask extends ManiphestDAO
|
||||||
PhabricatorDestructibleInterface,
|
PhabricatorDestructibleInterface,
|
||||||
PhabricatorApplicationTransactionInterface,
|
PhabricatorApplicationTransactionInterface,
|
||||||
PhabricatorProjectInterface,
|
PhabricatorProjectInterface,
|
||||||
PhabricatorSpacesInterface {
|
PhabricatorSpacesInterface,
|
||||||
|
PhabricatorSearchSnippetInterface {
|
||||||
|
|
||||||
const MARKUP_FIELD_DESCRIPTION = 'markup:desc';
|
const MARKUP_FIELD_DESCRIPTION = 'markup:desc';
|
||||||
|
|
||||||
|
@ -390,4 +391,18 @@ final class ManiphestTask extends ManiphestDAO
|
||||||
return $this->spacePHID;
|
return $this->spacePHID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -( PhabricatorSearchSnippetInterface )---------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
public function renderSearchResultSnippet(PhabricatorUser $viewer) {
|
||||||
|
$content = $this->getDescription();
|
||||||
|
$content = PhabricatorMarkupEngine::summarize($content);
|
||||||
|
$content = PhabricatorMarkupEngine::renderOneObject(
|
||||||
|
id(new PhabricatorMarkupOneOff())->setContent($content),
|
||||||
|
'default',
|
||||||
|
$viewer);
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,8 @@ final class PhrictionDocument extends PhrictionDAO
|
||||||
PhabricatorFlaggableInterface,
|
PhabricatorFlaggableInterface,
|
||||||
PhabricatorTokenReceiverInterface,
|
PhabricatorTokenReceiverInterface,
|
||||||
PhabricatorDestructibleInterface,
|
PhabricatorDestructibleInterface,
|
||||||
PhabricatorApplicationTransactionInterface {
|
PhabricatorApplicationTransactionInterface,
|
||||||
|
PhabricatorSearchSnippetInterface {
|
||||||
|
|
||||||
protected $slug;
|
protected $slug;
|
||||||
protected $depth;
|
protected $depth;
|
||||||
|
@ -252,4 +253,19 @@ final class PhrictionDocument extends PhrictionDAO
|
||||||
$this->saveTransaction();
|
$this->saveTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -( PhabricatorSearchSnippetInterface )---------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
public function renderSearchResultSnippet(PhabricatorUser $viewer) {
|
||||||
|
$content = $this->getContent()->getContent();
|
||||||
|
$content = PhabricatorMarkupEngine::summarize($content);
|
||||||
|
$content = PhabricatorMarkupEngine::renderOneObject(
|
||||||
|
id(new PhabricatorMarkupOneOff())->setContent($content),
|
||||||
|
'default',
|
||||||
|
$viewer);
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Objects can implement this interface to provide text snippets in search
|
||||||
|
* result views.
|
||||||
|
*/
|
||||||
|
interface PhabricatorSearchSnippetInterface {
|
||||||
|
|
||||||
|
public function renderSearchResultSnippet(PhabricatorUser $viewer);
|
||||||
|
|
||||||
|
}
|
|
@ -251,6 +251,7 @@ final class PhabricatorSearchApplicationSearchEngine
|
||||||
|
|
||||||
foreach ($results as $phid => $handle) {
|
foreach ($results as $phid => $handle) {
|
||||||
$view = id(new PhabricatorSearchResultView())
|
$view = id(new PhabricatorSearchResultView())
|
||||||
|
->setUser($viewer)
|
||||||
->setHandle($handle)
|
->setHandle($handle)
|
||||||
->setQuery($query)
|
->setQuery($query)
|
||||||
->setObject(idx($objects, $phid))
|
->setObject(idx($objects, $phid))
|
||||||
|
|
|
@ -21,7 +21,13 @@ final class PhabricatorSearchResultView extends AphrontView {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getObject() {
|
||||||
|
return $this->object;
|
||||||
|
}
|
||||||
|
|
||||||
public function render() {
|
public function render() {
|
||||||
|
$viewer = $this->getUser();
|
||||||
|
|
||||||
$handle = $this->handle;
|
$handle = $this->handle;
|
||||||
if (!$handle->isComplete()) {
|
if (!$handle->isComplete()) {
|
||||||
return;
|
return;
|
||||||
|
@ -46,6 +52,18 @@ final class PhabricatorSearchResultView extends AphrontView {
|
||||||
$item->addAttribute(pht('Closed'));
|
$item->addAttribute(pht('Closed'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$object = $this->getObject();
|
||||||
|
if ($object instanceof PhabricatorSearchSnippetInterface) {
|
||||||
|
$snippet = $object->renderSearchResultSnippet($viewer);
|
||||||
|
$snippet = phutil_tag(
|
||||||
|
'div',
|
||||||
|
array(
|
||||||
|
'class' => 'phui-search-snippet',
|
||||||
|
),
|
||||||
|
$snippet);
|
||||||
|
$item->appendChild($snippet);
|
||||||
|
}
|
||||||
|
|
||||||
return $item;
|
return $item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,3 +16,8 @@
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
color: #000;
|
color: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.phui-search-snippet {
|
||||||
|
margin: 0 8px;
|
||||||
|
color: {$greytext};
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue