mirror of
https://we.phorge.it/source/phorge.git
synced 2025-01-24 21:48:21 +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',
|
'PhabricatorConfigManagementSetWorkflow' => 'applications/config/management/PhabricatorConfigManagementSetWorkflow.php',
|
||||||
'PhabricatorConfigManagementWorkflow' => 'applications/config/management/PhabricatorConfigManagementWorkflow.php',
|
'PhabricatorConfigManagementWorkflow' => 'applications/config/management/PhabricatorConfigManagementWorkflow.php',
|
||||||
'PhabricatorConfigOption' => 'applications/config/option/PhabricatorConfigOption.php',
|
'PhabricatorConfigOption' => 'applications/config/option/PhabricatorConfigOption.php',
|
||||||
|
'PhabricatorConfigOptionType' => 'applications/config/custom/PhabricatorConfigOptionType.php',
|
||||||
'PhabricatorConfigProxySource' => 'infrastructure/env/PhabricatorConfigProxySource.php',
|
'PhabricatorConfigProxySource' => 'infrastructure/env/PhabricatorConfigProxySource.php',
|
||||||
'PhabricatorConfigResponse' => 'applications/config/response/PhabricatorConfigResponse.php',
|
'PhabricatorConfigResponse' => 'applications/config/response/PhabricatorConfigResponse.php',
|
||||||
'PhabricatorConfigSource' => 'infrastructure/env/PhabricatorConfigSource.php',
|
'PhabricatorConfigSource' => 'infrastructure/env/PhabricatorConfigSource.php',
|
||||||
|
@ -918,6 +919,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorCrumbsView' => 'view/layout/PhabricatorCrumbsView.php',
|
'PhabricatorCrumbsView' => 'view/layout/PhabricatorCrumbsView.php',
|
||||||
'PhabricatorCursorPagedPolicyAwareQuery' => 'infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php',
|
'PhabricatorCursorPagedPolicyAwareQuery' => 'infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php',
|
||||||
'PhabricatorCustomField' => 'infrastructure/customfield/field/PhabricatorCustomField.php',
|
'PhabricatorCustomField' => 'infrastructure/customfield/field/PhabricatorCustomField.php',
|
||||||
|
'PhabricatorCustomFieldConfigOptionType' => 'infrastructure/customfield/config/PhabricatorCustomFieldConfigOptionType.php',
|
||||||
'PhabricatorCustomFieldDataNotAvailableException' => 'infrastructure/customfield/exception/PhabricatorCustomFieldDataNotAvailableException.php',
|
'PhabricatorCustomFieldDataNotAvailableException' => 'infrastructure/customfield/exception/PhabricatorCustomFieldDataNotAvailableException.php',
|
||||||
'PhabricatorCustomFieldImplementationIncompleteException' => 'infrastructure/customfield/exception/PhabricatorCustomFieldImplementationIncompleteException.php',
|
'PhabricatorCustomFieldImplementationIncompleteException' => 'infrastructure/customfield/exception/PhabricatorCustomFieldImplementationIncompleteException.php',
|
||||||
'PhabricatorCustomFieldIndexStorage' => 'infrastructure/customfield/storage/PhabricatorCustomFieldIndexStorage.php',
|
'PhabricatorCustomFieldIndexStorage' => 'infrastructure/customfield/storage/PhabricatorCustomFieldIndexStorage.php',
|
||||||
|
@ -2774,6 +2776,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorCrumbView' => 'AphrontView',
|
'PhabricatorCrumbView' => 'AphrontView',
|
||||||
'PhabricatorCrumbsView' => 'AphrontView',
|
'PhabricatorCrumbsView' => 'AphrontView',
|
||||||
'PhabricatorCursorPagedPolicyAwareQuery' => 'PhabricatorPolicyAwareQuery',
|
'PhabricatorCursorPagedPolicyAwareQuery' => 'PhabricatorPolicyAwareQuery',
|
||||||
|
'PhabricatorCustomFieldConfigOptionType' => 'PhabricatorConfigOptionType',
|
||||||
'PhabricatorCustomFieldDataNotAvailableException' => 'Exception',
|
'PhabricatorCustomFieldDataNotAvailableException' => 'Exception',
|
||||||
'PhabricatorCustomFieldImplementationIncompleteException' => 'Exception',
|
'PhabricatorCustomFieldImplementationIncompleteException' => 'Exception',
|
||||||
'PhabricatorCustomFieldIndexStorage' => 'PhabricatorLiskDAO',
|
'PhabricatorCustomFieldIndexStorage' => 'PhabricatorLiskDAO',
|
||||||
|
|
|
@ -236,6 +236,10 @@ final class PhabricatorConfigEditController
|
||||||
return array($e_value, $errors, $value, $xaction);
|
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();
|
$type = $option->getType();
|
||||||
$set_value = null;
|
$set_value = null;
|
||||||
|
|
||||||
|
@ -298,6 +302,7 @@ final class PhabricatorConfigEditController
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!$errors) {
|
if (!$errors) {
|
||||||
$xaction->setNewValue(
|
$xaction->setNewValue(
|
||||||
|
@ -320,6 +325,9 @@ final class PhabricatorConfigEditController
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($option->isCustomType()) {
|
||||||
|
return $option->getCustomObject()->getDisplayValue($option, $entry);
|
||||||
|
} else {
|
||||||
$type = $option->getType();
|
$type = $option->getType();
|
||||||
$value = $entry->getValue();
|
$value = $entry->getValue();
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
|
@ -338,12 +346,19 @@ final class PhabricatorConfigEditController
|
||||||
return PhabricatorConfigJSON::prettyPrintJSON($value);
|
return PhabricatorConfigJSON::prettyPrintJSON($value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private function renderControl(
|
private function renderControl(
|
||||||
PhabricatorConfigOption $option,
|
PhabricatorConfigOption $option,
|
||||||
$display_value,
|
$display_value,
|
||||||
$e_value) {
|
$e_value) {
|
||||||
|
|
||||||
|
if ($option->isCustomType()) {
|
||||||
|
$control = $option->getCustomObject()->renderControl(
|
||||||
|
$option,
|
||||||
|
$display_value,
|
||||||
|
$e_value);
|
||||||
|
} else {
|
||||||
$type = $option->getType();
|
$type = $option->getType();
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case 'int':
|
case 'int':
|
||||||
|
@ -401,6 +416,7 @@ final class PhabricatorConfigEditController
|
||||||
->setError($e_value)
|
->setError($e_value)
|
||||||
->setValue($display_value)
|
->setValue($display_value)
|
||||||
->setName('value');
|
->setName('value');
|
||||||
|
}
|
||||||
|
|
||||||
if ($option->getLocked()) {
|
if ($option->getLocked()) {
|
||||||
$control->setDisabled(true);
|
$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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($option->isCustomType()) {
|
||||||
|
return $option->getCustomObject()->validateOption($option, $value);
|
||||||
|
}
|
||||||
|
|
||||||
switch ($option->getType()) {
|
switch ($option->getType()) {
|
||||||
case 'bool':
|
case 'bool':
|
||||||
if ($value !== true &&
|
if ($value !== true &&
|
||||||
|
|
|
@ -17,6 +17,8 @@ final class PhabricatorConfigOption
|
||||||
private $hidden;
|
private $hidden;
|
||||||
private $masked;
|
private $masked;
|
||||||
private $baseClass;
|
private $baseClass;
|
||||||
|
private $customData;
|
||||||
|
private $customObject;
|
||||||
|
|
||||||
public function setBaseClass($base_class) {
|
public function setBaseClass($base_class) {
|
||||||
$this->baseClass = $base_class;
|
$this->baseClass = $base_class;
|
||||||
|
@ -178,6 +180,29 @@ final class PhabricatorConfigOption
|
||||||
return $this->type;
|
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 )----------------------------------------- */
|
/* -( PhabricatorMarkupInterface )----------------------------------------- */
|
||||||
|
|
||||||
public function getMarkupFieldKey($field) {
|
public function getMarkupFieldKey($field) {
|
||||||
|
|
|
@ -25,8 +25,11 @@ final class PhabricatorUserConfigOptions
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$custom_field_type = 'custom:PhabricatorCustomFieldConfigOptionType';
|
||||||
|
|
||||||
return array(
|
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.")),
|
->setDescription(pht("Select and reorder user profile fields.")),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorCustomFieldConfigOptionType
|
||||||
|
extends PhabricatorConfigOptionType {
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue