feat(admin): upgrade message management and broadcast interactions
Add message details, per-row actions, selection-aware bulk controls and confirmation dialogs. Merge filters into the list card and link overview statistics to the matching views with site-timezone today filtering. Improve the compose dialog with Unicode character counters, recipient mode segments, role counts and explicit broadcast confirmation verified against the resolved role and recipient count on submission. Split rendering into focused sibling traits and cover rendering, handlers and UI interactions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6195508481
commit
fe3ef82718
9 files changed
+1242
-422
No files matched your search
@@ -1,79 +1,20 @@
|
||||
/* 消息管理(users.php?page=aksrt_messages)——仅本页入队。
|
||||
* 页面外壳 / 概览 / 表单栅格 / 筛选条 / 空状态均走 native-ui.css 的共享类,
|
||||
* 本文件只保留本页专属样式:发送弹窗、收件人模式切换、类型徽章、读取状态、用户单元格、列宽。 */
|
||||
|
||||
/* 消息管理原生页。共享卡片 / 表单 / 筛选沿用 native-ui.css 的 --an-* 令牌。 */
|
||||
.aksrt-messages-admin [hidden] { display: none; }
|
||||
.aksrt-messages-admin__muted { color: var(--an-muted); }
|
||||
.aksrt-messages-admin__sub { margin-top: 3px; color: var(--an-muted); font-size: 12px; }
|
||||
.aksrt-messages-admin__sub code { padding: 0 4px; font-size: 12px; background: var(--an-bg-soft); }
|
||||
|
||||
/* ---- 页头按钮:图标与文字居中对齐(<a> 与 <button> 一致) ---- */
|
||||
.aksrt-messages-admin .aksrt-native-header__actions .button { display: inline-flex; align-items: center; gap: 4px; }
|
||||
.aksrt-messages-admin .aksrt-native-header__actions .button .dashicons { margin: 0; line-height: 1; vertical-align: middle; }
|
||||
.aksrt-messages-admin .aksrt-native-stat:focus-visible { outline: 2px solid var(--an-primary); outline-offset: 2px; }
|
||||
|
||||
/* ---- 发送系统消息弹窗 ---- */
|
||||
.aksrt-msg-dialog {
|
||||
width: min(640px, calc(100vw - 32px));
|
||||
max-height: calc(100vh - 64px);
|
||||
padding: 0;
|
||||
color: var(--an-text-2);
|
||||
background: var(--an-card);
|
||||
border: 0;
|
||||
border-radius: var(--an-radius);
|
||||
box-shadow: 0 12px 48px rgba(15, 23, 42, .18);
|
||||
}
|
||||
.aksrt-msg-dialog::backdrop { background: rgba(15, 23, 42, .45); }
|
||||
.aksrt-msg-dialog__form { display: flex; flex-direction: column; max-height: inherit; margin: 0; }
|
||||
.aksrt-msg-dialog__head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
padding: 16px 20px;
|
||||
border-bottom: 1px solid var(--an-border-soft);
|
||||
}
|
||||
.aksrt-msg-dialog .aksrt-msg-dialog__title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin: 0;
|
||||
color: var(--an-text);
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.aksrt-msg-dialog__title .dashicons { color: var(--an-primary); }
|
||||
.aksrt-msg-dialog__close {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
padding: 0;
|
||||
color: var(--an-muted);
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-radius: var(--an-radius-sm);
|
||||
cursor: pointer;
|
||||
}
|
||||
.aksrt-msg-dialog__close:hover,
|
||||
.aksrt-msg-dialog__close:focus-visible { color: var(--an-text); background: var(--an-bg-soft); }
|
||||
.aksrt-msg-dialog__body { padding: 18px 20px; overflow-y: auto; }
|
||||
.aksrt-msg-dialog__note { margin: 14px 0 0; font-size: 12px; }
|
||||
.aksrt-msg-dialog__foot {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
padding: 14px 20px;
|
||||
border-top: 1px solid var(--an-border-soft);
|
||||
}
|
||||
|
||||
/* ---- 代发:收件人模式切换(纯 CSS,按所选模式显隐字段) ---- */
|
||||
.aksrt-messages-admin__modes { display: flex; gap: 16px; margin: 0 0 12px; padding: 0; border: 0; }
|
||||
.aksrt-messages-admin__modes legend { float: left; margin-right: 8px; font-weight: 600; }
|
||||
.aksrt-messages-admin__compose:has(input[name="recipient_mode"][value="users"]:checked) .is-role,
|
||||
.aksrt-messages-admin__compose:has(input[name="recipient_mode"][value="role"]:checked) .is-users { display: none; }
|
||||
|
||||
/* ---- 列表 ---- */
|
||||
/* ---- 列表内的筛选与批量工具栏 ---- */
|
||||
.aksrt-messages-admin__toolbar { padding: 14px 20px; border-bottom: 1px solid var(--an-border-soft); }
|
||||
.aksrt-messages-admin__toolbar .subsubsub { margin: 0 0 12px; }
|
||||
.aksrt-messages-admin__toolbar .aksrt-native-filters { margin: 0; }
|
||||
.aksrt-messages-admin__bulk { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 12px 20px; }
|
||||
.aksrt-messages-admin__selection { margin-right: auto; color: var(--an-muted); font-size: 12px; font-variant-numeric: tabular-nums; }
|
||||
.aksrt-messages-admin .button:disabled,
|
||||
.aksrt-messages-admin .button:disabled:hover { color: var(--an-muted) !important; background: var(--an-bg-soft) !important; border-color: var(--an-border-soft) !important; cursor: not-allowed; }
|
||||
.aksrt-messages-admin__danger.button { color: var(--an-danger); border-color: var(--an-danger); }
|
||||
.aksrt-messages-admin__danger.button:hover,
|
||||
.aksrt-messages-admin__danger.button:focus { color: #fff; background: var(--an-danger); border-color: var(--an-danger); }
|
||||
@@ -84,12 +25,16 @@
|
||||
.aksrt-messages-admin__table .column-read { width: 8%; }
|
||||
.aksrt-messages-admin__table .column-time { width: 14%; }
|
||||
.aksrt-messages-admin__table td { vertical-align: middle; }
|
||||
.aksrt-messages-admin__table .row-title { word-break: break-word; }
|
||||
.aksrt-messages-admin__table .row-title { display: inline; padding: 0; font-weight: 600; text-align: left; word-break: break-word; line-height: 1.5; }
|
||||
.aksrt-messages-admin__table tr.is-unread .row-title { font-weight: 700; }
|
||||
.aksrt-messages-admin__table tr.is-unread > th:first-child { box-shadow: inset 3px 0 0 var(--an-primary); }
|
||||
.aksrt-messages-admin__table tr.is-selected > td,
|
||||
.aksrt-messages-admin__table tr.is-selected > th { background: var(--an-primary-soft); }
|
||||
.aksrt-messages-admin__desc { margin-top: 3px; color: var(--an-text-2); word-break: break-word; }
|
||||
.aksrt-msg-row-actions { display: flex; flex-wrap: wrap; gap: 6px 12px; margin-top: 8px; }
|
||||
.aksrt-msg-row-actions button { padding: 0; font-size: 12px; text-decoration: none; }
|
||||
|
||||
/* 类型徽章(可点击筛选,按类型着色) */
|
||||
/* 类型徽章(可点击筛选) */
|
||||
.aksrt-msg-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -109,19 +54,80 @@
|
||||
.aksrt-msg-badge.is-success { --aksrt-msg-tone: #00a32a; }
|
||||
.aksrt-msg-badge.is-danger { --aksrt-msg-tone: var(--an-danger); }
|
||||
.aksrt-msg-badge.is-social { --aksrt-msg-tone: #8c5bd0; }
|
||||
|
||||
/* 读取状态(带阅读时间 title 提示) */
|
||||
.aksrt-msg-state { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; white-space: nowrap; }
|
||||
.aksrt-msg-state::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
|
||||
.aksrt-msg-state.is-unread { color: var(--an-primary); font-weight: 600; }
|
||||
.aksrt-msg-state.is-read { color: var(--an-muted); }
|
||||
|
||||
/* 用户单元格(点击按该用户筛选) */
|
||||
.aksrt-msg-user { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; min-width: 0; text-decoration: none; }
|
||||
.aksrt-msg-user img { flex: none; border-radius: 50%; }
|
||||
.aksrt-msg-user span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
|
||||
/* ---- 发送 / 详情 / 二次确认共用弹窗 ---- */
|
||||
html.aksrt-msg-modal-open { overflow: hidden; }
|
||||
.aksrt-msg-dialog {
|
||||
width: min(640px, calc(100vw - 32px));
|
||||
max-height: calc(100vh - 64px);
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
color: var(--an-text-2);
|
||||
background: var(--an-card);
|
||||
border: 0;
|
||||
border-radius: var(--an-radius);
|
||||
box-shadow: 0 12px 48px rgba(15, 23, 42, .18);
|
||||
}
|
||||
.aksrt-msg-dialog::backdrop { background: rgba(15, 23, 42, .45); }
|
||||
.aksrt-msg-dialog--confirm { width: min(440px, calc(100vw - 32px)); }
|
||||
.aksrt-msg-dialog__frame { display: flex; flex-direction: column; max-height: inherit; margin: 0; }
|
||||
.aksrt-msg-dialog__head {
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
padding: 16px 20px;
|
||||
border-bottom: 1px solid var(--an-border-soft);
|
||||
}
|
||||
.aksrt-msg-dialog .aksrt-msg-dialog__title { display: flex; align-items: center; gap: 8px; margin: 0; color: var(--an-text); font-size: 16px; font-weight: 600; line-height: 1.4; }
|
||||
.aksrt-msg-dialog__title .dashicons { flex-shrink: 0; color: var(--an-primary); }
|
||||
.aksrt-msg-dialog__close { display: inline-flex; flex-shrink: 0; align-items: center; justify-content: center; width: 32px; height: 32px; padding: 0; color: var(--an-muted); background: transparent; border: 0; border-radius: var(--an-radius-sm); cursor: pointer; }
|
||||
.aksrt-msg-dialog__close:hover,
|
||||
.aksrt-msg-dialog__close:focus-visible { color: var(--an-text); background: var(--an-bg-soft); }
|
||||
.aksrt-msg-dialog__body { min-height: 0; padding: 18px 20px; overflow-y: auto; overscroll-behavior: contain; }
|
||||
.aksrt-msg-dialog__note { margin: 14px 0 0; font-size: 12px; }
|
||||
.aksrt-msg-dialog__foot { display: flex; flex-shrink: 0; justify-content: flex-end; gap: 8px; padding: 14px 20px; border-top: 1px solid var(--an-border-soft); }
|
||||
.aksrt-msg-dialog .aksrt-native-form-grid { grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); }
|
||||
.aksrt-msg-dialog--confirm .aksrt-msg-dialog__body p { margin: 0; line-height: 1.8; }
|
||||
|
||||
/* 分段单选:保留键盘语义,隐藏 WP 默认勾选标记。 */
|
||||
.aksrt-msg-modes { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; margin: 0 0 16px; padding: 0; border: 0; }
|
||||
.aksrt-msg-modes legend { margin-bottom: 8px; padding: 0; }
|
||||
.aksrt-msg-mode { position: relative; cursor: pointer; }
|
||||
.aksrt-msg-mode input[type="radio"] { position: absolute; width: 1px; height: 1px; min-width: 0; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); border: 0; opacity: 0; appearance: none; }
|
||||
.aksrt-msg-mode > span { display: flex; align-items: center; justify-content: center; gap: 6px; padding: 10px; color: var(--an-text-2); border: 1px solid var(--an-border); border-radius: var(--an-radius-sm); }
|
||||
.aksrt-msg-mode input:checked + span { color: var(--an-primary); background: var(--an-primary-soft); border-color: var(--an-primary); font-weight: 600; }
|
||||
.aksrt-msg-mode:hover > span { border-color: var(--an-primary); }
|
||||
.aksrt-msg-mode input:focus-visible + span { outline: 2px solid var(--an-primary); outline-offset: 2px; }
|
||||
.aksrt-msg-counter { align-self: flex-end; color: var(--an-muted); font-size: 12px; font-variant-numeric: tabular-nums; }
|
||||
.aksrt-msg-counter.is-over { color: var(--an-danger); font-weight: 600; }
|
||||
|
||||
/* 详情原样展示纯文本,保留换行,不插入消息中的 HTML。 */
|
||||
.aksrt-msg-detail__title { margin: 0 0 16px; color: var(--an-text); font-size: 17px; line-height: 1.5; overflow-wrap: anywhere; }
|
||||
.aksrt-msg-detail__meta { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin: 0; padding: 14px; background: var(--an-bg-soft); border-radius: var(--an-radius-sm); }
|
||||
.aksrt-msg-detail__meta dt { color: var(--an-muted); font-size: 12px; }
|
||||
.aksrt-msg-detail__meta dd { margin: 4px 0 0; overflow-wrap: anywhere; }
|
||||
.aksrt-msg-detail__content { line-height: 1.8; white-space: pre-wrap; overflow-wrap: anywhere; }
|
||||
.aksrt-msg-detail__link { display: block; margin-top: 16px; overflow-wrap: anywhere; }
|
||||
|
||||
@media (max-width: 782px) {
|
||||
.aksrt-messages-admin__toolbar,
|
||||
.aksrt-messages-admin__bulk { padding: 12px 14px; }
|
||||
.aksrt-messages-admin__table .column-type,
|
||||
.aksrt-messages-admin__table .column-read { display: none; }
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
.aksrt-msg-dialog { max-height: calc(100dvh - 32px); }
|
||||
.aksrt-msg-dialog__head,
|
||||
.aksrt-msg-dialog__body,
|
||||
.aksrt-msg-dialog__foot { padding-left: 14px; padding-right: 14px; }
|
||||
.aksrt-msg-detail__meta { grid-template-columns: 1fr; }
|
||||
}
|
||||
+219
-32
@@ -1,40 +1,227 @@
|
||||
/**
|
||||
* 消息管理后台页(users.php?page=aksrt_messages)的「发送系统消息」弹窗。
|
||||
* - 页头按钮 [data-aksrt-dialog-open] 打开对应 <dialog>;
|
||||
* - 关闭按钮 / 点击遮罩关闭;发送失败回跳时(data-aksrt-dialog-autoopen)自动打开;
|
||||
* - 提交后禁用发送按钮防重复提交。
|
||||
* 标记由 src/Admin/Native/UsersMenusMessages.php 与 NativeUi::button_dialog() 输出。
|
||||
*/
|
||||
/** 消息管理:详情、选择与批量操作、发送计数及角色群发确认。仅本页入队。 */
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
document.querySelectorAll('[data-aksrt-dialog-open]').forEach(function (button) {
|
||||
var dialog = document.getElementById(button.getAttribute('data-aksrt-dialog-open'));
|
||||
if (!dialog || typeof dialog.showModal !== 'function') {
|
||||
button.hidden = true;
|
||||
var root = document.querySelector('.aksrt-messages-admin');
|
||||
if (!root) return;
|
||||
var compose = document.getElementById('aksrt-msg-compose');
|
||||
var detail = document.getElementById('aksrt-msg-detail');
|
||||
var confirmDialog = document.getElementById('aksrt-msg-confirm');
|
||||
if (!compose || !detail || !confirmDialog || typeof compose.showModal !== 'function') return;
|
||||
|
||||
function text(element, key, values) {
|
||||
var value = element.getAttribute('data-i18n-' + key) || '';
|
||||
return value.replace(/\{(\w+)\}/g, function (match, name) {
|
||||
return values && values[name] !== undefined ? String(values[name]) : match;
|
||||
});
|
||||
}
|
||||
|
||||
function syncScroll() {
|
||||
document.documentElement.classList.toggle('aksrt-msg-modal-open', !!root.querySelector('dialog[open]'));
|
||||
}
|
||||
|
||||
function open(dialog) {
|
||||
if (!dialog.open) dialog.showModal();
|
||||
syncScroll();
|
||||
}
|
||||
|
||||
root.querySelectorAll('.aksrt-msg-dialog').forEach(function (dialog) {
|
||||
var outsideStart = false;
|
||||
function outside(event) {
|
||||
var rect = dialog.getBoundingClientRect();
|
||||
return event.clientX < rect.left || event.clientX > rect.right || event.clientY < rect.top || event.clientY > rect.bottom;
|
||||
}
|
||||
dialog.querySelectorAll('[data-aksrt-dialog-close]').forEach(function (button) {
|
||||
button.addEventListener('click', function () { dialog.close(); });
|
||||
});
|
||||
dialog.addEventListener('pointerdown', function (event) {
|
||||
outsideStart = event.target === dialog && outside(event);
|
||||
});
|
||||
dialog.addEventListener('click', function (event) {
|
||||
if (outsideStart && event.target === dialog && outside(event)) dialog.close();
|
||||
outsideStart = false;
|
||||
});
|
||||
dialog.addEventListener('close', syncScroll);
|
||||
});
|
||||
|
||||
var pending = null;
|
||||
var confirmButton = confirmDialog.querySelector('[data-aksrt-msg-confirm]');
|
||||
function ask(title, message, label, danger, callback) {
|
||||
pending = callback;
|
||||
confirmDialog.querySelector('[data-aksrt-dialog-title]').textContent = title;
|
||||
confirmDialog.querySelector('#aksrt-msg-confirm-text').textContent = message;
|
||||
confirmButton.textContent = label;
|
||||
confirmButton.classList.toggle('aksrt-messages-admin__danger', danger);
|
||||
confirmButton.classList.toggle('button-primary', !danger);
|
||||
open(confirmDialog);
|
||||
confirmDialog.querySelector('[data-aksrt-dialog-close][autofocus]').focus();
|
||||
}
|
||||
confirmDialog.addEventListener('cancel', function () { pending = null; });
|
||||
confirmDialog.addEventListener('close', function () { pending = null; });
|
||||
confirmButton.addEventListener('click', function () {
|
||||
var callback = pending;
|
||||
pending = null;
|
||||
confirmDialog.close();
|
||||
if (callback) callback();
|
||||
});
|
||||
|
||||
root.querySelectorAll('[data-aksrt-msg-view]').forEach(function (button) {
|
||||
button.addEventListener('click', function () {
|
||||
var template = document.getElementById('aksrt-msg-detail-' + button.getAttribute('data-aksrt-msg-view'));
|
||||
if (!template) return;
|
||||
detail.querySelector('[data-aksrt-msg-detail-body]').replaceChildren(template.content.cloneNode(true));
|
||||
open(detail);
|
||||
});
|
||||
});
|
||||
|
||||
var list = root.querySelector('[data-aksrt-msg-list]');
|
||||
var listSubmitting = false;
|
||||
var syncSelection;
|
||||
if (list) {
|
||||
var checks = Array.from(list.querySelectorAll('[data-aksrt-msg-check]'));
|
||||
var checkAll = list.querySelector('[data-aksrt-msg-check-all]');
|
||||
var selection = list.querySelector('[data-aksrt-msg-selection]');
|
||||
var bulkButtons = list.querySelectorAll('[data-aksrt-msg-action]:not([data-id])');
|
||||
|
||||
function selected() { return checks.filter(function (check) { return check.checked; }); }
|
||||
syncSelection = function () {
|
||||
var count = selected().length;
|
||||
selection.textContent = selection.getAttribute('data-label').replace('%d', String(count));
|
||||
checkAll.checked = count > 0 && count === checks.length;
|
||||
checkAll.indeterminate = count > 0 && count < checks.length;
|
||||
checkAll.disabled = listSubmitting || checks.length === 0;
|
||||
bulkButtons.forEach(function (button) { button.disabled = listSubmitting || count === 0; });
|
||||
checks.forEach(function (check) { check.closest('tr').classList.toggle('is-selected', check.checked); });
|
||||
};
|
||||
checkAll.addEventListener('change', function () {
|
||||
checks.forEach(function (check) { check.checked = checkAll.checked; });
|
||||
syncSelection();
|
||||
});
|
||||
checks.forEach(function (check) { check.addEventListener('change', syncSelection); });
|
||||
function mutate(op, id) {
|
||||
if (listSubmitting) return;
|
||||
list.elements.bulk_action.value = op;
|
||||
list.elements.message_id.value = id || '';
|
||||
list.requestSubmit();
|
||||
}
|
||||
list.querySelectorAll('[data-aksrt-msg-action]').forEach(function (button) {
|
||||
button.addEventListener('click', function () {
|
||||
if (listSubmitting) return;
|
||||
var op = button.getAttribute('data-aksrt-msg-action');
|
||||
var id = button.getAttribute('data-id');
|
||||
var count = id ? 1 : selected().length;
|
||||
if (!count) return;
|
||||
if (op === 'delete') {
|
||||
ask(text(confirmDialog, 'delete-title'), text(confirmDialog, 'delete-text', { count: count }), text(confirmDialog, 'delete-send'), true, function () { mutate(op, id); });
|
||||
} else {
|
||||
mutate(op, id);
|
||||
}
|
||||
});
|
||||
});
|
||||
list.addEventListener('submit', function (event) {
|
||||
if (listSubmitting || !list.elements.bulk_action.value || (!list.elements.message_id.value && !selected().length)) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
listSubmitting = true;
|
||||
// 只锁操作按钮,不禁用复选框,否则 ids[] 不会随表单提交。
|
||||
list.querySelectorAll('button').forEach(function (button) { button.disabled = true; });
|
||||
syncSelection();
|
||||
});
|
||||
syncSelection();
|
||||
}
|
||||
|
||||
var form = compose.querySelector('[data-aksrt-msg-compose]');
|
||||
var send = form.querySelector('[data-aksrt-msg-send]');
|
||||
var role = form.elements.role;
|
||||
var counters = form.querySelectorAll('[data-count-limit]');
|
||||
var sending = false;
|
||||
var approved = '';
|
||||
|
||||
function clearApproval() {
|
||||
approved = '';
|
||||
form.elements.confirmed_role.value = '';
|
||||
form.elements.confirmed_count.value = '';
|
||||
}
|
||||
function syncCounters() {
|
||||
counters.forEach(function (field) {
|
||||
// 与 PHP mb_strlen 一致按 Unicode 码点计数,emoji 不占两个字。
|
||||
var count = Array.from(field.value).length;
|
||||
var limit = Number(field.getAttribute('data-count-limit'));
|
||||
var counter = form.querySelector('[data-count-for="' + field.name + '"]');
|
||||
counter.textContent = count + ' / ' + limit;
|
||||
counter.classList.toggle('is-over', count > limit);
|
||||
field.setCustomValidity(count > limit ? text(form, 'count-error', { count: limit }) : '');
|
||||
});
|
||||
}
|
||||
function syncRole() {
|
||||
var option = role.options[role.selectedIndex];
|
||||
var count = option ? Number(option.getAttribute('data-count')) : 0;
|
||||
form.querySelector('[data-aksrt-msg-role-hint]').textContent = count > 0 && !option.disabled ? text(form, 'role-hint', { count: count }) : '';
|
||||
}
|
||||
function mode() { return form.querySelector('input[name="recipient_mode"]:checked').value; }
|
||||
function syncMode() {
|
||||
clearApproval();
|
||||
form.querySelectorAll('[data-aksrt-msg-pane]').forEach(function (pane) {
|
||||
var active = pane.getAttribute('data-aksrt-msg-pane') === mode();
|
||||
pane.hidden = !active;
|
||||
pane.querySelectorAll('input, select, textarea').forEach(function (field) { field.disabled = !active; });
|
||||
});
|
||||
syncRole();
|
||||
}
|
||||
form.querySelectorAll('input[name="recipient_mode"]').forEach(function (radio) { radio.addEventListener('change', syncMode); });
|
||||
role.addEventListener('change', function () { clearApproval(); syncRole(); });
|
||||
form.addEventListener('input', function () { clearApproval(); syncCounters(); });
|
||||
|
||||
function snapshot() {
|
||||
return JSON.stringify([role.value, role.options[role.selectedIndex].getAttribute('data-count'), form.elements.title.value, form.elements.content.value, form.elements.target_url.value]);
|
||||
}
|
||||
form.addEventListener('submit', function (event) {
|
||||
syncCounters();
|
||||
if (sending || !form.reportValidity()) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
var form = dialog.querySelector('form');
|
||||
var submit = dialog.querySelector('[data-aksrt-dialog-submit]');
|
||||
|
||||
function open() {
|
||||
if (submit) submit.disabled = false;
|
||||
dialog.showModal();
|
||||
var first = dialog.querySelector('textarea:not([disabled]), input:not([type="hidden"]):not([type="radio"])');
|
||||
if (first) first.focus();
|
||||
if (mode() === 'role' && approved !== snapshot()) {
|
||||
event.preventDefault();
|
||||
var option = role.options[role.selectedIndex];
|
||||
if (!option || option.disabled || !role.value) return;
|
||||
var count = Number(option.getAttribute('data-count'));
|
||||
var current = snapshot();
|
||||
ask(text(form, 'role-title'), text(form, 'role-confirm', { role: option.getAttribute('data-label'), count: count }), text(form, 'role-send'), false, function () {
|
||||
if (mode() !== 'role' || current !== snapshot()) return;
|
||||
approved = current;
|
||||
form.elements.confirmed_role.value = role.value;
|
||||
form.elements.confirmed_count.value = String(count);
|
||||
form.requestSubmit(send);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
button.addEventListener('click', open);
|
||||
dialog.querySelectorAll('[data-aksrt-dialog-close]').forEach(function (close) {
|
||||
close.addEventListener('click', function () { dialog.close(); });
|
||||
});
|
||||
// 点击遮罩(dialog 自身而非内容区)关闭。
|
||||
dialog.addEventListener('click', function (event) {
|
||||
if (event.target === dialog) dialog.close();
|
||||
});
|
||||
if (form && submit) {
|
||||
form.addEventListener('submit', function () { submit.disabled = true; });
|
||||
}
|
||||
if (dialog.hasAttribute('data-aksrt-dialog-autoopen')) open();
|
||||
sending = true;
|
||||
send.disabled = true;
|
||||
});
|
||||
|
||||
root.querySelectorAll('[data-aksrt-dialog-open]').forEach(function (button) {
|
||||
button.addEventListener('click', function () {
|
||||
open(compose);
|
||||
var field = mode() === 'role' ? role : form.elements.users;
|
||||
field.focus();
|
||||
});
|
||||
});
|
||||
window.addEventListener('pageshow', function () {
|
||||
sending = false;
|
||||
send.disabled = false;
|
||||
clearApproval();
|
||||
if (list) {
|
||||
listSubmitting = false;
|
||||
list.elements.bulk_action.value = '';
|
||||
list.elements.message_id.value = '';
|
||||
list.querySelectorAll('button[data-id], button[data-aksrt-msg-view]').forEach(function (button) { button.disabled = false; });
|
||||
syncSelection();
|
||||
}
|
||||
syncCounters();
|
||||
});
|
||||
syncMode();
|
||||
syncCounters();
|
||||
if (compose.hasAttribute('data-aksrt-dialog-autoopen')) open(compose);
|
||||
})();
|
||||
Reference in new issue
Block a user