Files
MC_Report/public/js/pages/notifications.js

73 lines
6.0 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const NotificationsPage = {
async render() { return '<div class="loading"><i class="fas fa-spinner"></i></div>'; },
async mount() {
document.getElementById('page-title').textContent = '通知é…<C3A9>ç½®';
document.getElementById('page-actions').innerHTML = '<button class="btn btn-p btn-sm" onclick="NotificationsPage.showCreate()"><i class="fas fa-plus"></i> 添加Webhook</button>';
await this.load();
},
async load() {
const ct = document.getElementById('page-content');
try {
const cfgs = await API.get('/notifications');
ct.innerHTML = cfgs.length ? cfgs.map(c => `
<div class="card"><div class="card-h"><span><i class="fas fa-${c.type==='webhook'?'link':'envelope'}"></i> ${U.esc(c.name)}</span><span>${c.active?`<span class="badge bg-resolved">å<>¯ç”¨</span>`:`<span class="badge bg-rejected">ç¦<C3A7>用</span>`}</span></div><div class="card-b">
<div class="detail-row"><span class="lbl">类型</span><span class="val">${c.type==='webhook'?'Webhook':'邮件'}</span></div>
${c.webhook_url?`<div class="detail-row"><span class="lbl">地å<C2B0>€</span><span class="val ts" style="word-break:break-all">${U.esc(c.webhook_url)}</span></div>`:''}
<div class="detail-row"><span class="lbl">事件</span><span class="val">${EventsLabel(c.events)}</span></div>
<div class="mt-2 flex g2">
<button class="btn btn-o btn-sm" onclick="NotificationsPage.showEdit(${c.id},'${U.escJs(c.name)}','${c.type}','${U.escJs(c.webhook_url)}','${U.escJs(c.events)}',${c.active})"><i class="fas fa-edit"></i> 编辑</button>
<button class="btn btn-i btn-sm" onclick="NotificationsPage.test(${c.id})"><i class="fas fa-paper-plane"></i> 测试</button>
<button class="btn btn-d btn-sm" onclick="NotificationsPage.del(${c.id})"><i class="fas fa-trash"></i> 删除</button>
</div>
</div></div>
`).join('') : '<div class="empty"><i class="fas fa-bell-slash"></i><p>æšæ— é€šçŸ¥é…<C3A9>ç½®</p><p class="ts tm">添加Webhookå<6B>Žå<C5BD>¯è‡ªåŠ¨æŽ¨é€<C3A9>å·¥å<C2A5>•状æ€<C3A6>å<EFBFBD>˜æ´é€šçŸ¥</p></div>';
} catch (e) { ct.innerHTML = `<div class="alert alert-e">${e.message}</div>`; }
},
showCreate() {
U.modal('添加Webhook', `
<form id="nc-form"><div class="form-group"><label>å<><C3A5>ç§° *</label><input id="nc-name" placeholder="å¦? Discord通知" required></div>
<div class="form-group"><label>类型 *</label><select id="nc-type"><option value="webhook">Webhook</option></select></div>
<div class="form-group"><label>Webhook URL *</label><input id="nc-url" placeholder="https://discord.com/api/webhooks/..." required></div>
<div class="form-group"><label>触å<C2A6>äºä»¶</label>
<div style="display:flex;flex-wrap:wrap;gap:8px;margin-top:4px">${EventOptions('all')}</div>
<input type="hidden" id="nc-events" value="all">
</div>
<div class="modal-f"><button type="button" class="btn btn-o" data-action="App:closeModal">å<>消</button><button type="submit" class="btn btn-p">创建</button></div></form>
`);
bindEventToggles();
document.getElementById('nc-form').onsubmit = async e => { e.preventDefault();
try { await API.post('/notifications',{name:document.getElementById('nc-name').value,type:'webhook',webhook_url:document.getElementById('nc-url').value,events:document.getElementById('nc-events').value}); App.closeModal(); this.load(); } catch(ex){alert(ex.message);}
};
},
showEdit(id,name,type,url,events,active) {
U.modal('编辑通知', `
<form id="ne-form"><div class="form-group"><label>å<><C3A5>ç§°</label><input id="ne-name" value="${U.esc(name).replace(/"/g,'&quot;')}"></div>
<div class="form-group"><label>Webhook URL</label><input id="ne-url" value="${U.esc(url).replace(/"/g,'&quot;')}"></div>
<div class="form-group"><label>触å<C2A6>äºä»¶</label>
<div style="display:flex;flex-wrap:wrap;gap:8px;margin-top:4px">${EventOptions(events)}</div>
<input type="hidden" id="ne-events" value="${events}">
</div>
<div class="form-group"><label>状æ€?/label><select id="ne-active"><option value="1" ${active?'selected':''}<>¯ç”¨</option><option value="0" ${!active?'selected':''}>ç¦<C3A7>用</option></select></div>
<div class="modal-f"><button type="button" class="btn btn-o" data-action="App:closeModal">å<>消</button><button type="submit" class="btn btn-p">ä¿<C3A4>å­˜</button></div></form>
`);
bindEventToggles();
document.getElementById('ne-form').onsubmit = async e => { e.preventDefault();
try { await API.put(`/notifications/${id}`,{name:document.getElementById('ne-name').value,webhook_url:document.getElementById('ne-url').value,events:document.getElementById('ne-events').value,active:document.getElementById('ne-active').value==='1'}); App.closeModal(); this.load(); } catch(ex){alert(ex.message);}
};
},
async test(id) { try { alert((await API.post(`/notifications/${id}/test`)).message); } catch(ex){alert(ex.message);} },
async del(id) { if(await U.confirm('确认删除此通知é…<C3A9>ç½®ï¼?)){ try { await API.req('DELETE',`/notifications/${id}`); this.load(); } catch(ex){alert(ex.message);} } }
};
function EventOptions(current) { return ['all','ticket_created','ticket_claimed','ticket_transferred','ticket_updated'].map(e=>`<label style="cursor:pointer;font-size:12px"><input type="checkbox" value="${e}" class="ev-check" ${current.split(',').map(s=>s.trim()).includes(e)?'checked':''}> ${EventsLabelSingle(e)}</label>`).join(''); }
function EventsLabel(v) { return v==='all'?'å¨éƒ¨äºä»':v.split(',').map(s=>s.trim()).map(EventsLabelSingle).join(', '); }
function EventsLabelSingle(e) { return {all:'å¨éƒ¨',ticket_created:'å·¥å<EFBFBD>åˆå»º',ticket_claimed:'å·¥å<EFBFBD>认é¢',ticket_transferred:'å·¥å<EFBFBD>转交',ticket_updated:'å·¥å<EFBFBD>æ´æ°'}[e]||e; }
function bindEventToggles() {
document.querySelectorAll('.ev-check').forEach(cb=>{ cb.onchange=()=>{ const all=document.querySelectorAll('.ev-check'); const v=Array.from(all).filter(c=>c.checked).map(c=>c.value).join(','); const hid=cb.closest('form').querySelector('input[type="hidden"]'); if(hid)hid.value=v; }; });
}