feat(admin): open ticket creation in a dialog on the list page
Move "代客提交工单" back into a native <dialog> on the ticket list while the ticket workspace stays a full page. Closing asks before discarding input, ignores backdrop clicks, resets the form and returns focus; an uncertain create result keeps the form locked behind "重新加载". Remove the ?view=new create page route and its styles. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d86a85e6a6
commit
54cc5301c3
9 files changed
+169
-65
No files matched your search
@@ -22,7 +22,7 @@
|
||||
.aksrt-ticket-user img { flex: none; border-radius: 50%; }
|
||||
.aksrt-ticket-user span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
|
||||
/* 工作区与创建页共用:页头、提交反馈与表单控件。 */
|
||||
/* 工作区与代客提交弹窗共用:页头、提交反馈与表单控件。 */
|
||||
.aksrt-tickets-admin__detail-header .aksrt-native-header__title { overflow-wrap: anywhere; }
|
||||
.aksrt-tickets-admin__detail-header .aksrt-native-header__desc { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
|
||||
.aksrt-tickets-admin [hidden] { display: none !important; }
|
||||
@@ -34,8 +34,21 @@
|
||||
.aksrt-ticket-feedback p { margin: 0; }
|
||||
.aksrt-ticket-feedback.is-error { color: #a61b36; background: #fdf0f2; border-color: #f6d3da; }
|
||||
.aksrt-ticket-feedback .button { flex: none; }
|
||||
.aksrt-tickets-admin__create { max-width: 880px; }
|
||||
.aksrt-tickets-admin__create .aksrt-native-form-foot .aksrt-ticket-hint { margin-left: auto; }
|
||||
|
||||
/* 代客提交:原生 top layer 弹窗,头尾固定,仅正文滚动。 */
|
||||
.aksrt-ticket-dialog { box-sizing: border-box; width: min(720px, calc(100vw - 48px)); max-width: none; max-height: calc(100dvh - 48px); margin: auto; padding: 0; color: var(--an-text); background: var(--an-card); border: 0; border-radius: var(--an-radius); box-shadow: 0 12px 32px rgba(15, 23, 42, .12), 0 32px 80px rgba(15, 23, 42, .16); overflow: hidden; font: inherit; }
|
||||
.aksrt-ticket-dialog:not([open]) { display: none; }
|
||||
.aksrt-ticket-dialog::backdrop { background: rgba(15, 23, 42, .45); }
|
||||
.aksrt-ticket-dialog__frame { display: flex; flex-direction: column; max-height: calc(100dvh - 48px); margin: 0; }
|
||||
.aksrt-ticket-dialog__head { display: flex; flex: none; align-items: flex-start; justify-content: space-between; gap: 20px; padding: 18px 24px; border-bottom: 1px solid var(--an-border-soft); }
|
||||
.aksrt-ticket-dialog__head h2 { margin: 0; font-size: 18px; font-weight: 600; line-height: 1.5; }
|
||||
.aksrt-ticket-dialog__head h2:focus { outline: 0; }
|
||||
.aksrt-ticket-dialog__head p { margin: 4px 0 0; color: var(--an-muted); font-size: 12px; }
|
||||
.aksrt-ticket-dialog__close { display: inline-flex; flex: none; align-items: center; justify-content: center; width: 32px; height: 32px; margin: -2px -6px 0 0; padding: 0; color: var(--an-muted); background: transparent; border: 0; border-radius: 8px; cursor: pointer; }
|
||||
.aksrt-ticket-dialog__close:hover { color: var(--an-text); background: var(--an-bg-soft); }
|
||||
.aksrt-ticket-dialog__body { min-height: 0; padding: 20px 24px; overflow-y: auto; overscroll-behavior: contain; }
|
||||
.aksrt-ticket-dialog__foot { display: flex; flex: none; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 10px; padding: 14px 24px; border-top: 1px solid var(--an-border-soft); }
|
||||
.aksrt-ticket-dialog__foot > .aksrt-ticket-hint { margin-right: auto; }
|
||||
|
||||
/* 处理工作区:会话与回复在左,处理信息与内部备注在右。 */
|
||||
.aksrt-ticket-detail { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 16px; align-items: start; }
|
||||
@@ -142,7 +155,12 @@
|
||||
.aksrt-ticket-detail__avatar { width: 28px; height: 28px; }
|
||||
.aksrt-ticket-composer__bar select { flex-basis: 100%; max-width: 100%; }
|
||||
.aksrt-ticket-feedback { align-items: flex-start; flex-direction: column; }
|
||||
.aksrt-tickets-admin__create .aksrt-native-form-foot .aksrt-ticket-hint { flex-basis: 100%; margin-left: 0; }
|
||||
.aksrt-ticket-dialog { width: calc(100vw - 16px); max-height: calc(100dvh - 16px); }
|
||||
.aksrt-ticket-dialog__frame { max-height: calc(100dvh - 16px); }
|
||||
.aksrt-ticket-dialog__head,
|
||||
.aksrt-ticket-dialog__body,
|
||||
.aksrt-ticket-dialog__foot { padding: 12px 14px; }
|
||||
.aksrt-ticket-dialog__foot > .aksrt-ticket-hint { flex-basis: 100%; }
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.aksrt-tickets-admin *, .aksrt-tickets-admin *::before { scroll-behavior: auto !important; transition: none !important; animation: none !important; }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/** 工单后台:列表 / 处理工作区 / 代客提交均为页内视图;写操作只使用工单 REST 接口,成功后整页跳转刷新。 */
|
||||
/** 工单后台:列表与处理工作区为页内视图,代客提交为列表页上的原生 dialog;写操作只使用工单 REST 接口,成功后整页跳转刷新。 */
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
if (!root || !config) return;
|
||||
|
||||
var strings = config.strings;
|
||||
var dialog = document.getElementById('aksrt-ticket-create-dialog');
|
||||
var opener = null;
|
||||
var feedbackBox = root.querySelector('[data-aksrt-ticket-feedback]');
|
||||
var detail = root.querySelector('[data-aksrt-ticket-detail]');
|
||||
var ticketId = detail ? parseInt(detail.dataset.aksrtTicketDetail, 10) : 0;
|
||||
@@ -133,7 +135,6 @@
|
||||
/** 成功后跳回工作区并带结果码;未提交的其它表单草稿暂存到 sessionStorage,加载后恢复。 */
|
||||
function go(id, kind, remaining) {
|
||||
var url = new URL(window.location.href);
|
||||
url.searchParams.delete('view');
|
||||
url.searchParams.set('id', String(id));
|
||||
url.searchParams.set('aksrt_ticket_msg', kind);
|
||||
url.hash = '';
|
||||
@@ -176,12 +177,50 @@
|
||||
}
|
||||
}
|
||||
|
||||
/** 关闭代客提交弹窗:保存中不可关;有未保存输入时先确认。不响应遮罩点击,避免误关丢失输入。 */
|
||||
function closeDialog() {
|
||||
if (saving || !dialog.open) return;
|
||||
if (!stale && Object.keys(drafts()).length && !window.confirm(strings.discard)) return;
|
||||
dialog.close();
|
||||
}
|
||||
|
||||
if (dialog) {
|
||||
dialog.addEventListener('cancel', function (event) {
|
||||
event.preventDefault();
|
||||
closeDialog();
|
||||
});
|
||||
dialog.addEventListener('close', function () {
|
||||
var form = dialog.querySelector('[data-aksrt-ticket-form]');
|
||||
if (form && !stale) {
|
||||
form.reset();
|
||||
baselines.set(form, values(form));
|
||||
form.querySelectorAll('[name]').forEach(validateText);
|
||||
form.querySelectorAll('[data-aksrt-ticket-editor]').forEach(counter);
|
||||
feedback('', false, false);
|
||||
}
|
||||
if (opener && opener.isConnected) opener.focus();
|
||||
});
|
||||
}
|
||||
|
||||
root.addEventListener('click', function (event) {
|
||||
if (event.target.closest('[data-aksrt-ticket-reload]')) {
|
||||
leaving = true;
|
||||
window.location.reload();
|
||||
return;
|
||||
}
|
||||
if (dialog && event.target.closest('[data-aksrt-dialog-close]')) {
|
||||
closeDialog();
|
||||
return;
|
||||
}
|
||||
var open = dialog && event.target.closest('[data-aksrt-dialog-open="' + dialog.id + '"]');
|
||||
if (open) {
|
||||
if (saving) return;
|
||||
opener = open;
|
||||
// 结果未确认时保留「重新加载」提示,重新打开也不能再提交。
|
||||
if (!stale) feedback('', false, false);
|
||||
dialog.showModal();
|
||||
return;
|
||||
}
|
||||
if (saving || stale) return;
|
||||
var assign = event.target.closest('[data-aksrt-ticket-assign]');
|
||||
if (assign) {
|
||||
|
||||
Reference in new issue
Block a user