/**
* Permission grants: dashboard permissions and in-game commands given to (or taken from) one account or character.
* Grants.mount(el, {type, id}): the grants of one account or character, with a form to add one when the viewer may.
* Grants.mount(el, null): every grant in force and the history, with a form that asks whose it is (Permissions page).
* The server decides what may be granted (only what the viewer holds, on accounts they may manage); the form offers
* only those.
*/
(function () {
var KINDS = [
['permission', 'Dashboard permission'],
['command', 'In-game command'],
['permission_group', 'Every permission of a category'],
['command_group', 'Every command up to a GM level']
];
var catalog = null;
function loadCatalog() {
if (!catalog) {
catalog = api.get('/api/grants/catalog').then(function (d) {
if (!d.success) throw new Error(d.error || 'Could not load what can be granted');
return d;
});
catalog.catch(function () { catalog = null; });
}
return catalog;
}
// What can be picked for a kind: [{value, label, detail}], only what the viewer may grant
function choices(d, kind, text) {
var list;
if (kind === 'permission') {
list = d.permissions.map(function (p) {
return { value: p.key, label: p.title + ' (' + p.key + ')', detail: p.category + ' · GM ' + p.level + '+ · ' + p.description, ok: p.grantable, why: p.reason };
});
} else if (kind === 'command') {
list = d.commands.map(function (c) {
return { value: c.name, label: '/' + c.aliases[0] + (c.aliases.length > 1 ? ' (also /' + c.aliases.slice(1).join(', /') + ')' : ''),
detail: 'GM ' + c.level + '+' + (c.permission ? ' · follows ' + c.permission : '') + ' · ' + c.help, ok: c.grantable, why: c.reason };
});
} else if (kind === 'permission_group') {
list = d.permissionGroups.map(function (g) {
return { value: g.name, label: g.name, detail: g.permissions.join(', '), ok: g.grantable, why: g.reason };
});
} else {
list = d.commandGroups.map(function (g) {
return { value: g.name, label: 'Every command up to GM ' + g.name, detail: '', ok: g.grantable, why: g.reason };
});
}
var query = (text || '').toLowerCase();
return list.filter(function (item) {
return item.ok && (!query || (item.label + ' ' + item.value + ' ' + item.detail).toLowerCase().indexOf(query) !== -1);
}).slice(0, 60);
}
function status(g) {
if (g.status === 'removed') return fmt.badge('Removed', 'secondary');
if (g.status === 'expired') return fmt.badge('Expired', 'secondary');
return fmt.badge('In force', 'success');
}
function targetLink(g) {
if (g.targetType === 'account') return 'Account ' + fmt.link('/accounts/' + g.targetId, g.targetName || g.targetId);
return 'Character ' + fmt.character(g.targetId, g.targetName);
}
function rows(list, options) {
if (!list.length) return '