fix(admin): move message row actions into a rightmost column

Add a dedicated operations column for viewing, marking read and deleting
messages. Keep the message cell focused on its title, excerpt and ID;
adjust column widths and empty-state colspan with regression coverage.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
kate522andClaude Fable 5 committed 2026-10-30 17:45:52 +08:00
1 parent 1902ba1e87
commit 479b324f95
3 files changed
+36 -18

No files matched your search

@@ -80,6 +80,24 @@ test('list toolbar is merged into the table card and inline confirmation is remo
assert.match(empty, /当前筛选条件下没有消息/);
});
test('message row actions live only in a dedicated rightmost operations column', () => {
const { table, empty } = harness();
assert.match(table, /<th scope="col" class="column-time">发送时间<\/th><th scope="col" class="column-actions">操作<\/th><\/tr>/);
const rows = [...table.matchAll(/<tr class="is-(?:unread|read)">([\s\S]*?)<\/tr>/g)];
assert.equal(rows.length, 2);
rows.forEach(([, row]) => {
const cells = [...row.matchAll(/<(?:th|td)\b[^>]*>[\s\S]*?<\/(?:th|td)>/g)].map(([cell]) => cell);
assert.equal(cells.length, 7);
assert.match(cells[1], /class="column-title"/);
assert.doesNotMatch(cells[1], /<button|data-aksrt-msg-view|data-aksrt-msg-action/);
assert.match(cells[5], /class="column-time"/);
assert.match(cells[6], /class="column-actions"/);
assert.match(cells[6], /data-aksrt-msg-view=/);
assert.match(cells[6], /data-aksrt-msg-action="delete"/);
});
assert.match(empty, /colspan="7"/);
});
test('details preserve full content, escape HTML and unsafe links, and never mark read', () => {
const { table, cache_calls } = harness();
assert.match(table, /<template id="aksrt-msg-detail-8">/);