1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-01-18 10:41:08 +01:00

Allow custom fields to be reordered and disabled from Config

Summary: Ref T1703. Put a more reasonable UI than "blob of JSON" on top of this.

Test Plan:
Reordered, enabled and disabled user profile fields.

{F49317}

Reviewers: btrahan, chad

Reviewed By: chad

CC: aran

Maniphest Tasks: T1703

Differential Revision: https://secure.phabricator.com/D6393
This commit is contained in:
epriestley 2013-07-09 08:27:19 -07:00
parent 79f7dd457e
commit e5f200c654
4 changed files with 202 additions and 1 deletions

View file

@ -1343,6 +1343,20 @@ celerity_register_resource_map(array(
),
'disk' => '/rsrc/js/application/phortune/behavior-balanced-payment-form.js',
),
'javelin-behavior-config-reorder-fields' =>
array(
'uri' => '/res/691c5c8c/rsrc/js/application/config/behavior-reorder-fields.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'javelin-json',
4 => 'phabricator-draggable-list',
),
'disk' => '/rsrc/js/application/config/behavior-reorder-fields.js',
),
'javelin-behavior-conpherence-menu' =>
array(
'uri' => '/res/f27205d4/rsrc/js/application/conpherence/behavior-menu.js',

View file

@ -14,7 +14,11 @@ final class PhabricatorUserBlurbField
}
public function getFieldDescription() {
return pht('Short user summary.');
return pht('Short blurb about the user.');
}
public function canDisableField() {
return true;
}
protected function didSetObject(PhabricatorCustomFieldInterface $object) {

View file

@ -3,4 +3,129 @@
final class PhabricatorCustomFieldConfigOptionType
extends PhabricatorConfigOptionType {
public function readRequest(
PhabricatorConfigOption $option,
AphrontRequest $request) {
$e_value = null;
$errors = array();
$storage_value = $request->getStr('value');
$in_value = json_decode($storage_value, true);
if (!is_array($in_value)) {
$in_value = array();
}
// When we submit from JS, we submit a list (since maps are not guaranteed
// to retain order). Convert it into a map for storage (since it's far more
// convenient for us elsewhere).
$storage_value = ipull($in_value, null, 'key');
$display_value = $storage_value;
return array($e_value, $errors, $storage_value, $display_value);
}
public function renderControl(
PhabricatorConfigOption $option,
$display_value,
$e_value) {
$field_base_class = $option->getCustomData();
$field_spec = $display_value;
if (!is_array($field_spec)) {
$field_spec = PhabricatorEnv::getEnvConfig($option->getKey());
}
// Get all of the fields (including disabled fields) by querying for them
// with a faux spec where no fields are disabled.
$faux_spec = $field_spec;
foreach ($faux_spec as $key => $spec) {
unset($faux_spec[$key]['disabled']);
}
$fields = PhabricatorCustomField::buildFieldList(
$field_base_class,
$faux_spec);
$list_id = celerity_generate_unique_node_id();
$input_id = celerity_generate_unique_node_id();
$list = id(new PhabricatorObjectItemListView())
->setFlush(true)
->setID($list_id);
foreach ($fields as $key => $field) {
$item = id(new PhabricatorObjectItemView())
->addSigil('field-spec')
->setMetadata(array('fieldKey' => $key))
->setGrippable(true)
->addAttribute($field->getFieldDescription())
->setHeader($field->getFieldName());
$is_disabled = !empty($field_spec[$key]['disabled']);
$disabled_item = clone $item;
$enabled_item = clone $item;
if ($is_disabled) {
$list->addItem($disabled_item);
} else {
$list->addItem($enabled_item);
}
$disabled_item->addIcon('none', pht('Disabled'));
$disabled_item->addAction(
id(new PHUIListItemView())
->setHref('#')
->addSigil('field-spec-toggle')
->setIcon('new'));
$enabled_item->setBarColor('green');
if (!$field->canDisableField()) {
$enabled_item->addAction(
id(new PHUIListItemView())
->setIcon('lock-grey'));
$enabled_item->addIcon('none', pht('Permanent Field'));
} else {
$enabled_item->addAction(
id(new PHUIListItemView())
->setHref('#')
->addSigil('field-spec-toggle')
->setIcon('delete'));
}
$fields[$key] = array(
'disabled' => $is_disabled,
'disabledMarkup' => $disabled_item->render(),
'enabledMarkup' => $enabled_item->render(),
);
}
$input = phutil_tag(
'input',
array(
'id' => $input_id,
'type' => 'hidden',
'name' => 'value',
'value' => json_encode($display_value),
));
Javelin::initBehavior(
'config-reorder-fields',
array(
'listID' => $list_id,
'inputID' => $input_id,
'fields' => $fields,
));
return id(new AphrontFormMarkupControl())
->setLabel(pht('Value'))
->setError($e_value)
->setValue(
array(
$list,
$input,
));
}
}

View file

@ -0,0 +1,58 @@
/**
* @provides javelin-behavior-config-reorder-fields
* @requires javelin-behavior
* javelin-stratcom
* javelin-dom
* javelin-json
* phabricator-draggable-list
*/
JX.behavior('config-reorder-fields', function(config) {
var fields = config.fields;
var root = JX.$(config.listID);
var list = new JX.DraggableList('field-spec', root)
.setFindItemsHandler(function() {
return JX.DOM.scry(root, 'li', 'field-spec');
});
list.listen('didDrop', function(node, after) {
write_state_to_form();
});
JX.DOM.listen(root, 'click', 'field-spec-toggle', function(e) {
e.kill();
var key = e.getNodeData('field-spec').fieldKey;
fields[key].disabled = !fields[key].disabled;
JX.DOM.replace(
e.getNode('field-spec'),
JX.$H(
fields[key].disabled ?
fields[key].disabledMarkup :
fields[key].enabledMarkup));
write_state_to_form();
});
var write_state_to_form = function() {
var nodes = list.findItems();
var order = [];
var key;
for (var ii = 0; ii < nodes.length; ii++) {
key = JX.Stratcom.getData(nodes[ii]).fieldKey;
if (key) {
order.push({
key: key,
disabled: fields[key].disabled
});
}
}
JX.$(config.inputID).value = JX.JSON.stringify(order);
};
});