1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-30 17:30:59 +01:00
phorge-phorge/webroot/rsrc/js/application/releeph/releeph-request-state-change.js

146 lines
3.5 KiB
JavaScript
Raw Normal View History

/**
* @provides javelin-behavior-releeph-request-state-change
* @requires javelin-behavior
* javelin-dom
* javelin-stratcom
* javelin-request
* phabricator-keyboard-shortcut
* phabricator-notification
*/
JX.behavior('releeph-request-state-change', function(config) {
var root = JX.DOM.find(document, 'div', 'releeph-request-header-list');
function getRequestHeaderNodes() {
return JX.DOM.scry(root, 'div', 'releeph-request-header');
}
/**
* Keyboard navigation
*/
var keynav_cursor = -1;
var notification = new JX.Notification();
function keynavJump(manager, delta) {
// Calculate this everytime, because the DOM changes.
var headers = getRequestHeaderNodes();
keynav_cursor += delta;
if (keynav_cursor < 0) {
keynav_cursor = -1;
window.scrollTo(0);
keynavMarkup();
return;
}
if (keynav_cursor >= headers.length) {
keynav_cursor = headers.length - 1;
}
var focus = headers[keynav_cursor];
manager.scrollTo(focus);
keynavMarkup();
}
function keynavMarkup() {
var headers = getRequestHeaderNodes();
for (var k in headers) {
JX.DOM.alterClass(headers[k], 'focus', k == keynav_cursor);
}
}
function keynavAction(manager, action_name) {
var headers = getRequestHeaderNodes();
var header = headers[keynav_cursor];
if (keynav_cursor < 0) {
return;
}
var sigil = action_name;
var button = JX.DOM.find(header, 'a', sigil);
if (button) {
button.click();
}
}
function keynavNavigateToRequestPage() {
var headers = getRequestHeaderNodes();
var header = headers[keynav_cursor];
JX.DOM.find(header, 'a', 'hidden-link').click();
}
new JX.KeyboardShortcut('j', 'Jump to next request.')
.setHandler(function(manager) {
keynavJump(manager, +1);
})
.register();
new JX.KeyboardShortcut('k', 'Jump to previous request.')
.setHandler(function(manager) {
keynavJump(manager, -1);
})
.register();
new JX.KeyboardShortcut('a', 'Approve the selected request.')
.setHandler(function(manager) {
keynavAction(manager, 'want');
})
.register();
new JX.KeyboardShortcut('r', 'Reject the selected request.')
.setHandler(function(manager) {
keynavAction(manager, 'pass');
})
.register();
new JX.KeyboardShortcut('g', "Open selected request's page in a new tab.")
.setHandler(function(manager) {
keynavNavigateToRequestPage();
})
.register();
/**
* AJAXy state changes for request buttons.
*/
function request_action(node, url) {
var request = new JX.Request(url, function(response) {
if (config.reload) {
window.location.reload();
} else {
var markup = JX.$H(response.markup);
JX.DOM.replace(node, markup);
keynavMarkup();
}
});
request.send();
}
JX.Stratcom.listen(
'click',
'releeph-request-state-change',
function(e) {
var button = e.getNode('releeph-request-state-change');
var node = e.getNode('releeph-request-header');
var url = e.getNodeData('releeph-request-state-change');
// If this button has no action, or we've already responded to the first
// click...
if (!url || button.disabled) {
return;
}
// There's a race condition here though :(
JX.DOM.alterClass(button, 'disabled', true);
button.disabled = true;
e.prevent();
request_action(node, url);
}
);
});