1
0
Fork 0
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:
epriestley 2013-06-07 12:36:18 -07:00
parent 77c03a8a42
commit 059183f6b5
7 changed files with 224 additions and 128 deletions

View file

@ -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',

View file

@ -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);

View file

@ -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);
}
}

View file

@ -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 &&

View file

@ -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) {

View file

@ -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.")),
);
}

View file

@ -0,0 +1,6 @@
<?php
final class PhabricatorCustomFieldConfigOptionType
extends PhabricatorConfigOptionType {
}