mirror of
https://we.phorge.it/source/phorge.git
synced 2025-01-19 03:01:11 +01:00
Provide a generic "Datasource" StandardCustomField
Summary: Ref T9253. See discussion in D13843. I want to let Drydock blueprints for Almanac services choose those services from a typeahead, but only list appropriate services in the typeahead. To do this: - Provide a StandardCustomField for an arbitrary datasource. - Adjust the AlmanacServiceDatasource to allow filtering by service class. This implementation is substantially the same as the one in D13843, with some adjustments: - I lifted most of the code in the `Users` standard custom field into a new `Tokenizer` standard custom field. - The `Users` and `Datasource` custom fields now extend the `Tokenizer` custom field and can share most of the code it uses. - I exposed this field fully as a configurable field. I don't think anyone will ever use it, but this generality costs us nearly nothing and improves consistency. - The code in D13843 didn't actually pass the parameters over the wire, since the object that responds to the request is not the same object that renders the field. Use the "parameters" mechanism in datasources to get things passed over the wire. Test Plan: - Created a custom "users" field in Maniphest and made sure it still wokred. - Created a custom "almanc services" field in Maniphest and selected some services for a task. - With additional changes from D13843, selected an appropriate Almanac service in a new Drydock blueprint. Reviewers: hach-que, chad Reviewed By: hach-que, chad Maniphest Tasks: T9253 Differential Revision: https://secure.phabricator.com/D14111
This commit is contained in:
parent
c44f9d80de
commit
635e9c6075
6 changed files with 96 additions and 39 deletions
|
@ -2915,6 +2915,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorStandardCustomField' => 'infrastructure/customfield/standard/PhabricatorStandardCustomField.php',
|
||||
'PhabricatorStandardCustomFieldBool' => 'infrastructure/customfield/standard/PhabricatorStandardCustomFieldBool.php',
|
||||
'PhabricatorStandardCustomFieldCredential' => 'infrastructure/customfield/standard/PhabricatorStandardCustomFieldCredential.php',
|
||||
'PhabricatorStandardCustomFieldDatasource' => 'infrastructure/customfield/standard/PhabricatorStandardCustomFieldDatasource.php',
|
||||
'PhabricatorStandardCustomFieldDate' => 'infrastructure/customfield/standard/PhabricatorStandardCustomFieldDate.php',
|
||||
'PhabricatorStandardCustomFieldHeader' => 'infrastructure/customfield/standard/PhabricatorStandardCustomFieldHeader.php',
|
||||
'PhabricatorStandardCustomFieldInt' => 'infrastructure/customfield/standard/PhabricatorStandardCustomFieldInt.php',
|
||||
|
@ -2924,6 +2925,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorStandardCustomFieldRemarkup' => 'infrastructure/customfield/standard/PhabricatorStandardCustomFieldRemarkup.php',
|
||||
'PhabricatorStandardCustomFieldSelect' => 'infrastructure/customfield/standard/PhabricatorStandardCustomFieldSelect.php',
|
||||
'PhabricatorStandardCustomFieldText' => 'infrastructure/customfield/standard/PhabricatorStandardCustomFieldText.php',
|
||||
'PhabricatorStandardCustomFieldTokenizer' => 'infrastructure/customfield/standard/PhabricatorStandardCustomFieldTokenizer.php',
|
||||
'PhabricatorStandardCustomFieldUsers' => 'infrastructure/customfield/standard/PhabricatorStandardCustomFieldUsers.php',
|
||||
'PhabricatorStandardPageView' => 'view/page/PhabricatorStandardPageView.php',
|
||||
'PhabricatorStandardSelectCustomFieldDatasource' => 'infrastructure/customfield/datasource/PhabricatorStandardSelectCustomFieldDatasource.php',
|
||||
|
@ -7022,6 +7024,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorStandardCustomField' => 'PhabricatorCustomField',
|
||||
'PhabricatorStandardCustomFieldBool' => 'PhabricatorStandardCustomField',
|
||||
'PhabricatorStandardCustomFieldCredential' => 'PhabricatorStandardCustomField',
|
||||
'PhabricatorStandardCustomFieldDatasource' => 'PhabricatorStandardCustomFieldTokenizer',
|
||||
'PhabricatorStandardCustomFieldDate' => 'PhabricatorStandardCustomField',
|
||||
'PhabricatorStandardCustomFieldHeader' => 'PhabricatorStandardCustomField',
|
||||
'PhabricatorStandardCustomFieldInt' => 'PhabricatorStandardCustomField',
|
||||
|
@ -7030,7 +7033,8 @@ phutil_register_library_map(array(
|
|||
'PhabricatorStandardCustomFieldRemarkup' => 'PhabricatorStandardCustomField',
|
||||
'PhabricatorStandardCustomFieldSelect' => 'PhabricatorStandardCustomField',
|
||||
'PhabricatorStandardCustomFieldText' => 'PhabricatorStandardCustomField',
|
||||
'PhabricatorStandardCustomFieldUsers' => 'PhabricatorStandardCustomFieldPHIDs',
|
||||
'PhabricatorStandardCustomFieldTokenizer' => 'PhabricatorStandardCustomFieldPHIDs',
|
||||
'PhabricatorStandardCustomFieldUsers' => 'PhabricatorStandardCustomFieldTokenizer',
|
||||
'PhabricatorStandardPageView' => 'PhabricatorBarePageView',
|
||||
'PhabricatorStandardSelectCustomFieldDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||
'PhabricatorStatusController' => 'PhabricatorController',
|
||||
|
|
|
@ -23,6 +23,16 @@ final class AlmanacServiceDatasource
|
|||
->withNamePrefix($raw_query)
|
||||
->setOrder('name');
|
||||
|
||||
// TODO: When service classes are restricted, it might be nice to customize
|
||||
// the title and placeholder text to show which service types can be
|
||||
// selected, or show all services but mark the invalid ones disabled and
|
||||
// prevent their selection.
|
||||
|
||||
$service_classes = $this->getParameter('serviceClasses');
|
||||
if ($service_classes) {
|
||||
$services->withServiceClasses($service_classes);
|
||||
}
|
||||
|
||||
$services = $this->executeQuery($services);
|
||||
|
||||
if ($services) {
|
||||
|
|
|
@ -144,6 +144,9 @@ change, but are documented here for completeness:
|
|||
- **Credentials**: Controls with type `credential` allow selection of a
|
||||
Passphrase credential which provides `credential.provides`, and creation
|
||||
of credentials of `credential.type`.
|
||||
- **Datasource**: Controls with type `datasource` allow selection of tokens
|
||||
from an arbitrary datasource, controlled with `datasource.class` and
|
||||
`datasource.parameters`.
|
||||
|
||||
= Advanced Custom Fields =
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorStandardCustomFieldDatasource
|
||||
extends PhabricatorStandardCustomFieldTokenizer {
|
||||
|
||||
public function getFieldType() {
|
||||
return 'datasource';
|
||||
}
|
||||
|
||||
public function getDatasource() {
|
||||
$parameters = $this->getFieldConfigValue('datasource.parameters', array());
|
||||
|
||||
$class = $this->getFieldConfigValue('datasource.class');
|
||||
$parent = 'PhabricatorTypeaheadDatasource';
|
||||
if (!is_subclass_of($class, $parent)) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Configured datasource class "%s" must be a valid subclass of '.
|
||||
'"%s".',
|
||||
$class,
|
||||
$parent));
|
||||
}
|
||||
|
||||
return newv($class, array())
|
||||
->setParameters($parameters);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
abstract class PhabricatorStandardCustomFieldTokenizer
|
||||
extends PhabricatorStandardCustomFieldPHIDs {
|
||||
|
||||
abstract public function getDatasource();
|
||||
|
||||
public function renderEditControl(array $handles) {
|
||||
$value = $this->getFieldValue();
|
||||
|
||||
$control = id(new AphrontFormTokenizerControl())
|
||||
->setUser($this->getViewer())
|
||||
->setLabel($this->getFieldName())
|
||||
->setName($this->getFieldKey())
|
||||
->setDatasource($this->getDatasource())
|
||||
->setCaption($this->getCaption())
|
||||
->setValue(nonempty($value, array()));
|
||||
|
||||
$limit = $this->getFieldConfigValue('limit');
|
||||
if ($limit) {
|
||||
$control->setLimit($limit);
|
||||
}
|
||||
|
||||
return $control;
|
||||
}
|
||||
|
||||
public function appendToApplicationSearchForm(
|
||||
PhabricatorApplicationSearchEngine $engine,
|
||||
AphrontFormView $form,
|
||||
$value) {
|
||||
|
||||
$control = id(new AphrontFormTokenizerControl())
|
||||
->setLabel($this->getFieldName())
|
||||
->setName($this->getFieldKey())
|
||||
->setDatasource($this->getDatasource())
|
||||
->setValue(nonempty($value, array()));
|
||||
|
||||
$form->appendControl($control);
|
||||
}
|
||||
|
||||
public function getHeraldFieldValueType($condition) {
|
||||
return id(new HeraldTokenizerFieldValue())
|
||||
->setKey('custom.'.$this->getFieldKey())
|
||||
->setDatasource($this->getDatasource());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,49 +1,14 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorStandardCustomFieldUsers
|
||||
extends PhabricatorStandardCustomFieldPHIDs {
|
||||
extends PhabricatorStandardCustomFieldTokenizer {
|
||||
|
||||
public function getFieldType() {
|
||||
return 'users';
|
||||
}
|
||||
|
||||
public function renderEditControl(array $handles) {
|
||||
$value = $this->getFieldValue();
|
||||
|
||||
$control = id(new AphrontFormTokenizerControl())
|
||||
->setUser($this->getViewer())
|
||||
->setLabel($this->getFieldName())
|
||||
->setName($this->getFieldKey())
|
||||
->setDatasource(new PhabricatorPeopleDatasource())
|
||||
->setCaption($this->getCaption())
|
||||
->setValue(nonempty($value, array()));
|
||||
|
||||
$limit = $this->getFieldConfigValue('limit');
|
||||
if ($limit) {
|
||||
$control->setLimit($limit);
|
||||
}
|
||||
|
||||
return $control;
|
||||
}
|
||||
|
||||
public function appendToApplicationSearchForm(
|
||||
PhabricatorApplicationSearchEngine $engine,
|
||||
AphrontFormView $form,
|
||||
$value) {
|
||||
|
||||
$control = id(new AphrontFormTokenizerControl())
|
||||
->setLabel($this->getFieldName())
|
||||
->setName($this->getFieldKey())
|
||||
->setDatasource(new PhabricatorPeopleDatasource())
|
||||
->setValue(nonempty($value, array()));
|
||||
|
||||
$form->appendControl($control);
|
||||
}
|
||||
|
||||
public function getHeraldFieldValueType($condition) {
|
||||
return id(new HeraldTokenizerFieldValue())
|
||||
->setKey('custom.'.$this->getFieldKey())
|
||||
->setDatasource(new PhabricatorPeopleDatasource());
|
||||
public function getDatasource() {
|
||||
return new PhabricatorPeopleDatasource();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue