1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-26 08:42:41 +01:00

Add a "Customize Query" action to query panels to make it easier to make minor query adjustments

Summary:
Depends on D20473. Ref T13272. Fixes T7216. If you want to tweak the query a panel uses, you currently have to complete 7 Great Labors.

Instead, add a "Customize Query" action which lets you update the query inline.

Test Plan: {F6402171}

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13272, T7216

Differential Revision: https://secure.phabricator.com/D20474
This commit is contained in:
epriestley 2019-04-25 11:03:17 -07:00
parent a15b0063df
commit 9d716379a3
6 changed files with 169 additions and 0 deletions

View file

@ -329,6 +329,18 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
$actions = array();
if ($panel) {
$panel_actions = $panel->newHeaderEditActions(
$viewer,
$context_phid);
if ($panel_actions) {
foreach ($panel_actions as $panel_action) {
$actions[] = $panel_action;
}
$actions[] = id(new PhabricatorActionView())
->setType(PhabricatorActionView::TYPE_DIVIDER);
}
$panel_id = $panel->getID();
$edit_uri = "/dashboard/panel/edit/{$panel_id}/";

View file

@ -63,4 +63,11 @@ abstract class PhabricatorDashboardPanelType extends Phobject {
return array();
}
public function newHeaderEditActions(
PhabricatorDashboardPanel $panel,
PhabricatorUser $viewer,
$context_phid) {
return array();
}
}

View file

@ -236,4 +236,26 @@ final class PhabricatorDashboardQueryPanelType
return $engine;
}
public function newHeaderEditActions(
PhabricatorDashboardPanel $panel,
PhabricatorUser $viewer,
$context_phid) {
$actions = array();
$engine = $this->getSearchEngine($panel);
$customize_uri = $engine->getCustomizeURI(
$panel->getProperty('key'),
$panel->getPHID(),
$context_phid);
$actions[] = id(new PhabricatorActionView())
->setIcon('fa-pencil-square-o')
->setName(pht('Customize Query'))
->setWorkflow(true)
->setHref($customize_uri);
return $actions;
}
}

View file

@ -107,6 +107,15 @@ final class PhabricatorDashboardPanel
return $this->requireImplementation()->getEditEngineFields($this);
}
public function newHeaderEditActions(
PhabricatorUser $viewer,
$context_phid) {
return $this->requireImplementation()->newHeaderEditActions(
$this,
$viewer,
$context_phid);
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */

View file

@ -80,6 +80,10 @@ final class PhabricatorApplicationSearchController
return $this->processExportRequest();
}
if ($query_action === 'customize') {
return $this->processCustomizeRequest();
}
$key = $this->getQueryKey();
if ($key == 'edit') {
return $this->processEditRequest();
@ -985,4 +989,106 @@ final class PhabricatorApplicationSearchController
$editor->applyTransactions($preferences, $xactions);
}
private function processCustomizeRequest() {
$viewer = $this->getViewer();
$engine = $this->getSearchEngine();
$request = $this->getRequest();
$object_phid = $request->getStr('search.objectPHID');
$context_phid = $request->getStr('search.contextPHID');
// For now, the object can only be a dashboard panel, so just use a panel
// query explicitly.
$object = id(new PhabricatorDashboardPanelQuery())
->setViewer($viewer)
->withPHIDs(array($object_phid))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$object) {
return new Aphront404Response();
}
$object_name = pht('%s %s', $object->getMonogram(), $object->getName());
// Likewise, the context object can only be a dashboard.
if (strlen($context_phid)) {
$context = id(new PhabricatorDashboardQuery())
->setViewer($viewer)
->withPHIDs(array($context_phid))
->executeOne();
if (!$context) {
return new Aphront404Response();
}
} else {
$context = $object;
}
$done_uri = $context->getURI();
if ($request->isFormPost()) {
$saved_query = $engine->buildSavedQueryFromRequest($request);
$engine->saveQuery($saved_query);
$query_key = $saved_query->getQueryKey();
} else {
$query_key = $this->getQueryKey();
if ($engine->isBuiltinQuery($query_key)) {
$saved_query = $engine->buildSavedQueryFromBuiltin($query_key);
} else if ($query_key) {
$saved_query = id(new PhabricatorSavedQueryQuery())
->setViewer($viewer)
->withQueryKeys(array($query_key))
->executeOne();
} else {
$saved_query = null;
}
}
if (!$saved_query) {
return new Aphront404Response();
}
$form = id(new AphrontFormView())
->setViewer($viewer)
->addHiddenInput('search.objectPHID', $object_phid)
->addHiddenInput('search.contextPHID', $context_phid)
->setAction($request->getPath());
$engine->buildSearchForm($form, $saved_query);
$errors = $engine->getErrors();
if ($request->isFormPost()) {
if (!$errors) {
$xactions = array();
// Since this workflow is currently used only by dashboard panels,
// we can hard-code how the edit works.
$xactions[] = $object->getApplicationTransactionTemplate()
->setTransactionType(
PhabricatorDashboardQueryPanelQueryTransaction::TRANSACTIONTYPE)
->setNewValue($query_key);
$editor = $object->getApplicationTransactionEditor()
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true)
->setContinueOnMissingFields(true);
$editor->applyTransactions($object, $xactions);
return id(new AphrontRedirectResponse())->setURI($done_uri);
}
}
return $this->newDialog()
->setTitle(pht('Customize Query: %s', $object_name))
->setErrors($errors)
->setWidth(AphrontDialogView::WIDTH_FULL)
->appendForm($form)
->addCancelButton($done_uri)
->addSubmitButton(pht('Save Changes'));
}
}

View file

@ -425,6 +425,19 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
return $this->getURI('query/'.$query_key.'/export/');
}
public function getCustomizeURI($query_key, $object_phid, $context_phid) {
$params = array(
'search.objectPHID' => $object_phid,
'search.contextPHID' => $context_phid,
);
$uri = $this->getURI('query/'.$query_key.'/customize/');
$uri = new PhutilURI($uri, $params);
return phutil_string_cast($uri);
}
/**
* Return the URI to a path within the application. Used to construct default