1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-10 08:52:39 +01:00

Rough skeleton of a "Query" dashboard panel

Summary: Ref T4986. This isn't pretty/usable yet (I need to move rendering out of ListController classes and into SearchEngine classes, I think) but does pull the correct results.

Test Plan: {F151537}

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T4986

Differential Revision: https://secure.phabricator.com/D9007
This commit is contained in:
epriestley 2014-05-07 14:56:30 -07:00
parent 094026f64a
commit d30f43b15b
5 changed files with 132 additions and 9 deletions

View file

@ -1463,6 +1463,7 @@ phutil_register_library_map(array(
'PhabricatorDashboardPanelTransactionEditor' => 'applications/dashboard/editor/PhabricatorDashboardPanelTransactionEditor.php', 'PhabricatorDashboardPanelTransactionEditor' => 'applications/dashboard/editor/PhabricatorDashboardPanelTransactionEditor.php',
'PhabricatorDashboardPanelTransactionQuery' => 'applications/dashboard/query/PhabricatorDashboardPanelTransactionQuery.php', 'PhabricatorDashboardPanelTransactionQuery' => 'applications/dashboard/query/PhabricatorDashboardPanelTransactionQuery.php',
'PhabricatorDashboardPanelType' => 'applications/dashboard/paneltype/PhabricatorDashboardPanelType.php', 'PhabricatorDashboardPanelType' => 'applications/dashboard/paneltype/PhabricatorDashboardPanelType.php',
'PhabricatorDashboardPanelTypeQuery' => 'applications/dashboard/paneltype/PhabricatorDashboardPanelTypeQuery.php',
'PhabricatorDashboardPanelTypeText' => 'applications/dashboard/paneltype/PhabricatorDashboardPanelTypeText.php', 'PhabricatorDashboardPanelTypeText' => 'applications/dashboard/paneltype/PhabricatorDashboardPanelTypeText.php',
'PhabricatorDashboardPanelViewController' => 'applications/dashboard/controller/PhabricatorDashboardPanelViewController.php', 'PhabricatorDashboardPanelViewController' => 'applications/dashboard/controller/PhabricatorDashboardPanelViewController.php',
'PhabricatorDashboardQuery' => 'applications/dashboard/query/PhabricatorDashboardQuery.php', 'PhabricatorDashboardQuery' => 'applications/dashboard/query/PhabricatorDashboardQuery.php',
@ -4306,6 +4307,7 @@ phutil_register_library_map(array(
'PhabricatorDashboardPanelTransactionEditor' => 'PhabricatorApplicationTransactionEditor', 'PhabricatorDashboardPanelTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorDashboardPanelTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhabricatorDashboardPanelTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorDashboardPanelType' => 'Phobject', 'PhabricatorDashboardPanelType' => 'Phobject',
'PhabricatorDashboardPanelTypeQuery' => 'PhabricatorDashboardPanelType',
'PhabricatorDashboardPanelTypeText' => 'PhabricatorDashboardPanelType', 'PhabricatorDashboardPanelTypeText' => 'PhabricatorDashboardPanelType',
'PhabricatorDashboardPanelViewController' => 'PhabricatorDashboardController', 'PhabricatorDashboardPanelViewController' => 'PhabricatorDashboardController',
'PhabricatorDashboardQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorDashboardQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',

View file

@ -50,8 +50,16 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
} }
} }
try {
return $panel_type->renderPanel($viewer, $panel); return $panel_type->renderPanel($viewer, $panel);
} catch (Exception $ex) {
return $this->renderErrorPanel(
$panel->getName(),
pht(
'%s: %s',
phutil_tag('strong', array(), get_class($ex)),
$ex->getMessage()));
}
} }
private function renderErrorPanel($title, $body) { private function renderErrorPanel($title, $body) {

View file

@ -0,0 +1,82 @@
<?php
final class PhabricatorDashboardPanelTypeQuery
extends PhabricatorDashboardPanelType {
public function getPanelTypeKey() {
return 'query';
}
public function getPanelTypeName() {
return pht('Query Panel');
}
public function getPanelTypeDescription() {
return pht(
'Show results of a search query, like the most recently filed tasks or '.
'revisions you need to review.');
}
public function getFieldSpecifications() {
return array(
'class' => array(
'name' => pht('ApplicationSearch Class'),
'type' => 'text',
),
'key' => array(
'name' => pht('ApplicationSearch Key'),
'type' => 'text',
),
);
}
protected function renderPanelContent(
PhabricatorUser $viewer,
PhabricatorDashboardPanel $panel) {
$class = $panel->getProperty('class');
$engine = PhabricatorApplicationSearchEngine::getEngineByClassName($class);
if (!$engine) {
throw new Exception(
pht(
'The application search engine "%s" is not known to Phabricator!',
$class));
}
$engine->setViewer($viewer);
$key = $panel->getProperty('key');
if ($engine->isBuiltinQuery($key)) {
$saved = $engine->buildSavedQueryFromBuiltin($key);
} else {
$saved = id(new PhabricatorSavedQueryQuery())
->setViewer($viewer)
->withEngineClassNames(array($class))
->withQueryKeys(array($key))
->executeOne();
}
if (!$saved) {
throw new Exception(
pht(
'Query "%s" is unknown to application search engine "%s"!',
$key,
$class));
}
$query = $engine->buildQueryFromSavedQuery($saved);
$results = $query
->setViewer($viewer)
->execute();
$out = array();
foreach ($results as $result) {
$out[] = phutil_tag('div', array(), $result->getPHID());
}
return $out;
}
}

View file

@ -4,10 +4,11 @@
* Represents an abstract search engine for an application. It supports * Represents an abstract search engine for an application. It supports
* creating and storing saved queries. * creating and storing saved queries.
* *
* @task builtin Builtin Queries * @task construct Constructing Engines
* @task uri Query URIs * @task builtin Builtin Queries
* @task dates Date Filters * @task uri Query URIs
* @task read Reading Utilities * @task dates Date Filters
* @task read Reading Utilities
* *
* @group search * @group search
*/ */
@ -174,6 +175,36 @@ abstract class PhabricatorApplicationSearchEngine {
} }
/* -( Constructing Engines )----------------------------------------------- */
/**
* Load all available application search engines.
*
* @return list<PhabricatorApplicationSearchEngine> All available engines.
* @task construct
*/
public static function getAllEngines() {
$engines = id(new PhutilSymbolLoader())
->setAncestorClass(__CLASS__)
->loadObjects();
return $engines;
}
/**
* Get an engine by class name, if it exists.
*
* @return PhabricatorApplicationSearchEngine|null Engine, or null if it does
* not exist.
* @task construct
*/
public static function getEngineByClassName($class_name) {
return idx(self::getAllEngines(), $class_name);
}
/* -( Builtin Queries )---------------------------------------------------- */ /* -( Builtin Queries )---------------------------------------------------- */

View file

@ -40,21 +40,21 @@ final class PhabricatorSavedQueryQuery
private function buildWhereClause($conn_r) { private function buildWhereClause($conn_r) {
$where = array(); $where = array();
if ($this->ids) { if ($this->ids !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn_r, $conn_r,
'id IN (%Ld)', 'id IN (%Ld)',
$this->ids); $this->ids);
} }
if ($this->engineClassNames) { if ($this->engineClassNames !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn_r, $conn_r,
'engineClassName IN (%Ls)', 'engineClassName IN (%Ls)',
$this->engineClassNames); $this->engineClassNames);
} }
if ($this->queryKeys) { if ($this->queryKeys !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn_r, $conn_r,
'queryKey IN (%Ls)', 'queryKey IN (%Ls)',