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:
parent
b2b739c709
commit
a9caab49f7
10 changed files with 204 additions and 33 deletions
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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,
|
||||
));
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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(
|
||||
|
|
14
src/applications/herald/value/HeraldEmptyFieldValue.php
Normal file
14
src/applications/herald/value/HeraldEmptyFieldValue.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
final class HeraldEmptyFieldValue
|
||||
extends HeraldFieldValue {
|
||||
|
||||
public function getFieldValueKey() {
|
||||
return 'none';
|
||||
}
|
||||
|
||||
public function getControlType() {
|
||||
return self::CONTROL_NONE;
|
||||
}
|
||||
|
||||
}
|
24
src/applications/herald/value/HeraldFieldValue.php
Normal file
24
src/applications/herald/value/HeraldFieldValue.php
Normal 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();
|
||||
}
|
||||
|
||||
}
|
59
src/applications/herald/value/HeraldSelectFieldValue.php
Normal file
59
src/applications/herald/value/HeraldSelectFieldValue.php
Normal 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(),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
14
src/applications/herald/value/HeraldTextFieldValue.php
Normal file
14
src/applications/herald/value/HeraldTextFieldValue.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
final class HeraldTextFieldValue
|
||||
extends HeraldFieldValue {
|
||||
|
||||
public function getFieldValueKey() {
|
||||
return 'text';
|
||||
}
|
||||
|
||||
public function getControlType() {
|
||||
return self::CONTROL_TEXT;
|
||||
}
|
||||
|
||||
}
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue