Summary: Currently, when a dialog is submitted the Workflow itself emits an event but no DOM event is emitted. The workflow event is fine for handlers which only use JS, but there's currently no way for a handler to act more like a normal form handler. This event gives normal form handlers a way to capture Workflow submits and muck around with form contents, etc. Test Plan: In a future diff, edited policies via a Workflow dialog. Reviewers: btrahan Reviewed By: btrahan CC: aran Differential Revision: https://secure.phabricator.com/D7295
180 lines
4.4 KiB
JavaScript
180 lines
4.4 KiB
JavaScript
/**
|
|
* @provides javelin-behavior-policy-rule-editor
|
|
* @requires javelin-behavior
|
|
* multirow-row-manager
|
|
* javelin-dom
|
|
* javelin-util
|
|
* phabricator-prefab
|
|
* javelin-tokenizer
|
|
* javelin-typeahead
|
|
* javelin-typeahead-preloaded-source
|
|
* javelin-json
|
|
*/
|
|
JX.behavior('policy-rule-editor', function(config) {
|
|
var root = JX.$(config.rootID);
|
|
var rows = [];
|
|
var data = {};
|
|
|
|
JX.DOM.listen(
|
|
root,
|
|
'click',
|
|
'create-rule',
|
|
function(e) {
|
|
e.kill();
|
|
new_rule(config.defaultRule);
|
|
});
|
|
|
|
JX.DOM.listen(
|
|
root,
|
|
'change',
|
|
'rule-select',
|
|
function(e) {
|
|
e.kill();
|
|
|
|
var row = e.getNode(JX.MultirowRowManager.getRowSigil());
|
|
var row_id = rules_manager.getRowID(row);
|
|
|
|
data[row_id].rule = data[row_id].ruleNode.value;
|
|
data[row_id].value = null;
|
|
|
|
redraw(row_id);
|
|
});
|
|
|
|
JX.DOM.listen(
|
|
JX.DOM.findAbove(root, 'form'),
|
|
['submit', 'didWorkflowSubmit'],
|
|
null,
|
|
function(e) {
|
|
var rules = JX.DOM.find(e.getNode('tag:form'), 'input', 'rules');
|
|
|
|
var value = [];
|
|
for (var ii = 0; ii < rows.length; ii++) {
|
|
var row_data = data[rows[ii]];
|
|
|
|
var row_dict = {
|
|
action: row_data.actionNode.value,
|
|
rule: row_data.rule,
|
|
value: row_data.getValue()
|
|
};
|
|
|
|
value.push(row_dict);
|
|
}
|
|
|
|
rules.value = JX.JSON.stringify(value);
|
|
});
|
|
|
|
|
|
var rules_table = JX.DOM.find(root, 'table', 'rules');
|
|
var rules_manager = new JX.MultirowRowManager(rules_table);
|
|
rules_manager.listen(
|
|
'row-removed',
|
|
function(row_id) {
|
|
delete data[row_id];
|
|
for (var ii = 0; ii < rows.length; ii++) {
|
|
if (rows[ii] == row_id) {
|
|
rows.splice(ii, 1);
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
function new_rule(spec) {
|
|
var row = rules_manager.addRow([]);
|
|
var row_id = rules_manager.getRowID(row);
|
|
|
|
rows.push(row_id);
|
|
data[row_id] = JX.copy({}, spec);
|
|
|
|
redraw(row_id);
|
|
}
|
|
|
|
function redraw(row_id) {
|
|
var action_content = JX.Prefab.renderSelect(
|
|
config.actions,
|
|
data[row_id].action);
|
|
data[row_id].actionNode = action_content;
|
|
var action_cell = JX.$N('td', {className: "action-cell"}, action_content);
|
|
|
|
var rule_content = JX.Prefab.renderSelect(
|
|
config.rules,
|
|
data[row_id].rule,
|
|
{sigil: 'rule-select'});
|
|
data[row_id].ruleNode = rule_content;
|
|
var rule_cell = JX.$N('td', {className: "rule-cell"}, rule_content);
|
|
|
|
var input = render_input(data[row_id].rule, null);
|
|
|
|
var value_content = input.node;
|
|
data[row_id].getValue = input.get;
|
|
input.set(data[row_id].value);
|
|
|
|
var value_cell = JX.$N('td', {className: "value-cell"}, value_content);
|
|
|
|
rules_manager.updateRow(row_id, [action_cell, rule_cell, value_cell]);
|
|
}
|
|
|
|
function render_input(rule, value) {
|
|
var node, get_fn, set_fn;
|
|
var type = config.types[rule];
|
|
var template = config.templates[rule];
|
|
|
|
switch (type) {
|
|
case 'tokenizer':
|
|
node = JX.$H(template.markup).getNode();
|
|
node.id = '';
|
|
|
|
var datasource = new JX.TypeaheadPreloadedSource(template.uri);
|
|
|
|
var typeahead = new JX.Typeahead(node);
|
|
typeahead.setDatasource(datasource);
|
|
|
|
var tokenizer = new JX.Tokenizer(node);
|
|
tokenizer.setLimit(template.limit);
|
|
tokenizer.setTypeahead(typeahead);
|
|
tokenizer.setPlaceholder(template.placeholder);
|
|
tokenizer.start();
|
|
|
|
get_fn = function() { return JX.keys(tokenizer.getTokens()); };
|
|
set_fn = function(map) {
|
|
if (!map) {
|
|
return;
|
|
}
|
|
for (var k in map) {
|
|
tokenizer.addToken(k, map[k]);
|
|
}
|
|
};
|
|
break;
|
|
case 'none':
|
|
node = null;
|
|
get_fn = JX.bag;
|
|
set_fn = JX.bag;
|
|
break;
|
|
case 'select':
|
|
node = JX.Prefab.renderSelect(
|
|
config.templates[rule].options,
|
|
value);
|
|
get_fn = function() { return node.value; };
|
|
set_fn = function(v) { node.value = v; };
|
|
break;
|
|
default:
|
|
case 'text':
|
|
node = JX.$N('input', {type: 'text'});
|
|
get_fn = function() { return node.value; };
|
|
set_fn = function(v) { node.value = v; };
|
|
break;
|
|
}
|
|
|
|
return {
|
|
node: node,
|
|
get: get_fn,
|
|
set: set_fn
|
|
};
|
|
}
|
|
|
|
for (var ii = 0; ii < config.data.length; ii++) {
|
|
new_rule(config.data[ii]);
|
|
}
|
|
|
|
});
|