mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-19 12:00:55 +01:00
Implement a "pro" EditEngine for dashboard panels
Summary: Ref T10855. This can't replace the old edit flow yet, but get the basics in place. (This is actually much closer to just being able to swap than I anticipated since CustomFields sort of just work, but the exiting flow has some "clone existing panel" / "place directly on dashboard" stuff that this doesn't yet.) Test Plan: Created and edited a panel by manually using the "editpro" flow. Reviewers: chad Reviewed By: chad Maniphest Tasks: T10855 Differential Revision: https://secure.phabricator.com/D16226
This commit is contained in:
parent
d7b4c50941
commit
fa6d3e2de3
8 changed files with 237 additions and 21 deletions
|
@ -2295,7 +2295,10 @@ phutil_register_library_map(array(
|
|||
'PhabricatorDashboardPanelArchiveController' => 'applications/dashboard/controller/PhabricatorDashboardPanelArchiveController.php',
|
||||
'PhabricatorDashboardPanelCoreCustomField' => 'applications/dashboard/customfield/PhabricatorDashboardPanelCoreCustomField.php',
|
||||
'PhabricatorDashboardPanelCustomField' => 'applications/dashboard/customfield/PhabricatorDashboardPanelCustomField.php',
|
||||
'PhabricatorDashboardPanelEditConduitAPIMethod' => 'applications/dashboard/conduit/PhabricatorDashboardPanelEditConduitAPIMethod.php',
|
||||
'PhabricatorDashboardPanelEditController' => 'applications/dashboard/controller/PhabricatorDashboardPanelEditController.php',
|
||||
'PhabricatorDashboardPanelEditEngine' => 'applications/dashboard/editor/PhabricatorDashboardPanelEditEngine.php',
|
||||
'PhabricatorDashboardPanelEditproController' => 'applications/dashboard/controller/PhabricatorDashboardPanelEditproController.php',
|
||||
'PhabricatorDashboardPanelHasDashboardEdgeType' => 'applications/dashboard/edge/PhabricatorDashboardPanelHasDashboardEdgeType.php',
|
||||
'PhabricatorDashboardPanelListController' => 'applications/dashboard/controller/PhabricatorDashboardPanelListController.php',
|
||||
'PhabricatorDashboardPanelPHIDType' => 'applications/dashboard/phid/PhabricatorDashboardPanelPHIDType.php',
|
||||
|
@ -6942,7 +6945,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorCustomFieldInterface',
|
||||
'PhabricatorFlaggableInterface',
|
||||
'PhabricatorProjectInterface',
|
||||
'PhabricatorDestructibleInterface',
|
||||
),
|
||||
'PhabricatorDashboardPanelArchiveController' => 'PhabricatorDashboardController',
|
||||
|
@ -6951,7 +6953,10 @@ phutil_register_library_map(array(
|
|||
'PhabricatorStandardCustomFieldInterface',
|
||||
),
|
||||
'PhabricatorDashboardPanelCustomField' => 'PhabricatorCustomField',
|
||||
'PhabricatorDashboardPanelEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod',
|
||||
'PhabricatorDashboardPanelEditController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardPanelEditEngine' => 'PhabricatorEditEngine',
|
||||
'PhabricatorDashboardPanelEditproController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardPanelHasDashboardEdgeType' => 'PhabricatorEdgeType',
|
||||
'PhabricatorDashboardPanelListController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardPanelPHIDType' => 'PhabricatorPHIDType',
|
||||
|
|
|
@ -40,6 +40,8 @@ final class PhabricatorDashboardApplication extends PhabricatorApplication {
|
|||
'(?:query/(?P<queryKey>[^/]+)/)?'
|
||||
=> 'PhabricatorDashboardPanelListController',
|
||||
'create/' => 'PhabricatorDashboardPanelEditController',
|
||||
$this->getEditRoutePattern('editpro/')
|
||||
=> 'PhabricatorDashboardPanelEditproController',
|
||||
'edit/(?:(?P<id>\d+)/)?' => 'PhabricatorDashboardPanelEditController',
|
||||
'render/(?P<id>\d+)/' => 'PhabricatorDashboardPanelRenderController',
|
||||
'archive/(?P<id>\d+)/'
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPanelEditConduitAPIMethod
|
||||
extends PhabricatorEditEngineAPIMethod {
|
||||
|
||||
public function getAPIMethodName() {
|
||||
return 'dashboard.panel.edit';
|
||||
}
|
||||
|
||||
public function newEditEngine() {
|
||||
return new PhabricatorDashboardPanelEditEngine();
|
||||
}
|
||||
|
||||
public function getMethodSummary() {
|
||||
return pht(
|
||||
'Apply transactions to create a new dashboard panel or edit an '.
|
||||
'existing one.');
|
||||
}
|
||||
|
||||
}
|
|
@ -51,10 +51,6 @@ final class PhabricatorDashboardPanelEditController
|
|||
if (!$panel) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$v_projects = PhabricatorEdgeQuery::loadDestinationPHIDs(
|
||||
$panel->getPHID(),
|
||||
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
|
||||
$v_projects = array_reverse($v_projects);
|
||||
|
||||
if ($dashboard) {
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
|
@ -84,7 +80,6 @@ final class PhabricatorDashboardPanelEditController
|
|||
if (empty($types[$type])) {
|
||||
return $this->processPanelTypeRequest($request);
|
||||
}
|
||||
$v_projects = array();
|
||||
|
||||
$panel->setPanelType($type);
|
||||
}
|
||||
|
@ -135,7 +130,6 @@ final class PhabricatorDashboardPanelEditController
|
|||
$v_name = $request->getStr('name');
|
||||
$v_view_policy = $request->getStr('viewPolicy');
|
||||
$v_edit_policy = $request->getStr('editPolicy');
|
||||
$v_projects = $request->getArr('projects');
|
||||
|
||||
$type_name = PhabricatorDashboardPanelTransaction::TYPE_NAME;
|
||||
$type_view_policy = PhabricatorTransactions::TYPE_VIEW_POLICY;
|
||||
|
@ -155,12 +149,6 @@ final class PhabricatorDashboardPanelEditController
|
|||
->setTransactionType($type_edit_policy)
|
||||
->setNewValue($v_edit_policy);
|
||||
|
||||
$proj_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
|
||||
$xactions[] = id(new PhabricatorDashboardPanelTransaction())
|
||||
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
|
||||
->setMetadataValue('edge:type', $proj_edge_type)
|
||||
->setNewValue(array('=' => array_fuse($v_projects)));
|
||||
|
||||
$field_xactions = $field_list->buildFieldTransactionsFromRequest(
|
||||
new PhabricatorDashboardPanelTransaction(),
|
||||
$request);
|
||||
|
@ -238,13 +226,6 @@ final class PhabricatorDashboardPanelEditController
|
|||
->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
|
||||
->setPolicies($policies));
|
||||
|
||||
$form->appendControl(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setLabel(pht('Tags'))
|
||||
->setName('projects')
|
||||
->setValue($v_projects)
|
||||
->setDatasource(new PhabricatorProjectDatasource()));
|
||||
|
||||
$field_list->appendFieldsToForm($form);
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPanelEditproController
|
||||
extends PhabricatorDashboardController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$engine = id(new PhabricatorDashboardPanelEditEngine())
|
||||
->setController($this);
|
||||
|
||||
$id = $request->getURIData('id');
|
||||
if (!$id) {
|
||||
$list_uri = $this->getApplicationURI('panel/');
|
||||
|
||||
$panel_type = $request->getStr('panelType');
|
||||
$panel_types = PhabricatorDashboardPanelType::getAllPanelTypes();
|
||||
if (empty($panel_types[$panel_type])) {
|
||||
return $this->buildPanelTypeResponse($list_uri);
|
||||
}
|
||||
|
||||
$engine
|
||||
->addContextParameter('panelType', $panel_type)
|
||||
->setPanelType($panel_type);
|
||||
}
|
||||
|
||||
return $engine->buildResponse();
|
||||
}
|
||||
|
||||
private function buildPanelTypeResponse($cancel_uri) {
|
||||
$panel_types = PhabricatorDashboardPanelType::getAllPanelTypes();
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
$request = $this->getRequest();
|
||||
|
||||
$e_type = null;
|
||||
$errors = array();
|
||||
if ($request->isFormPost()) {
|
||||
$e_type = pht('Required');
|
||||
$errors[] = pht(
|
||||
'To create a new dashboard panel, you must select a panel type.');
|
||||
}
|
||||
|
||||
$type_control = id(new AphrontFormRadioButtonControl())
|
||||
->setLabel(pht('Panel Type'))
|
||||
->setName('panelType')
|
||||
->setError($e_type);
|
||||
|
||||
foreach ($panel_types as $key => $type) {
|
||||
$type_control->addButton(
|
||||
$key,
|
||||
$type->getPanelTypeName(),
|
||||
$type->getPanelTypeDescription());
|
||||
}
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->appendRemarkupInstructions(
|
||||
pht('Choose the type of dashboard panel to create:'))
|
||||
->appendChild($type_control);
|
||||
|
||||
if ($request->isAjax()) {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Add New Panel'))
|
||||
->setWidth(AphrontDialogView::WIDTH_FORM)
|
||||
->setErrors($errors)
|
||||
->appendForm($form)
|
||||
->addCancelButton($cancel_uri)
|
||||
->addSubmitButton(pht('Continue'));
|
||||
}
|
||||
|
||||
$form->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue(pht('Continue'))
|
||||
->addCancelButton($cancel_uri));
|
||||
|
||||
$title = pht('Create Dashboard Panel');
|
||||
$header_icon = 'fa-plus-square';
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(
|
||||
pht('Panels'),
|
||||
$this->getApplicationURI('panel/'));
|
||||
$crumbs->addTextCrumb(pht('New Panel'));
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
$box = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Panel'))
|
||||
->setFormErrors($errors)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setForm($form);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($title)
|
||||
->setHeaderIcon($header_icon);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter($box);
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
}
|
|
@ -9,6 +9,10 @@ final class PhabricatorDashboardPanelCoreCustomField
|
|||
}
|
||||
|
||||
public function createFields($object) {
|
||||
if (!$object->getPanelType()) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$impl = $object->requireImplementation();
|
||||
$specs = $impl->getFieldSpecifications();
|
||||
return PhabricatorStandardCustomField::buildStandardFields($this, $specs);
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPanelEditEngine
|
||||
extends PhabricatorEditEngine {
|
||||
|
||||
const ENGINECONST = 'dashboard.panel';
|
||||
|
||||
private $panelType;
|
||||
|
||||
public function setPanelType($panel_type) {
|
||||
$this->panelType = $panel_type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPanelType() {
|
||||
return $this->panelType;
|
||||
}
|
||||
|
||||
public function isEngineConfigurable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getEngineName() {
|
||||
return pht('Dashboard Panels');
|
||||
}
|
||||
|
||||
public function getSummaryHeader() {
|
||||
return pht('Edit Dashboard Panels');
|
||||
}
|
||||
|
||||
public function getSummaryText() {
|
||||
return pht('This engine is used to modify dashboard panels.');
|
||||
}
|
||||
|
||||
public function getEngineApplicationClass() {
|
||||
return 'PhabricatorSearchApplication';
|
||||
}
|
||||
|
||||
protected function newEditableObject() {
|
||||
$viewer = $this->getViewer();
|
||||
$panel = PhabricatorDashboardPanel::initializeNewPanel($viewer);
|
||||
|
||||
if ($this->panelType) {
|
||||
$panel->setPanelType($this->panelType);
|
||||
}
|
||||
|
||||
return $panel;
|
||||
}
|
||||
|
||||
protected function newObjectQuery() {
|
||||
return new PhabricatorDashboardPanelQuery();
|
||||
}
|
||||
|
||||
protected function getObjectCreateTitleText($object) {
|
||||
return pht('Create Dashboard Panel');
|
||||
}
|
||||
|
||||
protected function getObjectCreateButtonText($object) {
|
||||
return pht('Create Panel');
|
||||
}
|
||||
|
||||
protected function getObjectEditTitleText($object) {
|
||||
return pht('Edit Panel: %s', $object->getName());
|
||||
}
|
||||
|
||||
protected function getObjectEditShortText($object) {
|
||||
return pht('Edit Panel');
|
||||
}
|
||||
|
||||
protected function getObjectCreateShortText() {
|
||||
return pht('Edit Panel');
|
||||
}
|
||||
|
||||
protected function getObjectName() {
|
||||
return pht('Dashboard Panel');
|
||||
}
|
||||
|
||||
protected function getObjectViewURI($object) {
|
||||
return $object->getURI();
|
||||
}
|
||||
|
||||
protected function buildCustomEditFields($object) {
|
||||
return array(
|
||||
id(new PhabricatorTextEditField())
|
||||
->setKey('name')
|
||||
->setLabel(pht('Name'))
|
||||
->setDescription(pht('Name of the panel.'))
|
||||
->setConduitDescription(pht('Rename the panel.'))
|
||||
->setConduitTypeDescription(pht('New panel name.'))
|
||||
->setTransactionType(PhabricatorDashboardPanelTransaction::TYPE_NAME)
|
||||
->setIsRequired(true)
|
||||
->setValue($object->getName()),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -10,7 +10,6 @@ final class PhabricatorDashboardPanel
|
|||
PhabricatorPolicyInterface,
|
||||
PhabricatorCustomFieldInterface,
|
||||
PhabricatorFlaggableInterface,
|
||||
PhabricatorProjectInterface,
|
||||
PhabricatorDestructibleInterface {
|
||||
|
||||
protected $name;
|
||||
|
@ -72,6 +71,10 @@ final class PhabricatorDashboardPanel
|
|||
return 'W'.$this->getID();
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
return '/'.$this->getMonogram();
|
||||
}
|
||||
|
||||
public function getPanelTypes() {
|
||||
$panel_types = PhabricatorDashboardPanelType::getAllPanelTypes();
|
||||
$panel_types = mpull($panel_types, 'getPanelTypeName', 'getPanelTypeKey');
|
||||
|
|
Loading…
Reference in a new issue