cryptpad/www/moderation/inner.js

311 lines
11 KiB
JavaScript
Raw Normal View History

2024-02-12 21:30:33 +08:00
// SPDX-FileCopyrightText: 2023 XWiki CryptPad Team <contact@cryptpad.org> and contributors
//
// SPDX-License-Identifier: AGPL-3.0-or-later
define([
'jquery',
'/api/config',
'/customize/application_config.js',
'/common/toolbar.js',
'/components/nthen/index.js',
'/common/sframe-common.js',
'/common/hyperscript.js',
'/customize/messages.js',
'/common/common-interface.js',
'/common/common-ui-elements.js',
'/common/common-util.js',
'/common/common-hash.js',
'/common/inner/sidebar-layout.js',
2024-02-12 21:30:33 +08:00
'/support/ui.js',
'css!/components/components-font-awesome/css/font-awesome.min.css',
'less!/moderation/app-moderation.less',
], function (
$,
ApiConfig,
AppConfig,
Toolbar,
nThen,
SFCommon,
h,
Messages,
UI,
UIElements,
Util,
Hash,
Sidebar,
2024-02-12 21:30:33 +08:00
Support,
)
{
var APP = {};
2024-02-12 21:30:33 +08:00
var common;
var sframeChan;
var events = {
'NEW_TICKET': Util.mkEvent(),
'UPDATE_TICKET': Util.mkEvent()
};
2024-02-12 21:30:33 +08:00
// XXX
Messages.support_activeListTitle = "Active tickets";
Messages.support_activeListHint = "List of tickets that are in an active state";
Messages.support_pendingListTitle = "Pending tickets";
Messages.support_pendingListHint = "List of tickets that may not be updated for a while but should not be closed";
2024-02-21 00:50:41 +08:00
Messages.support_privacyTitle = "Answer anonymously";
Messages.support_privacyHint = "Check this option to reply as 'The Support Team' instead of your own usenrame";
2024-02-16 01:37:08 +08:00
var andThen = function (common, $container, linkedTicket) {
const sidebar = Sidebar.create(common, 'support', $container);
const blocks = sidebar.blocks;
2024-02-16 01:37:08 +08:00
// Support panel functions
let open = [];
2024-02-21 00:50:41 +08:00
let refresh = ($container, type) => {
APP.module.execCommand('LIST_TICKETS_ADMIN', {
type: type
}, (tickets) => {
let activeForms = {};
$container.find('.cp-support-form-container').each((i, el) => {
let id = $(el).attr('data-id');
if (!id) { return; }
activeForms[id] = el;
});
2024-02-16 01:37:08 +08:00
$container.empty();
var col1 = h('div.cp-support-column', h('h1', [
h('span', Messages.admin_support_premium),
h('span.cp-support-count'),
]));
var col2 = h('div.cp-support-column', h('h1', [
h('span', Messages.admin_support_normal),
h('span.cp-support-count'),
]));
var col3 = h('div.cp-support-column', h('h1', [
h('span', Messages.admin_support_answered),
h('span.cp-support-count'),
]));
2024-02-21 00:50:41 +08:00
var col4 = h('div.cp-support-column', h('h1', [
h('span', Messages.admin_support_closed),
h('span.cp-support-count'),
]));
if (type === 'closed') {
// Only one column
col1 = col2 = col3 = col4;
}
2024-02-16 01:37:08 +08:00
$container.append([col1, col2, col3]);
var sortTicket = function (c1, c2) {
return tickets[c2].time - tickets[c1].time;
};
2024-02-12 21:30:33 +08:00
const onShow = function (ticket, channel, data, done) {
2024-02-16 01:37:08 +08:00
APP.module.execCommand('LOAD_TICKET_ADMIN', {
channel: channel,
curvePublic: data.authorKey
}, function (obj) {
if (!Array.isArray(obj)) {
console.error(obj && obj.error);
done();
2024-02-16 01:37:08 +08:00
return void UI.warn(Messages.error);
}
2024-02-21 00:50:41 +08:00
var $ticket = $(ticket);
2024-02-16 01:37:08 +08:00
obj.forEach(function (msg) {
if (!data.notifications) {
data.notifications = Util.find(msg, ['sender', 'notifications']);
}
2024-02-21 00:50:41 +08:00
if (msg.close) {
$ticket.addClass('cp-support-list-closed');
return $ticket.append(APP.support.makeCloseMessage(msg));
}
$ticket.append(APP.support.makeMessage(msg));
2024-02-16 01:37:08 +08:00
});
if (!open.includes(channel)) { open.push(channel); }
done();
});
};
const onHide = function (ticket, channel, data, done) {
$(ticket).find('.cp-support-list-message').remove();
open = open.filter((chan) => {
return chan !== channel;
2024-02-16 01:37:08 +08:00
});
done();
2024-02-16 01:37:08 +08:00
};
const onReply = function (ticket, channel, data, form, cb) {
// XXX TODO
var formData = APP.support.getFormData(form);
APP.module.execCommand('REPLY_TICKET_ADMIN', {
channel: channel,
curvePublic: data.authorKey,
notifChannel: data.notifications,
2024-02-16 01:37:08 +08:00
ticket: formData
}, function (obj) {
if (obj && obj.error) {
console.error(obj && obj.error);
return void UI.warn(Messages.error);
}
$(ticket).find('.cp-support-list-message').remove();
$(ticket).find('.cp-support-form-container').remove();
2024-02-21 00:50:41 +08:00
refresh($container, type);
});
};
const onClose = function (ticket, channel, data) {
APP.module.execCommand('CLOSE_TICKET_ADMIN', {
channel: channel,
curvePublic: data.authorKey,
notifChannel: data.notifications,
ticket: APP.support.getDebuggingData({
close: true
})
}, function (obj) {
if (obj && obj.error) {
console.error(obj && obj.error);
return void UI.warn(Messages.error);
}
refreshAll();
2024-02-16 01:37:08 +08:00
});
};
2024-02-12 21:30:33 +08:00
2024-02-16 01:37:08 +08:00
Object.keys(tickets).sort(sortTicket).forEach(function (channel) {
var d = tickets[channel];
var ticket = APP.support.makeTicket({
id: channel,
content: d,
form: activeForms[channel],
onShow, onHide, onClose, onReply
});
2024-02-16 01:37:08 +08:00
var container;
if (d.lastAdmin) { container = col3; }
else if (d.premium) { container = col1; }
else { container = col2; }
$(container).append(ticket);
if (open.includes(channel)) { return void ticket.open(); }
if (linkedTicket === channel) {
linkedTicket = undefined;
ticket.open();
ticket.scrollIntoView();
}
2024-02-16 01:37:08 +08:00
});
open = [];
2024-02-21 00:50:41 +08:00
console.log(type, tickets);
2024-02-16 01:37:08 +08:00
});
};
let activeContainer, pendingContainer, closedContainer;
2024-02-21 00:50:41 +08:00
var refreshAll = function () {
console.error('refresh');
refresh($(activeContainer), 'active');
refresh($(pendingContainer), 'pending');
refresh($(closedContainer), 'closed');
2024-02-21 00:50:41 +08:00
};
// Make sidebar layout
const categories = {
'open': {
icon: undefined,
content: [
'privacy',
'active-list',
'pending-list',
]
},
'closed': {
icon: undefined,
content: [
'closed-list'
]
},
'refresh': {
icon: undefined,
action: refreshAll
}
};
sidebar.addCheckboxItem({
key: 'privacy',
getState: () => false,
query: (val, setState) => {
APP.support.setAnonymous(val);
setState(val);
}
});
sidebar.addItem('active-list', cb => {
let div = activeContainer = h('div.cp-support-container'); // XXX block
cb(div);
});
sidebar.addItem('pending-list', cb => {
let div = pendingContainer = h('div.cp-support-container'); // XXX block
cb(div);
});
sidebar.addItem('closed-list', cb => {
let div = closedContainer = h('div.cp-support-container'); // XXX block
cb(div);
}, { noTitle: true, noHint: true });
2024-02-21 00:50:41 +08:00
let _refresh = Util.throttle(refreshAll, 500);
events.NEW_TICKET.reg(_refresh);
2024-02-21 00:50:41 +08:00
events.UPDATE_TICKET.reg(_refresh);
refreshAll();
sidebar.makeLeftside(categories);
2024-02-12 21:30:33 +08:00
};
var createToolbar = function () {
var displayed = ['useradmin', 'newpad', 'limit', 'pageTitle', 'notifications'];
var configTb = {
displayed: displayed,
sfCommon: common,
$container: APP.$toolbar,
pageTitle: Messages.supportPage,
metadataMgr: common.getMetadataMgr(),
};
APP.toolbar = Toolbar.create(configTb);
APP.toolbar.$rightside.hide();
};
nThen(function (waitFor) {
$(waitFor(UI.addLoadingScreen));
SFCommon.create(waitFor(function (c) { APP.common = common = c; }));
}).nThen(function (waitFor) {
APP.$container = $('#cp-sidebarlayout-container');
2024-02-12 21:30:33 +08:00
APP.$toolbar = $('#cp-toolbar');
sframeChan = common.getSframeChannel();
sframeChan.onReady(waitFor());
2024-02-12 21:30:33 +08:00
}).nThen(function (/*waitFor*/) {
createToolbar();
var metadataMgr = common.getMetadataMgr();
var privateData = metadataMgr.getPrivateData();
common.setTabTitle(Messages.supportPage);
if (!common.isAdmin()) {
return void UI.errorLoadingScreen(Messages.admin_authError || '403 Forbidden');
}
APP.privateKey = privateData.supportPrivateKey;
APP.origin = privateData.origin;
APP.readOnly = privateData.readOnly;
APP.module = common.makeUniversal('support', {
onEvent: (obj) => {
let cmd = obj.ev;
let data = obj.data;
if (!events[cmd]) { return; }
events[cmd].fire(data);
}
});
2024-02-12 21:30:33 +08:00
APP.support = Support.create(common, true);
let active = privateData.category || 'active';
let linkedTicket;
if (active.indexOf('-') !== -1) {
linkedTicket = active.split('-')[1];
active = active.split('-')[0];
}
andThen(common, APP.$container, linkedTicket);
2024-02-12 21:30:33 +08:00
UI.removeLoadingScreen();
});
});