1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-22 14:52:41 +01:00

Add a rough Quick Search datasource for Phriction documents

Summary:
Depends on D19106. Fixes T5941. Ref T13077. Allows you to find Phriction documents as suggestions from global quick search.

Also supports `w` to jump to Phriction and `w query` to query Phriction.

The actual query logic for the datasource may need some tweaking after it collides with reality, but seems to produce fairly reasonable results in local testing against synthetic data.

Test Plan: Searched for "Porcupine Facts", "Travel Companions", and other useful local pages. Searched for `w`. Searched for `w zebra facts`.

Maniphest Tasks: T13077, T5941

Differential Revision: https://secure.phabricator.com/D19107
This commit is contained in:
epriestley 2018-02-16 07:09:17 -08:00
parent b8bb4d3ad5
commit f82206a4d1
6 changed files with 167 additions and 14 deletions

View file

@ -10,7 +10,7 @@ return array(
'conpherence.pkg.css' => 'e68cf1fa',
'conpherence.pkg.js' => '15191c65',
'core.pkg.css' => 'e4f098a5',
'core.pkg.js' => '3ac6e174',
'core.pkg.js' => 'bd19de1c',
'darkconsole.pkg.js' => '1f9a31bc',
'differential.pkg.css' => '113e692c',
'differential.pkg.js' => 'f6d809c0',
@ -506,7 +506,7 @@ return array(
'rsrc/js/core/behavior-reorder-applications.js' => '76b9fc3e',
'rsrc/js/core/behavior-reveal-content.js' => '60821bc7',
'rsrc/js/core/behavior-scrollbar.js' => '834a1173',
'rsrc/js/core/behavior-search-typeahead.js' => 'd0a99ab4',
'rsrc/js/core/behavior-search-typeahead.js' => 'c3e917d9',
'rsrc/js/core/behavior-select-content.js' => 'bf5374ef',
'rsrc/js/core/behavior-select-on-click.js' => '4e3e79a6',
'rsrc/js/core/behavior-setup-check-https.js' => '491416b3',
@ -663,7 +663,7 @@ return array(
'javelin-behavior-phabricator-oncopy' => '2926fff2',
'javelin-behavior-phabricator-remarkup-assist' => 'acd29eee',
'javelin-behavior-phabricator-reveal-content' => '60821bc7',
'javelin-behavior-phabricator-search-typeahead' => 'd0a99ab4',
'javelin-behavior-phabricator-search-typeahead' => 'c3e917d9',
'javelin-behavior-phabricator-show-older-transactions' => '8f29b364',
'javelin-behavior-phabricator-tooltips' => 'c420b0b9',
'javelin-behavior-phabricator-transaction-comment-form' => 'b23b49e6',
@ -1918,6 +1918,17 @@ return array(
'javelin-dom',
'javelin-vector',
),
'c3e917d9' => array(
'javelin-behavior',
'javelin-typeahead-ondemand-source',
'javelin-typeahead',
'javelin-dom',
'javelin-uri',
'javelin-util',
'javelin-stratcom',
'phabricator-prefab',
'phuix-icon-view',
),
'c420b0b9' => array(
'javelin-behavior',
'javelin-behavior-device',
@ -1969,17 +1980,6 @@ return array(
'phabricator-notification',
'conpherence-thread-manager',
),
'd0a99ab4' => array(
'javelin-behavior',
'javelin-typeahead-ondemand-source',
'javelin-typeahead',
'javelin-dom',
'javelin-uri',
'javelin-util',
'javelin-stratcom',
'phabricator-prefab',
'phuix-icon-view',
),
'd0c516d5' => array(
'javelin-behavior',
'javelin-dom',

View file

@ -4855,6 +4855,7 @@ phutil_register_library_map(array(
'PhrictionController' => 'applications/phriction/controller/PhrictionController.php',
'PhrictionCreateConduitAPIMethod' => 'applications/phriction/conduit/PhrictionCreateConduitAPIMethod.php',
'PhrictionDAO' => 'applications/phriction/storage/PhrictionDAO.php',
'PhrictionDatasourceEngineExtension' => 'applications/phriction/engineextension/PhrictionDatasourceEngineExtension.php',
'PhrictionDeleteController' => 'applications/phriction/controller/PhrictionDeleteController.php',
'PhrictionDiffController' => 'applications/phriction/controller/PhrictionDiffController.php',
'PhrictionDocument' => 'applications/phriction/storage/PhrictionDocument.php',
@ -4862,6 +4863,7 @@ phutil_register_library_map(array(
'PhrictionDocumentContentHeraldField' => 'applications/phriction/herald/PhrictionDocumentContentHeraldField.php',
'PhrictionDocumentContentTransaction' => 'applications/phriction/xaction/PhrictionDocumentContentTransaction.php',
'PhrictionDocumentController' => 'applications/phriction/controller/PhrictionDocumentController.php',
'PhrictionDocumentDatasource' => 'applications/phriction/typeahead/PhrictionDocumentDatasource.php',
'PhrictionDocumentDeleteTransaction' => 'applications/phriction/xaction/PhrictionDocumentDeleteTransaction.php',
'PhrictionDocumentFerretEngine' => 'applications/phriction/search/PhrictionDocumentFerretEngine.php',
'PhrictionDocumentFulltextEngine' => 'applications/phriction/search/PhrictionDocumentFulltextEngine.php',
@ -10777,6 +10779,7 @@ phutil_register_library_map(array(
'PhrictionController' => 'PhabricatorController',
'PhrictionCreateConduitAPIMethod' => 'PhrictionConduitAPIMethod',
'PhrictionDAO' => 'PhabricatorLiskDAO',
'PhrictionDatasourceEngineExtension' => 'PhabricatorDatasourceEngineExtension',
'PhrictionDeleteController' => 'PhrictionController',
'PhrictionDiffController' => 'PhrictionController',
'PhrictionDocument' => array(
@ -10796,6 +10799,7 @@ phutil_register_library_map(array(
'PhrictionDocumentContentHeraldField' => 'PhrictionDocumentHeraldField',
'PhrictionDocumentContentTransaction' => 'PhrictionDocumentTransactionType',
'PhrictionDocumentController' => 'PhrictionController',
'PhrictionDocumentDatasource' => 'PhabricatorTypeaheadDatasource',
'PhrictionDocumentDeleteTransaction' => 'PhrictionDocumentTransactionType',
'PhrictionDocumentFerretEngine' => 'PhabricatorFerretEngine',
'PhrictionDocumentFulltextEngine' => 'PhabricatorFulltextEngine',

View file

@ -0,0 +1,56 @@
<?php
final class PhrictionDatasourceEngineExtension
extends PhabricatorDatasourceEngineExtension {
public function newQuickSearchDatasources() {
return array(
new PhrictionDocumentDatasource(),
);
}
public function newJumpURI($query) {
$viewer = $this->getViewer();
// Send "w" to Phriction.
if (preg_match('/^w\z/i', $query)) {
return '/w/';
}
// Send "w <string>" to a search for similar wiki documents.
$matches = null;
if (preg_match('/^w\s+(.+)\z/i', $query, $matches)) {
$raw_query = $matches[1];
$engine = id(new PhrictionDocument())
->newFerretEngine();
$compiler = id(new PhutilSearchQueryCompiler())
->setEnableFunctions(true);
$raw_tokens = $compiler->newTokens($raw_query);
$fulltext_tokens = array();
foreach ($raw_tokens as $raw_token) {
$fulltext_token = id(new PhabricatorFulltextToken())
->setToken($raw_token);
$fulltext_tokens[] = $fulltext_token;
}
$documents = id(new PhrictionDocumentQuery())
->setViewer($viewer)
->withFerretConstraint($engine, $fulltext_tokens)
->execute();
if (count($documents) == 1) {
return head($documents)->getURI();
} else {
// More than one match, jump to search.
return urisprintf(
'/phriction/?order=relevance&query=%s#R',
$raw_query);
}
}
return null;
}
}

View file

@ -149,6 +149,10 @@ final class PhrictionDocument extends PhrictionDAO
return $this;
}
public function getURI() {
return self::getSlugURI($this->getSlug());
}
/* -( Status )------------------------------------------------------------- */

View file

@ -0,0 +1,88 @@
<?php
final class PhrictionDocumentDatasource
extends PhabricatorTypeaheadDatasource {
public function getBrowseTitle() {
return pht('Browse Documents');
}
public function getPlaceholderText() {
return pht('Type a document name...');
}
public function getDatasourceApplicationClass() {
return 'PhabricatorPhrictionApplication';
}
public function loadResults() {
$viewer = $this->getViewer();
$raw_query = $this->getRawQuery();
$engine = id(new PhrictionDocument())
->newFerretEngine();
$compiler = id(new PhutilSearchQueryCompiler())
->setEnableFunctions(true);
$raw_tokens = $compiler->newTokens($raw_query);
$fulltext_tokens = array();
foreach ($raw_tokens as $raw_token) {
// This is a little hacky and could maybe be cleaner. We're treating
// every search term as though the user had entered "title:dog" insead
// of "dog".
$alternate_token = PhutilSearchQueryToken::newFromDictionary(
array(
'quoted' => $raw_token->isQuoted(),
'value' => $raw_token->getValue(),
'operator' => PhutilSearchQueryCompiler::OPERATOR_SUBSTRING,
'function' => 'title',
));
$fulltext_token = id(new PhabricatorFulltextToken())
->setToken($alternate_token);
$fulltext_tokens[] = $fulltext_token;
}
$documents = id(new PhrictionDocumentQuery())
->setViewer($viewer)
->withFerretConstraint($engine, $fulltext_tokens)
->needContent(true)
->execute();
$results = array();
foreach ($documents as $document) {
$content = $document->getContent();
if (!$document->isActive()) {
$closed = $document->getStatusDisplayName();
} else {
$closed = null;
}
$slug = $document->getSlug();
$title = $content->getTitle();
$sprite = 'phabricator-search-icon phui-font-fa phui-icon-view fa-book';
$result = id(new PhabricatorTypeaheadResult())
->setName($title)
->setDisplayName($title)
->setURI($document->getURI())
->setPHID($document->getPHID())
->setDisplayType($slug)
->setPriorityType('wiki')
->setImageSprite($sprite)
->setClosed($closed);
$results[] = $result;
}
return $results;
}
}

View file

@ -70,6 +70,7 @@ JX.behavior('phabricator-search-typeahead', function(config) {
'proj',
'user',
'repo',
'wiki',
'symb',
'misc'
];