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:
parent
a15b0063df
commit
9d716379a3
6 changed files with 169 additions and 0 deletions
|
@ -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}/";
|
||||
|
|
|
@ -63,4 +63,11 @@ abstract class PhabricatorDashboardPanelType extends Phobject {
|
|||
return array();
|
||||
}
|
||||
|
||||
public function newHeaderEditActions(
|
||||
PhabricatorDashboardPanel $panel,
|
||||
PhabricatorUser $viewer,
|
||||
$context_phid) {
|
||||
return array();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 )------------------------- */
|
||||
|
||||
|
|
|
@ -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'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue