feat(ticket): redesign native ticket admin page UI/UX
- Fix empty status/department selects in the detail panel (printf leak) - Replace dead 代客提交 button with a working collapsible create form - Error-aware notices; redirect keeps filters and the open ticket - Status views with counts, incl. 未关闭 default and 已关闭 view - Two-column detail: conversation + attachments + prereplies | info, status/department/assignee select, internal notes; closed = read-only - Split detail panel into UsersMenusTicketsDetail trait; page-scoped tickets.css / admin-tickets.js replace inline styles - AdminListPagination accepts parent file so users.php keeps menu highlight - Drop native loading="lazy" per lazyload contract Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b927b9ec7c
commit
b74381cfa2
9 files changed
+885
-278
No files matched your search
@@ -42,16 +42,21 @@ test('write actions are nonce-protected and dispatched by action name', () => {
|
||||
assert.ok(center.includes(`case '${action}':`), `dispatch case ${action} missing`);
|
||||
}
|
||||
|
||||
// nonce 以 action + id 为单位,行内表单各自带自己的 nonce(渲染在 List trait 中)。
|
||||
// nonce 以 action + id 为单位,行内表单各自带自己的 nonce:
|
||||
// 代客提交在 List trait,回复 / 状态 / 备注在 Detail trait。
|
||||
// 删除类操作已迁至 SPA(n-dialog 二次确认),本页不再有 onsubmit=confirm 的小表单。
|
||||
const list = read('src/Admin/Native/UsersMenusTicketsList.php');
|
||||
const detail = read('src/Admin/Native/UsersMenusTicketsDetail.php');
|
||||
assert.ok(list.includes("wp_nonce_field('aksrt_ticket_create_0')"), 'create nonce missing');
|
||||
for (const hook of [
|
||||
'aksrt_ticket_reply_',
|
||||
'aksrt_ticket_status_',
|
||||
'aksrt_ticket_note_',
|
||||
]) {
|
||||
assert.ok(list.includes(hook), `nonce prefix ${hook} missing`);
|
||||
assert.ok(detail.includes(hook), `nonce prefix ${hook} missing`);
|
||||
}
|
||||
assert.ok(center.includes('use UsersMenusTicketsDetail;'), 'detail trait not composed');
|
||||
assert.ok(!detail.includes('ticket_tab'), 'ticket_tab hidden input must be gone');
|
||||
// Tab 已移除,三个行内表单不再输出 ticket_tab 隐藏域。
|
||||
assert.ok(!list.includes('ticket_tab'), 'ticket_tab hidden input must be gone');
|
||||
assert.ok(!center.includes('onsubmit="return confirm('), 'config delete forms must be gone');
|
||||
@@ -97,8 +102,11 @@ test('the ticket list paginates through the shared helper', () => {
|
||||
});
|
||||
|
||||
test('detail panel renders replies, quote blocks and internal notes', () => {
|
||||
const list = read('src/Admin/Native/UsersMenusTicketsList.php');
|
||||
const body = list.slice(list.indexOf('private function render_ticket_detail_panel'));
|
||||
const detail = read('src/Admin/Native/UsersMenusTicketsDetail.php');
|
||||
const body = detail.slice(detail.indexOf('private function render_ticket_detail_panel'));
|
||||
assert.ok(detail.includes('private function render_ticket_detail_panel'), 'detail renderer missing');
|
||||
// 选项必须拼进返回值而不是直接 echo(历史 bug:printf 导致下拉框为空)。
|
||||
assert.ok(!/\bprintf\(/.test(detail), 'detail panel must not echo via printf');
|
||||
|
||||
assert.match(body, /TicketNoteService::for_ticket/);
|
||||
assert.match(body, /repo->replies\(\$id\)/);
|
||||
|
||||
Reference in new issue
Block a user