fix(admin): remove duplicate ticket dialog subtitle
Keep the ticket number and status in the sidebar only, remove the unused header description payload and bindings, and update dialog regression coverage. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
264015b7e9
commit
7f1a0dbeb4
5 files changed
+15
-18
No files matched your search
@@ -12,9 +12,7 @@
|
||||
var panel = detailDialog.querySelector('[data-aksrt-ticket-panel]');
|
||||
var list = root.querySelector('[data-aksrt-ticket-list]');
|
||||
var detailTitle = document.getElementById('aksrt-ticket-detail-title');
|
||||
var detailDescription = document.getElementById('aksrt-ticket-detail-description');
|
||||
var initialTitle = detailTitle.textContent;
|
||||
var initialDescription = detailDescription.textContent;
|
||||
var baselines = new WeakMap();
|
||||
var active = null;
|
||||
var opener = null;
|
||||
@@ -179,7 +177,6 @@
|
||||
if (current !== generation || active !== detailDialog) return;
|
||||
panel.innerHTML = data.panel;
|
||||
detailTitle.textContent = data.title;
|
||||
detailDescription.textContent = data.description;
|
||||
if (typeof data.list === 'string') list.innerHTML = data.list;
|
||||
updateUrl(id, data.page);
|
||||
setupForms(panel, restore);
|
||||
@@ -225,7 +222,6 @@
|
||||
function openDetail(id, source, refresh, message) {
|
||||
ticketId = id;
|
||||
detailTitle.textContent = initialTitle;
|
||||
detailDescription.textContent = initialDescription;
|
||||
show(detailDialog, source);
|
||||
updateUrl(id);
|
||||
return loadDetail(id, !!refresh, message || '', {});
|
||||
|
||||
@@ -107,7 +107,6 @@ trait UsersMenusTicketsCenter {
|
||||
}
|
||||
$data['panel'] = $this->render_ticket_detail_panel($ticket);
|
||||
$data['title'] = (string) $ticket['title'];
|
||||
$data['description'] = (string) $ticket['ticket_num'] . ' / ' . (string) $ticket['status_label'];
|
||||
}
|
||||
if ($refresh_list) {
|
||||
ob_start();
|
||||
|
||||
@@ -41,15 +41,15 @@ trait UsersMenusTicketsDialogs {
|
||||
}
|
||||
echo '</footer>' . ($types === [] ? '</div>' : '</form>') . '</dialog>';
|
||||
|
||||
echo '<dialog id="aksrt-ticket-detail-dialog" class="aksrt-ticket-dialog aksrt-ticket-dialog--detail" aria-labelledby="aksrt-ticket-detail-title" aria-describedby="aksrt-ticket-detail-description"><div class="aksrt-ticket-dialog__frame">';
|
||||
echo $this->ticket_dialog_header('detail', __('工单详情', 'aksrt'), __('查看沟通记录并处理工单。', 'aksrt')); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
echo '<dialog id="aksrt-ticket-detail-dialog" class="aksrt-ticket-dialog aksrt-ticket-dialog--detail" aria-labelledby="aksrt-ticket-detail-title"><div class="aksrt-ticket-dialog__frame">';
|
||||
echo $this->ticket_dialog_header('detail', __('工单详情', 'aksrt')); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
echo $this->ticket_dialog_feedback(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
echo '<div class="aksrt-ticket-dialog__body" data-aksrt-ticket-panel></div></div></dialog>';
|
||||
}
|
||||
|
||||
private function ticket_dialog_header(string $key, string $title, string $description): string {
|
||||
private function ticket_dialog_header(string $key, string $title, string $description = ''): string {
|
||||
return '<header class="aksrt-ticket-dialog__head"><div><h2 id="aksrt-ticket-' . esc_attr($key) . '-title" tabindex="-1" autofocus>' . esc_html($title) . '</h2>'
|
||||
. '<p id="aksrt-ticket-' . esc_attr($key) . '-description">' . esc_html($description) . '</p></div>'
|
||||
. ($description !== '' ? '<p id="aksrt-ticket-' . esc_attr($key) . '-description">' . esc_html($description) . '</p>' : '') . '</div>'
|
||||
. '<button type="button" class="aksrt-ticket-dialog__close" data-aksrt-dialog-close aria-label="' . esc_attr__('关闭弹窗', 'aksrt') . '"><span class="dashicons dashicons-no-alt" aria-hidden="true"></span></button></header>';
|
||||
}
|
||||
|
||||
|
||||
@@ -269,8 +269,6 @@ function makeRuntime({ href = 'https://site.test/wp-admin/users.php?page=aksrt_t
|
||||
const detailFrame = el('div', {}, detailDialog);
|
||||
const detailTitle = el('h2', { id: 'aksrt-ticket-detail-title', autofocus: '' }, detailFrame);
|
||||
detailTitle.textContent = 'Ticket detail';
|
||||
const detailDescription = el('p', { id: 'aksrt-ticket-detail-description' }, detailFrame);
|
||||
detailDescription.textContent = 'View the conversation';
|
||||
feedbackBox(detailDialog);
|
||||
const panel = el('div', { 'data-aksrt-ticket-panel': '' }, detailFrame);
|
||||
panel.isPanel = true;
|
||||
@@ -362,7 +360,7 @@ function makeRuntime({ href = 'https://site.test/wp-admin/users.php?page=aksrt_t
|
||||
document, window, fetch, URL, AbortController, setTimeout, clearTimeout,
|
||||
}, { filename: scriptPath });
|
||||
|
||||
return { document, window, root, list, createDialog, detailDialog, createForm, createOpener, detailTitle, detailDescription, panel, viewsById, fetchCalls };
|
||||
return { document, window, root, list, createDialog, detailDialog, createForm, createOpener, detailTitle, panel, viewsById, fetchCalls };
|
||||
}
|
||||
|
||||
function response(data, status = 200) {
|
||||
@@ -396,7 +394,7 @@ function loadDetail(runtime, id = 41, status = 'pending') {
|
||||
assert.ok(opener, `missing opener for ${id}`);
|
||||
runtime.root.fire('click', { target: opener });
|
||||
assert.equal(runtime.fetchCalls.length, 1);
|
||||
resolveFetch(runtime, 0, { success: true, data: { panel: `ticket:${id}:${status}`, title: `Ticket ${id}`, description: `#${id}`, page: 1 } });
|
||||
resolveFetch(runtime, 0, { success: true, data: { panel: `ticket:${id}:${status}`, title: `Ticket ${id}`, page: 1 } });
|
||||
return tick();
|
||||
}
|
||||
|
||||
@@ -444,7 +442,7 @@ test('detail load ignores a response that arrives after cancellation', async ()
|
||||
assert.equal(runtime.detailDialog.open, false);
|
||||
assert.equal(pending.options.signal.aborted, true);
|
||||
|
||||
resolveFetch(runtime, 0, { success: true, data: { panel: 'ticket:41', title: 'Late title', description: 'Late', page: 1 } });
|
||||
resolveFetch(runtime, 0, { success: true, data: { panel: 'ticket:41', title: 'Late title', page: 1 } });
|
||||
await tick();
|
||||
assert.equal(runtime.panel.querySelector('[data-aksrt-ticket-form]'), null);
|
||||
assert.equal(runtime.detailTitle.textContent, 'Ticket detail');
|
||||
@@ -467,7 +465,7 @@ test('deep link loads an ID even when it is absent from the current list', async
|
||||
assert.equal(read.searchParams.get('ticket_type_id'), '6');
|
||||
assert.equal(read.searchParams.get('s'), 'network');
|
||||
assert.equal(read.searchParams.get('paged'), '3');
|
||||
resolveFetch(runtime, 0, { success: true, data: { panel: 'ticket:987', title: 'Ticket 987', description: '#987', page: 3 } });
|
||||
resolveFetch(runtime, 0, { success: true, data: { panel: 'ticket:987', title: 'Ticket 987', page: 3 } });
|
||||
await tick();
|
||||
assert.equal(runtime.panel.querySelector('[data-aksrt-ticket-detail="987"]') !== null, true);
|
||||
});
|
||||
@@ -510,7 +508,7 @@ test('successful create waits for its asynchronous close event before opening th
|
||||
assert.equal(runtime.fetchCalls.length, 2);
|
||||
assert.equal(runtime.detailDialog.open, true);
|
||||
assert.equal(runtime.document.documentElement.classList.contains('aksrt-ticket-modal-open'), true);
|
||||
resolveFetch(runtime, 1, { success: true, data: { panel: 'ticket:303', title: 'New issue', description: '#303', list: 'updated rows', page: 1 } });
|
||||
resolveFetch(runtime, 1, { success: true, data: { panel: 'ticket:303', title: 'New issue', list: 'updated rows', page: 1 } });
|
||||
await tick();
|
||||
assert.equal(runtime.panel.querySelector('[data-aksrt-ticket-detail="303"]') !== null, true);
|
||||
assert.equal(runtime.list.innerHTML, 'updated rows');
|
||||
@@ -546,7 +544,7 @@ test('reply, status, and note saves refresh detail and list while restoring othe
|
||||
const statusAfterSave = kind === 'status' ? 'handling' : 'pending';
|
||||
resolveFetch(runtime, 2, {
|
||||
success: true,
|
||||
data: { panel: `ticket:41:${statusAfterSave}`, title: 'Ticket 41', description: '#41', list: `rows-after-${kind}`, page: 1 },
|
||||
data: { panel: `ticket:41:${statusAfterSave}`, title: 'Ticket 41', list: `rows-after-${kind}`, page: 1 },
|
||||
});
|
||||
await tick();
|
||||
|
||||
@@ -630,7 +628,7 @@ test('a saved write followed by a failed refresh retries only the read', async (
|
||||
runtime.root.fire('click', { target: retry });
|
||||
assert.equal(runtime.fetchCalls.length, 4);
|
||||
assert.equal(runtime.fetchCalls[3].options.method, undefined);
|
||||
resolveFetch(runtime, 3, { success: true, data: { panel: 'ticket:41', title: 'Ticket 41', description: '#41', list: 'fresh rows', page: 1 } });
|
||||
resolveFetch(runtime, 3, { success: true, data: { panel: 'ticket:41', title: 'Ticket 41', list: 'fresh rows', page: 1 } });
|
||||
await tick();
|
||||
assert.equal(runtime.fetchCalls.filter((call) => call.options.method === 'POST').length, 1);
|
||||
assert.equal(formsIn(runtime).note.querySelector('[name="content"]').value, 'Keep this draft');
|
||||
|
||||
@@ -18,6 +18,8 @@ test('page renders header creation action and one of each dialog, without eagerl
|
||||
assert.equal((html.match(/<dialog /g) || []).length, 2);
|
||||
assert.match(html, /aksrt-native-header__actions[^]*data-aksrt-dialog-open="aksrt-ticket-create-dialog"/);
|
||||
assert.match(html, /aria-controls="aksrt-ticket-detail-dialog"/);
|
||||
assert.doesNotMatch(html, /aksrt-ticket-detail-description/);
|
||||
assert.match(html, /id="aksrt-ticket-create-description"/);
|
||||
assert.doesNotMatch(html, /<details|detail-row|data-aksrt-ticket-detail="/);
|
||||
assert.equal(initial.detail_reads, 0);
|
||||
assert.equal(initial.reply_reads, 0);
|
||||
@@ -40,6 +42,8 @@ test('detail is independently loaded even for a closed ticket outside current fi
|
||||
assert.match(open.data.panel, /action="https:\/\/example.test\/wp-json\/aksrt\/v1\/admin\/tickets\/21\/notes"/);
|
||||
assert.match(open.data.panel, /data-aksrt-ticket-close-confirm/);
|
||||
assert.match(open.data.panel, /value="closed" data-closed="1"/);
|
||||
assert.equal(open.data.description, undefined);
|
||||
assert.match(open.data.panel, /<dt>工单号<\/dt><dd>TK-00021<\/dd>/);
|
||||
});
|
||||
|
||||
test('read handler enforces capability, nonce and record existence', () => {
|
||||
|
||||
Reference in new issue
Block a user