mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-18 21:02:41 +01:00
Convert maniphest to use standard fields
Summary: Ref T3794. Drop auxiliary field, use standard field. Test Plan: Performed migration, field seemed to survive it intact. Edited and viewed tasks. Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T3794 Differential Revision: https://secure.phabricator.com/D7036
This commit is contained in:
parent
2088b99078
commit
0558d53273
10 changed files with 136 additions and 50 deletions
66
resources/sql/patches/20130919.mfieldconf.php
Normal file
66
resources/sql/patches/20130919.mfieldconf.php
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
echo "Migrating Maniphest custom field configuration...\n";
|
||||||
|
|
||||||
|
$old_key = 'maniphest.custom-fields';
|
||||||
|
$new_key = 'maniphest.custom-field-definitions';
|
||||||
|
|
||||||
|
if (PhabricatorEnv::getEnvConfig($new_key)) {
|
||||||
|
echo "Skipping migration, new data is already set.\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$old = PhabricatorEnv::getEnvConfigIfExists($old_key);
|
||||||
|
if (!$old) {
|
||||||
|
echo "Skipping migration, old data does not exist.\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$new = array();
|
||||||
|
foreach ($old as $field_key => $spec) {
|
||||||
|
$new_spec = array();
|
||||||
|
|
||||||
|
foreach ($spec as $key => $value) {
|
||||||
|
switch ($key) {
|
||||||
|
case 'label':
|
||||||
|
$new_spec['name'] = $value;
|
||||||
|
break;
|
||||||
|
case 'required':
|
||||||
|
case 'default':
|
||||||
|
case 'caption':
|
||||||
|
case 'options':
|
||||||
|
$new_spec[$key] = $value;
|
||||||
|
break;
|
||||||
|
case 'checkbox-label':
|
||||||
|
$new_spec['strings']['edit.checkbox'] = $value;
|
||||||
|
break;
|
||||||
|
case 'checkbox-value':
|
||||||
|
$new_spec['strings']['view.yes'] = $value;
|
||||||
|
break;
|
||||||
|
case 'type':
|
||||||
|
switch ($value) {
|
||||||
|
case 'string':
|
||||||
|
$value = 'text';
|
||||||
|
break;
|
||||||
|
case 'user':
|
||||||
|
$value = 'users';
|
||||||
|
$new_spec['limit'] = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$new_spec['type'] = $value;
|
||||||
|
break;
|
||||||
|
case 'copy':
|
||||||
|
$new_spec['copy'] = $value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$new[$field_key] = $new_spec;
|
||||||
|
}
|
||||||
|
|
||||||
|
PhabricatorConfigEntry::loadConfigEntry($new_key)
|
||||||
|
->setIsDeleted(0)
|
||||||
|
->setValue($new)
|
||||||
|
->save();
|
||||||
|
|
||||||
|
echo "Done.\n";
|
|
@ -688,6 +688,7 @@ phutil_register_library_map(array(
|
||||||
'ManiphestAuxiliaryFieldDefaultSpecification' => 'applications/maniphest/auxiliaryfield/ManiphestAuxiliaryFieldDefaultSpecification.php',
|
'ManiphestAuxiliaryFieldDefaultSpecification' => 'applications/maniphest/auxiliaryfield/ManiphestAuxiliaryFieldDefaultSpecification.php',
|
||||||
'ManiphestAuxiliaryFieldSpecification' => 'applications/maniphest/auxiliaryfield/ManiphestAuxiliaryFieldSpecification.php',
|
'ManiphestAuxiliaryFieldSpecification' => 'applications/maniphest/auxiliaryfield/ManiphestAuxiliaryFieldSpecification.php',
|
||||||
'ManiphestBatchEditController' => 'applications/maniphest/controller/ManiphestBatchEditController.php',
|
'ManiphestBatchEditController' => 'applications/maniphest/controller/ManiphestBatchEditController.php',
|
||||||
|
'ManiphestConfiguredCustomField' => 'applications/maniphest/field/ManiphestConfiguredCustomField.php',
|
||||||
'ManiphestConstants' => 'applications/maniphest/constants/ManiphestConstants.php',
|
'ManiphestConstants' => 'applications/maniphest/constants/ManiphestConstants.php',
|
||||||
'ManiphestController' => 'applications/maniphest/controller/ManiphestController.php',
|
'ManiphestController' => 'applications/maniphest/controller/ManiphestController.php',
|
||||||
'ManiphestCreateMailReceiver' => 'applications/maniphest/mail/ManiphestCreateMailReceiver.php',
|
'ManiphestCreateMailReceiver' => 'applications/maniphest/mail/ManiphestCreateMailReceiver.php',
|
||||||
|
@ -2765,6 +2766,11 @@ phutil_register_library_map(array(
|
||||||
1 => 'PhabricatorMarkupInterface',
|
1 => 'PhabricatorMarkupInterface',
|
||||||
),
|
),
|
||||||
'ManiphestBatchEditController' => 'ManiphestController',
|
'ManiphestBatchEditController' => 'ManiphestController',
|
||||||
|
'ManiphestConfiguredCustomField' =>
|
||||||
|
array(
|
||||||
|
0 => 'ManiphestCustomField',
|
||||||
|
1 => 'PhabricatorStandardCustomFieldInterface',
|
||||||
|
),
|
||||||
'ManiphestController' => 'PhabricatorController',
|
'ManiphestController' => 'PhabricatorController',
|
||||||
'ManiphestCreateMailReceiver' => 'PhabricatorMailReceiver',
|
'ManiphestCreateMailReceiver' => 'PhabricatorMailReceiver',
|
||||||
'ManiphestCustomField' => 'PhabricatorCustomField',
|
'ManiphestCustomField' => 'PhabricatorCustomField',
|
||||||
|
|
|
@ -150,6 +150,11 @@ final class PhabricatorSetupCheckExtraConfig extends PhabricatorSetupCheck {
|
||||||
pht(
|
pht(
|
||||||
'Maniphest fields are now loaded automatically. You can configure '.
|
'Maniphest fields are now loaded automatically. You can configure '.
|
||||||
'them with `maniphest.fields`.'),
|
'them with `maniphest.fields`.'),
|
||||||
|
'maniphest.custom-fields' =>
|
||||||
|
pht(
|
||||||
|
'Maniphest fields are now defined in '.
|
||||||
|
'`maniphest.custom-field-definitions`. Existing definitions have '.
|
||||||
|
'been migrated.'),
|
||||||
);
|
);
|
||||||
|
|
||||||
return $ancient_config;
|
return $ancient_config;
|
||||||
|
|
|
@ -26,32 +26,7 @@ class ManiphestAuxiliaryFieldDefaultSpecification
|
||||||
const TYPE_HEADER = 'header';
|
const TYPE_HEADER = 'header';
|
||||||
|
|
||||||
public function createFields() {
|
public function createFields() {
|
||||||
$fields = PhabricatorEnv::getEnvConfig('maniphest.custom-fields');
|
return array();
|
||||||
$specs = array();
|
|
||||||
foreach ($fields as $aux => $info) {
|
|
||||||
$spec = new ManiphestAuxiliaryFieldDefaultSpecification();
|
|
||||||
$spec->setAuxiliaryKey($aux);
|
|
||||||
$spec->setLabel(idx($info, 'label'));
|
|
||||||
$spec->setCaption(idx($info, 'caption'));
|
|
||||||
$spec->setFieldType(idx($info, 'type'));
|
|
||||||
$spec->setRequired(idx($info, 'required'));
|
|
||||||
|
|
||||||
$spec->setCheckboxLabel(idx($info, 'checkbox-label'));
|
|
||||||
$spec->setCheckboxValue(idx($info, 'checkbox-value', 1));
|
|
||||||
|
|
||||||
if ($spec->getFieldType() ==
|
|
||||||
ManiphestAuxiliaryFieldDefaultSpecification::TYPE_SELECT) {
|
|
||||||
$spec->setSelectOptions(idx($info, 'options'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$spec->setShouldCopyWhenCreatingSimilarTask(idx($info, 'copy'));
|
|
||||||
|
|
||||||
$spec->setDefaultValue(idx($info, 'default'));
|
|
||||||
|
|
||||||
$specs[] = $spec;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $specs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFieldType() {
|
public function getFieldType() {
|
||||||
|
|
|
@ -59,7 +59,7 @@ final class PhabricatorManiphestConfigOptions
|
||||||
$custom_field_type = 'custom:PhabricatorCustomFieldConfigOptionType';
|
$custom_field_type = 'custom:PhabricatorCustomFieldConfigOptionType';
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
$this->newOption('maniphest.custom-fields', 'wild', array())
|
$this->newOption('maniphest.custom-field-definitions', 'wild', array())
|
||||||
->setSummary(pht("Custom Maniphest fields."))
|
->setSummary(pht("Custom Maniphest fields."))
|
||||||
->setDescription(
|
->setDescription(
|
||||||
pht(
|
pht(
|
||||||
|
@ -67,9 +67,9 @@ final class PhabricatorManiphestConfigOptions
|
||||||
"adding custom fields to Maniphest, see 'Maniphest User Guide: ".
|
"adding custom fields to Maniphest, see 'Maniphest User Guide: ".
|
||||||
"Adding Custom Fields'."))
|
"Adding Custom Fields'."))
|
||||||
->addExample(
|
->addExample(
|
||||||
'{"mycompany:estimated-hours": {"label": "Estimated Hours", '.
|
'{"mycompany:estimated-hours": {"name": "Estimated Hours", '.
|
||||||
'"type": "int", "caption": "Estimated number of hours this will '.
|
'"type": "int", "caption": "Estimated number of hours this will '.
|
||||||
'take.", "required": false}}',
|
'take."}}',
|
||||||
pht('Valid Setting')),
|
pht('Valid Setting')),
|
||||||
$this->newOption('maniphest.fields', $custom_field_type, $default_fields)
|
$this->newOption('maniphest.fields', $custom_field_type, $default_fields)
|
||||||
->setCustomData(id(new ManiphestTask())->getCustomFieldBaseClass())
|
->setCustomData(id(new ManiphestTask())->getCustomFieldBaseClass())
|
||||||
|
|
|
@ -229,9 +229,21 @@ final class ManiphestTaskEditController extends ManiphestController {
|
||||||
ManiphestTransactionType::TYPE_AUXILIARY);
|
ManiphestTransactionType::TYPE_AUXILIARY);
|
||||||
$aux_key = $aux_field->getFieldKey();
|
$aux_key = $aux_field->getFieldKey();
|
||||||
$transaction->setMetadataValue('aux:key', $aux_key);
|
$transaction->setMetadataValue('aux:key', $aux_key);
|
||||||
$transaction->setOldValue(idx($old_values, $aux_key));
|
$old = idx($old_values, $aux_key);
|
||||||
$transaction->setNewValue(
|
$new = $aux_field->getNewValueForApplicationTransactions();
|
||||||
$aux_field->getNewValueForApplicationTransactions());
|
|
||||||
|
// TODO: This is a ghetto check for transactions with no effect.
|
||||||
|
if (!is_array($old) && !is_array($new)) {
|
||||||
|
if ((string)$old === (string)$new) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if ($old == $new) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$transaction->setOldValue($old);
|
||||||
|
$transaction->setNewValue($new);
|
||||||
|
|
||||||
$transactions[] = $transaction;
|
$transactions[] = $transaction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class ManiphestConfiguredCustomField
|
||||||
|
extends ManiphestCustomField
|
||||||
|
implements PhabricatorStandardCustomFieldInterface {
|
||||||
|
|
||||||
|
public function getStandardCustomFieldNamespace() {
|
||||||
|
return 'maniphest';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createFields() {
|
||||||
|
$config = PhabricatorEnv::getEnvConfig(
|
||||||
|
'maniphest.custom-field-definitions',
|
||||||
|
array());
|
||||||
|
$fields = PhabricatorStandardCustomField::buildStandardFields(
|
||||||
|
$this,
|
||||||
|
$config);
|
||||||
|
|
||||||
|
return $fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -81,12 +81,17 @@ abstract class ManiphestCustomField
|
||||||
public function renderTransactionDescription(
|
public function renderTransactionDescription(
|
||||||
ManiphestTransaction $transaction,
|
ManiphestTransaction $transaction,
|
||||||
$target) {
|
$target) {
|
||||||
return 'updated a custom field';
|
$old = $transaction->getOldValue();
|
||||||
|
$new = $transaction->getNewValue();
|
||||||
|
return pht(
|
||||||
|
'updated field %s from %s to %s',
|
||||||
|
$this->getFieldName(),
|
||||||
|
$old,
|
||||||
|
$new);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getMarkupFields() {
|
public function getMarkupFields() {
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,36 +22,34 @@ If you don't need complicated display controls or sophisticated validation, you
|
||||||
can add simple fields. These allow you to attach things like strings, numbers,
|
can add simple fields. These allow you to attach things like strings, numbers,
|
||||||
and dropdown menus to the task template.
|
and dropdown menus to the task template.
|
||||||
|
|
||||||
Customize Maniphest fields by setting ##maniphest.custom-fields## in your
|
Customize Maniphest fields by setting `maniphest.custom-field-definitions` in
|
||||||
configuration. For example, suppose you want to add "Estimated Hours" and
|
your configuration. For example, suppose you want to add "Estimated Hours" and
|
||||||
"Actual Hours" fields. To do this, set your configuration like this:
|
"Actual Hours" fields. To do this, set your configuration like this:
|
||||||
|
|
||||||
'maniphest.custom-fields' => array(
|
'maniphest.custom-fields' => array(
|
||||||
'mycompany:estimated-hours' => array(
|
'mycompany:estimated-hours' => array(
|
||||||
'label' => 'Estimated Hours',
|
'name' => 'Estimated Hours',
|
||||||
'type' => 'int',
|
'type' => 'int',
|
||||||
'caption' => 'Estimated number of hours this will take.',
|
'caption' => 'Estimated number of hours this will take.',
|
||||||
'required' => false,
|
'required' => true,
|
||||||
),
|
),
|
||||||
'mycompany:actual-hours' => array(
|
'mycompany:actual-hours' => array(
|
||||||
'label' => 'Actual Hours',
|
'name' => 'Actual Hours',
|
||||||
'type' => 'int',
|
'type' => 'int',
|
||||||
'required' => false,
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
Each array key must be unique, and is used to organize the internal storage of
|
Each array key must be unique, and is used to organize the internal storage of
|
||||||
the field. These options are available:
|
the field. These options are available:
|
||||||
|
|
||||||
- **label**: Display label for the field on the edit and detail interfaces.
|
- **name**: Display label for the field on the edit and detail interfaces.
|
||||||
- **type**: Field type. The supported field types are:
|
- **type**: Field type. The supported field types are:
|
||||||
- **int**: An integer, rendered as a text field.
|
- **int**: An integer, rendered as a text field.
|
||||||
- **string**: A string, rendered as a text field.
|
- **text**: A string, rendered as a text field.
|
||||||
- **bool**: A boolean value, rendered as a checkbox.
|
- **bool**: A boolean value, rendered as a checkbox.
|
||||||
- **select**: Allows the user to select from several options, rendered
|
- **select**: Allows the user to select from several options, rendered
|
||||||
as a dropdown.
|
as a dropdown.
|
||||||
- **remarkup**: A text area which allows the user to enter markup.
|
- **remarkup**: A text area which allows the user to enter markup.
|
||||||
- **user**: A single user typeahead.
|
|
||||||
- **users**: A typeahead which allows multiple users to be input.
|
- **users**: A typeahead which allows multiple users to be input.
|
||||||
- **date**: A date/time picker.
|
- **date**: A date/time picker.
|
||||||
- **header**: Renders a visual divider which you can use to group fields.
|
- **header**: Renders a visual divider which you can use to group fields.
|
||||||
|
@ -59,14 +57,7 @@ the field. These options are available:
|
||||||
- **required**: True if the user should be required to provide a value.
|
- **required**: True if the user should be required to provide a value.
|
||||||
- **options**: If type is set to **select**, provide options for the dropdown
|
- **options**: If type is set to **select**, provide options for the dropdown
|
||||||
as a dictionary.
|
as a dictionary.
|
||||||
- **checkbox-label**: If type is set to **bool**, an optional string to
|
|
||||||
show next to the checkbox.
|
|
||||||
- **checkbox-value**: If type is set to **bool**, the value to show on
|
|
||||||
the detail view when the checkbox is selected.
|
|
||||||
- **default**: Default field value.
|
- **default**: Default field value.
|
||||||
- For **date**, you can use a string like `"July 4, 1990"`, `"5PM today"`,
|
|
||||||
or any other valid input to `strtotime()`.
|
|
||||||
- For **user** and **users**, you can use an array of user PHIDs.
|
|
||||||
- **copy**: When a user creates a task, the UI gives them an option to
|
- **copy**: When a user creates a task, the UI gives them an option to
|
||||||
"Create Another Similar Task". Some fields from the original task are copied
|
"Create Another Similar Task". Some fields from the original task are copied
|
||||||
into the new task, while others are not; by default, fields are not copied.
|
into the new task, while others are not; by default, fields are not copied.
|
||||||
|
|
|
@ -1604,6 +1604,10 @@ final class PhabricatorBuiltinPatchList extends PhabricatorSQLPatchList {
|
||||||
'type' => 'php',
|
'type' => 'php',
|
||||||
'name' => $this->getPatchPath('20130915.maniphestmigrate.php'),
|
'name' => $this->getPatchPath('20130915.maniphestmigrate.php'),
|
||||||
),
|
),
|
||||||
|
'20130919.mfieldconf.php' => array(
|
||||||
|
'type' => 'php',
|
||||||
|
'name' => $this->getPatchPath('20130919.mfieldconf.php'),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue