1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-28 16:30:59 +01:00

Begin modularizing Herald field values

Summary:
Ref T8726. I'm primarily trying to modularize tokenizer values so we don't have to update JS to add a new one.

This is ultimately the blocker for "select" custom fields working in Herald.

This inches us toward that. I'm //not// modularizing conditions or control types in this round, but hope to end up with hard-coded conditions (which are highly general and very rarely change), hard-coded control types (which are also highly general and very rarely change) and completely modular fields and values (which have mid-to-low generality and change frequently).

Test Plan: Used UI to interact with "none", "text", and new-style "select" controls. No actual support for tokenizers yet.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T8726

Differential Revision: https://secure.phabricator.com/D13613
This commit is contained in:
epriestley 2015-07-16 14:12:00 -07:00
parent b2b739c709
commit a9caab49f7
10 changed files with 204 additions and 33 deletions

View file

@ -382,7 +382,7 @@ return array(
'rsrc/js/application/doorkeeper/behavior-doorkeeper-tag.js' => 'e5822781',
'rsrc/js/application/files/behavior-icon-composer.js' => '8ef9ab58',
'rsrc/js/application/files/behavior-launch-icon-composer.js' => '48086888',
'rsrc/js/application/herald/HeraldRuleEditor.js' => 'b2cae298',
'rsrc/js/application/herald/HeraldRuleEditor.js' => '0f85bdfd',
'rsrc/js/application/herald/PathTypeahead.js' => 'f7fc67ec',
'rsrc/js/application/herald/herald-rule-editor.js' => '7ebaeed3',
'rsrc/js/application/maniphest/behavior-batch-editor.js' => '782ab6e7',
@ -538,7 +538,7 @@ return array(
'global-drag-and-drop-css' => '697324ad',
'harbormaster-css' => '49d64eb4',
'herald-css' => '826075fa',
'herald-rule-editor' => 'b2cae298',
'herald-rule-editor' => '0f85bdfd',
'herald-test-css' => '778b008e',
'inline-comment-summary-css' => '51efda3a',
'javelin-aphlict' => '5359e785',
@ -918,6 +918,15 @@ return array(
'javelin-install',
'javelin-util',
),
'0f85bdfd' => array(
'multirow-row-manager',
'javelin-install',
'javelin-util',
'javelin-dom',
'javelin-stratcom',
'javelin-json',
'phabricator-prefab',
),
'13c739ea' => array(
'javelin-behavior',
'javelin-stratcom',
@ -1676,15 +1685,6 @@ return array(
'javelin-uri',
'javelin-request',
),
'b2cae298' => array(
'multirow-row-manager',
'javelin-install',
'javelin-util',
'javelin-dom',
'javelin-stratcom',
'javelin-json',
'phabricator-prefab',
),
'b3a4b884' => array(
'javelin-behavior',
'phabricator-prefab',

View file

@ -1018,9 +1018,11 @@ phutil_register_library_map(array(
'HeraldDifferentialRevisionAdapter' => 'applications/differential/herald/HeraldDifferentialRevisionAdapter.php',
'HeraldDisableController' => 'applications/herald/controller/HeraldDisableController.php',
'HeraldEffect' => 'applications/herald/engine/HeraldEffect.php',
'HeraldEmptyFieldValue' => 'applications/herald/value/HeraldEmptyFieldValue.php',
'HeraldEngine' => 'applications/herald/engine/HeraldEngine.php',
'HeraldField' => 'applications/herald/field/HeraldField.php',
'HeraldFieldTestCase' => 'applications/herald/field/__tests__/HeraldFieldTestCase.php',
'HeraldFieldValue' => 'applications/herald/value/HeraldFieldValue.php',
'HeraldInvalidActionException' => 'applications/herald/engine/exception/HeraldInvalidActionException.php',
'HeraldInvalidConditionException' => 'applications/herald/engine/exception/HeraldInvalidConditionException.php',
'HeraldManageGlobalRulesCapability' => 'applications/herald/capability/HeraldManageGlobalRulesCapability.php',
@ -1050,9 +1052,11 @@ phutil_register_library_map(array(
'HeraldRuleTypeConfig' => 'applications/herald/config/HeraldRuleTypeConfig.php',
'HeraldRuleViewController' => 'applications/herald/controller/HeraldRuleViewController.php',
'HeraldSchemaSpec' => 'applications/herald/storage/HeraldSchemaSpec.php',
'HeraldSelectFieldValue' => 'applications/herald/value/HeraldSelectFieldValue.php',
'HeraldSpaceField' => 'applications/spaces/herald/HeraldSpaceField.php',
'HeraldSubscribersField' => 'applications/subscriptions/herald/HeraldSubscribersField.php',
'HeraldTestConsoleController' => 'applications/herald/controller/HeraldTestConsoleController.php',
'HeraldTextFieldValue' => 'applications/herald/value/HeraldTextFieldValue.php',
'HeraldTransactionQuery' => 'applications/herald/query/HeraldTransactionQuery.php',
'HeraldTranscript' => 'applications/herald/storage/transcript/HeraldTranscript.php',
'HeraldTranscriptController' => 'applications/herald/controller/HeraldTranscriptController.php',
@ -4615,9 +4619,11 @@ phutil_register_library_map(array(
'HeraldDifferentialRevisionAdapter' => 'HeraldDifferentialAdapter',
'HeraldDisableController' => 'HeraldController',
'HeraldEffect' => 'Phobject',
'HeraldEmptyFieldValue' => 'HeraldFieldValue',
'HeraldEngine' => 'Phobject',
'HeraldField' => 'Phobject',
'HeraldFieldTestCase' => 'PhutilTestCase',
'HeraldFieldValue' => 'Phobject',
'HeraldInvalidActionException' => 'Exception',
'HeraldInvalidConditionException' => 'Exception',
'HeraldManageGlobalRulesCapability' => 'PhabricatorPolicyCapability',
@ -4653,9 +4659,11 @@ phutil_register_library_map(array(
'HeraldRuleTypeConfig' => 'Phobject',
'HeraldRuleViewController' => 'HeraldController',
'HeraldSchemaSpec' => 'PhabricatorConfigSchemaSpec',
'HeraldSelectFieldValue' => 'HeraldFieldValue',
'HeraldSpaceField' => 'HeraldField',
'HeraldSubscribersField' => 'HeraldField',
'HeraldTestConsoleController' => 'HeraldController',
'HeraldTextFieldValue' => 'HeraldFieldValue',
'HeraldTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'HeraldTranscript' => array(
'HeraldDAO',

View file

@ -440,6 +440,7 @@ final class HeraldRuleController extends HeraldController {
$config_info['fields'] = $field_map;
$config_info['conditions'] = $all_conditions;
$config_info['actions'] = $action_map;
$config_info['valueMap'] = array();
foreach ($config_info['fields'] as $field => $name) {
try {
@ -452,10 +453,17 @@ final class HeraldRuleController extends HeraldController {
foreach ($config_info['fields'] as $field => $fname) {
foreach ($config_info['conditionMap'][$field] as $condition) {
$value_type = $adapter->getValueTypeForFieldAndCondition(
$value_key = $adapter->getValueTypeForFieldAndCondition(
$field,
$condition);
$config_info['values'][$field][$condition] = $value_type;
if ($value_key instanceof HeraldFieldValue) {
$spec = $value_key->getControlSpecificationDictionary();
$value_key = $value_key->getFieldValueKey();
$config_info['valueMap'][$value_key] = $spec;
}
$config_info['values'][$field][$condition] = $value_key;
}
}
@ -482,10 +490,6 @@ final class HeraldRuleController extends HeraldController {
'conditions' => (object)$serial_conditions,
'actions' => (object)$serial_actions,
'select' => array(
HeraldAdapter::VALUE_CONTENT_SOURCE => array(
'options' => PhabricatorContentSource::getSourceNameMap(),
'default' => PhabricatorContentSource::SOURCE_WEB,
),
HeraldAdapter::VALUE_FLAG_COLOR => array(
'options' => PhabricatorFlagColor::getColorNameMap(),
'default' => PhabricatorFlagColor::COLOR_BLUE,
@ -509,10 +513,6 @@ final class HeraldRuleController extends HeraldController {
'template' => $this->buildTokenizerTemplates($handles) + array(
'rules' => $all_rules,
),
'author' => array(
$rule->getAuthorPHID() =>
$handles[$rule->getAuthorPHID()]->getName(),
),
'info' => $config_info,
));
}

View file

@ -20,7 +20,13 @@ final class HeraldContentSourceField extends HeraldField {
}
public function getHeraldFieldValueType($condition) {
return HeraldAdapter::VALUE_CONTENT_SOURCE;
$map = PhabricatorContentSource::getSourceNameMap();
asort($map);
return id(new HeraldSelectFieldValue())
->setKey(self::FIELDCONST)
->setDefault(PhabricatorContentSource::SOURCE_WEB)
->setOptions($map);
}
public function supportsObject($object) {

View file

@ -86,11 +86,11 @@ abstract class HeraldField extends Phobject {
switch ($standard_type) {
case self::STANDARD_BOOL:
case self::STANDARD_PHID_BOOL:
return HeraldAdapter::VALUE_NONE;
return new HeraldEmptyFieldValue();
case self::STANDARD_TEXT:
case self::STANDARD_TEXT_LIST:
case self::STANDARD_TEXT_MAP:
return HeraldAdapter::VALUE_TEXT;
return new HeraldTextFieldValue();
}
throw new Exception(

View file

@ -0,0 +1,14 @@
<?php
final class HeraldEmptyFieldValue
extends HeraldFieldValue {
public function getFieldValueKey() {
return 'none';
}
public function getControlType() {
return self::CONTROL_NONE;
}
}

View file

@ -0,0 +1,24 @@
<?php
abstract class HeraldFieldValue extends Phobject {
const CONTROL_NONE = 'herald.control.none';
const CONTROL_TEXT = 'herald.control.text';
const CONTROL_SELECT = 'herald.control.select';
const CONTROL_TOKENIZER = 'herald.control.tokenizer';
abstract public function getFieldValueKey();
abstract public function getControlType();
final public function getControlSpecificationDictionary() {
return array(
'control' => $this->getControlType(),
'template' => $this->getControlTemplate(),
);
}
protected function getControlTemplate() {
return array();
}
}

View file

@ -0,0 +1,59 @@
<?php
final class HeraldSelectFieldValue
extends HeraldFieldValue {
private $key;
private $options;
private $default;
public function setKey($key) {
$this->key = $key;
return $this;
}
public function getKey() {
return $this->key;
}
public function setOptions(array $options) {
$this->options = $options;
return $this;
}
public function getOptions() {
return $this->options;
}
public function setDefault($default) {
$this->default = $default;
return $this;
}
public function getDefault() {
return $this->default;
}
public function getFieldValueKey() {
if ($this->getKey() === null) {
throw new PhutilInvalidStateException('setKey');
}
return 'select.'.$this->getKey();
}
public function getControlType() {
return self::CONTROL_SELECT;
}
protected function getControlTemplate() {
if ($this->getOptions() === null) {
throw new PhutilInvalidStateException('setOptions');
}
return array(
'options' => $this->getOptions(),
'default' => $this->getDefault(),
);
}
}

View file

@ -0,0 +1,14 @@
<?php
final class HeraldTextFieldValue
extends HeraldFieldValue {
public function getFieldValueKey() {
return 'text';
}
public function getControlType() {
return self::CONTROL_TEXT;
}
}

View file

@ -200,7 +200,48 @@ JX.install('HeraldRuleEditor', {
return node;
},
_buildStandardInput: function(spec) {
var input;
var get_fn;
var set_fn;
switch (spec.control) {
case 'herald.control.none':
input = null;
get_fn = JX.bag;
set_fn = JX.bag;
break;
case 'herald.control.text':
input = JX.$N('input', {type: 'text'});
get_fn = function() { return input.value; };
set_fn = function(v) { input.value = v; };
break;
case 'herald.control.select':
input = this._renderSelect(spec.template.options);
get_fn = function() { return input.value; };
set_fn = function(v) { input.value = v; };
if (spec.template.default) {
set_fn(spec.template.default);
}
break;
case 'herald.control.tokenizer':
var tokenizer = this._newTokenizer(spec.template.tokenizer, true);
input = tokenizer[0];
get_fn = tokenizer[1];
set_fn = tokenizer[2];
break;
default:
JX.$E('No rules to build control "' + spec.control + '".');
break;
}
return [input, get_fn, set_fn];
},
_buildInput : function(type) {
if (this._config.info.valueMap[type]) {
return this._buildStandardInput(this._config.info.valueMap[type]);
}
var input;
var get_fn;
var set_fn;
@ -233,7 +274,6 @@ JX.install('HeraldRuleEditor', {
get_fn = JX.bag;
set_fn = JX.bag;
break;
case 'contentsource':
case 'flagcolor':
case 'value-ref-type':
case 'value-ref-change':
@ -276,14 +316,20 @@ JX.install('HeraldRuleEditor', {
return node;
},
_newTokenizer : function(type) {
var tokenizerConfig = {
src : this._config.template.source[type].uri,
placeholder: this._config.template.source[type].placeholder,
browseURI: this._config.template.source[type].browseURI,
icons : this._config.template.icons,
username : this._config.username
};
_newTokenizer : function(type, is_config) {
var tokenizerConfig;
if (is_config) {
tokenizerConfig = type;
} else {
tokenizerConfig = {
src : this._config.template.source[type].uri,
placeholder: this._config.template.source[type].placeholder,
browseURI: this._config.template.source[type].browseURI,
icons : this._config.template.icons,
username : this._config.username
};
}
var build = JX.Prefab.newTokenizerFromTemplate(
this._config.template.markup,