mirror of
https://we.phorge.it/source/phorge.git
synced 2025-01-09 14:21:02 +01:00
Allow configuration to have custom UI types
Summary: Ref T1703. This sets the stage for (but does not yet implement) custom UI types for config. In particular, a draggable list for custom fields. I might make all the builtin types go through this at some point too, but don't really want to bother for the moment. It would be very slightly cleaner but woudn't get us much of anything. Test Plan: UI now renders via custom code, although that code does nothing (produces an unadorned text field): {F45693} Reviewers: chad Reviewed By: chad CC: aran Maniphest Tasks: T1703 Differential Revision: https://secure.phabricator.com/D6154
This commit is contained in:
parent
77c03a8a42
commit
059183f6b5
7 changed files with 224 additions and 128 deletions
|
@ -894,6 +894,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorConfigManagementSetWorkflow' => 'applications/config/management/PhabricatorConfigManagementSetWorkflow.php',
|
||||
'PhabricatorConfigManagementWorkflow' => 'applications/config/management/PhabricatorConfigManagementWorkflow.php',
|
||||
'PhabricatorConfigOption' => 'applications/config/option/PhabricatorConfigOption.php',
|
||||
'PhabricatorConfigOptionType' => 'applications/config/custom/PhabricatorConfigOptionType.php',
|
||||
'PhabricatorConfigProxySource' => 'infrastructure/env/PhabricatorConfigProxySource.php',
|
||||
'PhabricatorConfigResponse' => 'applications/config/response/PhabricatorConfigResponse.php',
|
||||
'PhabricatorConfigSource' => 'infrastructure/env/PhabricatorConfigSource.php',
|
||||
|
@ -918,6 +919,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorCrumbsView' => 'view/layout/PhabricatorCrumbsView.php',
|
||||
'PhabricatorCursorPagedPolicyAwareQuery' => 'infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php',
|
||||
'PhabricatorCustomField' => 'infrastructure/customfield/field/PhabricatorCustomField.php',
|
||||
'PhabricatorCustomFieldConfigOptionType' => 'infrastructure/customfield/config/PhabricatorCustomFieldConfigOptionType.php',
|
||||
'PhabricatorCustomFieldDataNotAvailableException' => 'infrastructure/customfield/exception/PhabricatorCustomFieldDataNotAvailableException.php',
|
||||
'PhabricatorCustomFieldImplementationIncompleteException' => 'infrastructure/customfield/exception/PhabricatorCustomFieldImplementationIncompleteException.php',
|
||||
'PhabricatorCustomFieldIndexStorage' => 'infrastructure/customfield/storage/PhabricatorCustomFieldIndexStorage.php',
|
||||
|
@ -2774,6 +2776,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorCrumbView' => 'AphrontView',
|
||||
'PhabricatorCrumbsView' => 'AphrontView',
|
||||
'PhabricatorCursorPagedPolicyAwareQuery' => 'PhabricatorPolicyAwareQuery',
|
||||
'PhabricatorCustomFieldConfigOptionType' => 'PhabricatorConfigOptionType',
|
||||
'PhabricatorCustomFieldDataNotAvailableException' => 'Exception',
|
||||
'PhabricatorCustomFieldImplementationIncompleteException' => 'Exception',
|
||||
'PhabricatorCustomFieldIndexStorage' => 'PhabricatorLiskDAO',
|
||||
|
|
|
@ -236,6 +236,10 @@ final class PhabricatorConfigEditController
|
|||
return array($e_value, $errors, $value, $xaction);
|
||||
}
|
||||
|
||||
if ($option->isCustomType()) {
|
||||
$info = $option->getCustomObject()->readRequest($option, $request);
|
||||
list($e_value, $errors, $set_value, $value) = $info;
|
||||
} else {
|
||||
$type = $option->getType();
|
||||
$set_value = null;
|
||||
|
||||
|
@ -298,6 +302,7 @@ final class PhabricatorConfigEditController
|
|||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$errors) {
|
||||
$xaction->setNewValue(
|
||||
|
@ -320,6 +325,9 @@ final class PhabricatorConfigEditController
|
|||
return null;
|
||||
}
|
||||
|
||||
if ($option->isCustomType()) {
|
||||
return $option->getCustomObject()->getDisplayValue($option, $entry);
|
||||
} else {
|
||||
$type = $option->getType();
|
||||
$value = $entry->getValue();
|
||||
switch ($type) {
|
||||
|
@ -338,12 +346,19 @@ final class PhabricatorConfigEditController
|
|||
return PhabricatorConfigJSON::prettyPrintJSON($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function renderControl(
|
||||
PhabricatorConfigOption $option,
|
||||
$display_value,
|
||||
$e_value) {
|
||||
|
||||
if ($option->isCustomType()) {
|
||||
$control = $option->getCustomObject()->renderControl(
|
||||
$option,
|
||||
$display_value,
|
||||
$e_value);
|
||||
} else {
|
||||
$type = $option->getType();
|
||||
switch ($type) {
|
||||
case 'int':
|
||||
|
@ -401,6 +416,7 @@ final class PhabricatorConfigEditController
|
|||
->setError($e_value)
|
||||
->setValue($display_value)
|
||||
->setName('value');
|
||||
}
|
||||
|
||||
if ($option->getLocked()) {
|
||||
$control->setDisabled(true);
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
abstract class PhabricatorConfigOptionType {
|
||||
|
||||
public function validateOption(PhabricatorConfigOption $option, $value) {
|
||||
return;
|
||||
}
|
||||
|
||||
public function readRequest(
|
||||
PhabricatorConfigOption $option,
|
||||
AphrontRequest $request) {
|
||||
|
||||
$e_value = null;
|
||||
$errors = array();
|
||||
$storage_value = $request->getStr('value');
|
||||
$display_value = $request->getStr('value');
|
||||
|
||||
return array($e_value, $errors, $storage_value, $display_value);
|
||||
}
|
||||
|
||||
public function getDisplayValue(
|
||||
PhabricatorConfigOption $option,
|
||||
PhabricatorConfigEntry $entry) {
|
||||
return $entry->getValue();
|
||||
}
|
||||
|
||||
public function renderControl(
|
||||
PhabricatorConfigOption $option,
|
||||
$display_value,
|
||||
$e_value) {
|
||||
|
||||
return id(new AphrontFormTextControl())
|
||||
->setName('value')
|
||||
->setLabel(pht('Value'))
|
||||
->setValue($display_value)
|
||||
->setError($e_value);
|
||||
}
|
||||
|
||||
}
|
|
@ -15,6 +15,10 @@ abstract class PhabricatorApplicationConfigOptions extends Phobject {
|
|||
return;
|
||||
}
|
||||
|
||||
if ($option->isCustomType()) {
|
||||
return $option->getCustomObject()->validateOption($option, $value);
|
||||
}
|
||||
|
||||
switch ($option->getType()) {
|
||||
case 'bool':
|
||||
if ($value !== true &&
|
||||
|
|
|
@ -17,6 +17,8 @@ final class PhabricatorConfigOption
|
|||
private $hidden;
|
||||
private $masked;
|
||||
private $baseClass;
|
||||
private $customData;
|
||||
private $customObject;
|
||||
|
||||
public function setBaseClass($base_class) {
|
||||
$this->baseClass = $base_class;
|
||||
|
@ -178,6 +180,29 @@ final class PhabricatorConfigOption
|
|||
return $this->type;
|
||||
}
|
||||
|
||||
public function isCustomType() {
|
||||
return !strncmp($this->getType(), 'custom:', 7);
|
||||
}
|
||||
|
||||
public function getCustomObject() {
|
||||
if (!$this->customObject) {
|
||||
if (!$this->isCustomType()) {
|
||||
throw new Exception("This option does not have a custom type!");
|
||||
}
|
||||
$this->customObject = newv(substr($this->getType(), 7), array());
|
||||
}
|
||||
return $this->customObject;
|
||||
}
|
||||
|
||||
public function getCustomData() {
|
||||
return $this->customData;
|
||||
}
|
||||
|
||||
public function setCustomData($data) {
|
||||
$this->customData = $data;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/* -( PhabricatorMarkupInterface )----------------------------------------- */
|
||||
|
||||
public function getMarkupFieldKey($field) {
|
||||
|
|
|
@ -25,8 +25,11 @@ final class PhabricatorUserConfigOptions
|
|||
);
|
||||
}
|
||||
|
||||
$custom_field_type = 'custom:PhabricatorCustomFieldConfigOptionType';
|
||||
|
||||
return array(
|
||||
$this->newOption('user.fields', 'wild', $default)
|
||||
$this->newOption('user.fields', $custom_field_type, $default)
|
||||
->setCustomData(id(new PhabricatorUser())->getCustomFieldBaseClass())
|
||||
->setDescription(pht("Select and reorder user profile fields.")),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorCustomFieldConfigOptionType
|
||||
extends PhabricatorConfigOptionType {
|
||||
|
||||
}
|
Loading…
Reference in a new issue