1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-29 17:00:59 +01:00
phorge-phorge/webroot/rsrc/js/phuix/PHUIXFormControl.js
epriestley fab37aa4e3 When accepting revisions, allow users to accept on behalf of a subset of reviewers
Summary:
Ref T12271. Currenty, when you "Accept" a revision, you always accept it for all reviewers you have authority over.

There are some situations where communication can be more clear if users can accept as only themselves, or for only some packages, etc. T12271 discusses some of these use cases in more depth.

Instead of making "Accept" a blanket action, default it to doing what it does now but let the user uncheck reviewers.

In cases where project/package reviewers aren't in use, this doesn't change anything.

For now, "reject" still acts the old way (reject everything). We could make that use checkboxes too, but I'm not sure there's as much of a use case for it, and I generally want users who are blocking stuff to have more direct accountability in a product sense.

Test Plan:
  - Accepted normally.
  - Accepted a subset.
  - Tried to accept none.
  - Tried to accept bogus reviewers.
  - Accepted with myself not a reviewer
  - Accepted with only one reviewer (just got normal "this will be accepted" text).

{F4251255}

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T12271

Differential Revision: https://secure.phabricator.com/D17533
2017-03-22 14:25:04 -07:00

336 lines
7.1 KiB
JavaScript

/**
* @provides phuix-form-control-view
* @requires javelin-install
* javelin-dom
*/
JX.install('PHUIXFormControl', {
members: {
_node: null,
_labelNode: null,
_errorNode: null,
_inputNode: null,
_className: null,
_valueSetCallback: null,
_valueGetCallback: null,
setLabel: function(label) {
JX.DOM.setContent(this._getLabelNode(), label);
return this;
},
setError: function(error) {
JX.DOM.setContent(this._getErrorNode(), error);
return this;
},
setClass: function(className) {
this._className = className;
return this;
},
setControl: function(type, spec) {
var node = this._getInputNode();
var input;
switch (type) {
case 'tokenizer':
input = this._newTokenizer(spec);
break;
case 'select':
input = this._newSelect(spec);
break;
case 'points':
input = this._newPoints(spec);
break;
case 'optgroups':
input = this._newOptgroups(spec);
break;
case 'static':
input = this._newStatic(spec);
break;
case 'checkboxes':
input = this._newCheckboxes(spec);
break;
default:
// TODO: Default or better error?
JX.$E('Bad Input Type');
return;
}
JX.DOM.setContent(node, input.node);
this._valueGetCallback = input.get;
this._valueSetCallback = input.set;
return this;
},
setValue: function(value) {
this._valueSetCallback(value);
return this;
},
getValue: function() {
return this._valueGetCallback();
},
getNode: function() {
if (!this._node) {
var attrs = {
className: 'aphront-form-control ' + this._className + ' grouped'
};
var content = [
this._getLabelNode(),
this._getErrorNode(),
this._getInputNode()
];
this._node = JX.$N('div', attrs, content);
}
return this._node;
},
_getLabelNode: function() {
if (!this._labelNode) {
var attrs = {
className: 'aphront-form-label'
};
this._labelNode = JX.$N('label', attrs);
}
return this._labelNode;
},
_getErrorNode: function() {
if (!this._errorNode) {
var attrs = {
className: 'aphront-form-error'
};
this._errorNode = JX.$N('span', attrs);
}
return this._errorNode;
},
_getInputNode: function() {
if (!this._inputNode) {
var attrs = {
className: 'aphront-form-input'
};
this._inputNode = JX.$N('div', attrs);
}
return this._inputNode;
},
_newTokenizer: function(spec) {
var build = JX.Prefab.newTokenizerFromTemplate(
spec.markup,
spec.config);
build.tokenizer.start();
function get_value() {
return JX.keys(build.tokenizer.getTokens());
}
function set_value(map) {
var tokens = get_value();
for (var ii = 0; ii < tokens.length; ii++) {
build.tokenizer.removeToken(tokens[ii]);
}
for (var k in map) {
var v = JX.Prefab.transformDatasourceResults(map[k]);
build.tokenizer.addToken(k, v);
}
}
set_value(spec.value || {});
return {
node: build.node,
get: get_value,
set: set_value
};
},
_newSelect: function(spec) {
var node = JX.Prefab.renderSelect(
spec.options,
spec.value,
{},
spec.order);
return {
node: node,
get: function() {
return node.value;
},
set: function(value) {
node.value = value;
}
};
},
_newStatic: function(spec) {
var node = JX.$N(
'div',
{
className: 'phui-form-static-action'
},
spec.description || '');
return {
node: node,
get: function() {
return true;
},
set: function() {
return;
}
};
},
_newCheckboxes: function(spec) {
var checkboxes = [];
var checkbox_list = [];
for (var ii = 0; ii < spec.keys.length; ii++) {
var key = spec.keys[ii];
var checkbox_id = 'checkbox-' + Math.floor(Math.random() * 1000000);
var checkbox = JX.$N(
'input',
{
type: 'checkbox',
value: key,
id: checkbox_id
});
checkboxes.push(checkbox);
var label = JX.$N(
'label',
{
className: 'phuix-form-checkbox-label',
htmlFor: checkbox_id
},
JX.$H(spec.labels[key] || ''));
var display = JX.$N(
'div',
{
className: 'phuix-form-checkbox-item'
},
[checkbox, label]);
checkbox_list.push(display);
}
var node = JX.$N(
'div',
{
className: 'phuix-form-checkbox-action'
},
checkbox_list);
var get_value = function() {
var list = [];
for (var ii = 0; ii < checkboxes.length; ii++) {
if (checkboxes[ii].checked) {
list.push(checkboxes[ii].value);
}
}
return list;
};
var set_value = function(value) {
value = value || [];
if (!value.length) {
value = [];
}
var map = {};
var ii;
for (ii = 0; ii < value.length; ii++) {
map[value[ii]] = true;
}
for (ii = 0; ii < checkboxes.length; ii++) {
if (map.hasOwnProperty(checkboxes[ii].value)) {
checkboxes[ii].checked = 'checked';
} else {
checkboxes[ii].checked = false;
}
}
};
set_value(spec.value);
return {
node: node,
get: get_value,
set: set_value
};
},
_newPoints: function(spec) {
var attrs = {
type: 'text',
value: spec.value
};
var node = JX.$N('input', attrs);
return {
node: node,
get: function() {
return node.value;
},
set: function(value) {
node.value = value;
}
};
},
_newOptgroups: function(spec) {
var value = spec.value || null;
var optgroups = [];
for (var ii = 0; ii < spec.groups.length; ii++) {
var group = spec.groups[ii];
var options = [];
for (var jj = 0; jj < group.options.length; jj++) {
var option = group.options[jj];
options.push(JX.$N('option', {value: option.key}, option.label));
if (option.selected && (value === null)) {
value = option.key;
}
}
optgroups.push(JX.$N('optgroup', {label: group.label}, options));
}
var node = JX.$N('select', {}, optgroups);
node.value = value;
return {
node: node,
get: function() {
return node.value;
},
set: function(value) {
node.value = value;
}
};
}
}
});