feat: 优化待办截图删除操作 #683

Merged
yueyang merged 1 commits from feature/yueyang-systemization-screenshot-delete into main 2026-10-27 13:12:00 +08:00
2 changed files with 78 additions and 13 deletions

View File

@ -147,10 +147,22 @@
.sys-todo-upload-note { flex:1 1 15rem; color:#666; font-size:.72rem; line-height:1.5; }
.sys-todo-field.is-dragging { outline:2px dashed var(--sys-gold); outline-offset:3px; border-radius:.55rem; background:var(--sys-gold-soft); }
.sys-todo-existing { display:flex; flex-wrap:wrap; gap:.55rem; margin-top:.45rem; }
.sys-todo-existing__item { display:grid; gap:.25rem; width:8.5rem; padding:.4rem; border:1px solid #e4dccd; border-radius:.45rem; background:#fcfaf5; font-size:.7rem; }
.sys-todo-existing__item button { display:block; width:100%; padding:0; border:0; border-radius:.3rem; background:#fff; cursor:zoom-in; overflow:hidden; }
.sys-todo-existing__item img { display:block; width:100%; height:5rem; object-fit:contain; background:#fff; }
.sys-todo-existing__item label { display:flex; align-items:center; gap:.25rem; color:#b80000; }
.sys-todo-existing__item { position:relative; display:flex; flex-direction:column; gap:.35rem; width:9.25rem; padding:.45rem; border:1px solid #e4dccd; border-radius:.45rem; background:#fcfaf5; font-size:.7rem; transition:border-color 150ms ease,background 150ms ease; }
.sys-todo-existing__preview { display:block; width:100%; padding:0; border:1px solid #e4dccd; border-radius:.35rem; background:#fff; cursor:zoom-in; overflow:hidden; }
.sys-todo-existing__preview:hover { border-color:var(--sys-gold); }
.sys-todo-existing__preview:focus-visible { outline:2px solid var(--sys-gold); outline-offset:2px; }
.sys-todo-existing__preview img { display:block; width:100%; height:4.75rem; object-fit:contain; background:#fff; transition:opacity 150ms ease,filter 150ms ease; }
.sys-todo-existing__name { display:block; overflow:hidden; color:#595959; line-height:1.35; text-overflow:ellipsis; white-space:nowrap; }
.sys-todo-existing__state { position:absolute; top:.62rem; right:.62rem; z-index:2; display:none; padding:.08rem .36rem; border:1px solid #dba9a9; border-radius:999px; background:rgba(255,247,247,.96); color:#b80000; font-size:.62rem; font-weight:600; }
.sys-todo-existing__remove { display:inline-flex; align-items:center; justify-content:center; gap:.22rem; width:100%; min-height:1.8rem; margin-top:auto; padding:0 .4rem; border:1px solid #e7c3c3; border-radius:.35rem; background:#fff; color:#b80000; font:inherit; font-size:.7rem; font-weight:500; white-space:nowrap; cursor:pointer; transition:border-color 150ms ease,background 150ms ease,color 150ms ease; }
.sys-todo-existing__remove:hover { border-color:#d89a9a; background:#fff3f3; }
.sys-todo-existing__remove:focus-visible { outline:2px solid #b80000; outline-offset:2px; }
.sys-todo-existing__remove .material-icons-outlined { font-size:.9rem; }
.sys-todo-existing__remove[aria-pressed="true"] { border-color:#b80000; background:#b80000; color:#fff; }
.sys-todo-existing__item.is-marked-for-removal { border-color:#d9aaaa; background:#fff6f6; }
.sys-todo-existing__item.is-marked-for-removal .sys-todo-existing__preview img { opacity:.45; filter:grayscale(1); }
.sys-todo-existing__item.is-marked-for-removal .sys-todo-existing__name { color:#8a3030; }
.sys-todo-existing__item.is-marked-for-removal .sys-todo-existing__state { display:inline-flex; }
.sys-todo-dialog__foot { display:flex; justify-content:flex-end; gap:.5rem; padding:.75rem 1.25rem; border-top:1px solid #e8e0d2; background:#fcfaf5; }
.sys-todo-dialog__foot button { min-height:2.1rem; padding:0 .9rem; border:1px solid var(--sys-border); border-radius:.45rem; background:#fff; font:inherit; font-size:.8125rem; cursor:pointer; }
.sys-todo-dialog__foot button[type="submit"] { border-color:var(--sys-gold); background:var(--sys-gold); color:#fff; }
@ -1271,6 +1283,21 @@
else groupDialog.removeAttribute('open');
}
function toggleAttachmentRemoval(button) {
var marked = button.getAttribute('aria-pressed') !== 'true';
var item = button.closest('.sys-todo-existing__item');
var input = item ? item.querySelector('[data-sys-todo-remove-input]') : null;
var label = button.querySelector('[data-sys-todo-remove-label]');
var name = button.getAttribute('data-sys-todo-remove-name') || '';
button.setAttribute('aria-pressed', marked ? 'true' : 'false');
button.setAttribute('aria-label', (marked ? '取消删除截图:' : '删除截图:') + name);
button.title = marked ? '再次点击可取消,保存待办后删除' : '标记删除,保存待办后生效';
if (label) label.textContent = marked ? '取消删除' : '删除';
if (input) input.disabled = !marked;
if (item) item.classList.toggle('is-marked-for-removal', marked);
}
function openDialog(payload) {
currentTodoId = payload && payload.id ? payload.id : null;
currentTodoTitle = payload && payload.title ? payload.title : '';
@ -1320,10 +1347,15 @@
existing.replaceChildren();
((payload && payload.attachments) || []).forEach(function (attachment) {
var item = document.createElement('span');
var item = document.createElement('div');
item.className = 'sys-todo-existing__item';
var state = document.createElement('span');
state.className = 'sys-todo-existing__state';
state.textContent = '保存后删除';
item.appendChild(state);
var preview = document.createElement('button');
preview.type = 'button';
preview.className = 'sys-todo-existing__preview';
preview.setAttribute('data-sys-todo-image-url', attachment.url);
preview.setAttribute('data-sys-todo-image-name', attachment.name);
preview.title = '点击预览:' + attachment.name;
@ -1332,14 +1364,36 @@
image.alt = attachment.name;
preview.appendChild(image);
item.appendChild(preview);
var label = document.createElement('label');
var checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.name = 'remove_attachments[]';
checkbox.value = attachment.id;
label.appendChild(checkbox);
label.appendChild(document.createTextNode('删除截图'));
item.appendChild(label);
var fileName = document.createElement('span');
fileName.className = 'sys-todo-existing__name';
fileName.textContent = attachment.name || '完成截图';
fileName.title = attachment.name || '完成截图';
item.appendChild(fileName);
var remove = document.createElement('button');
remove.type = 'button';
remove.className = 'sys-todo-existing__remove';
remove.setAttribute('data-sys-todo-remove-attachment', '');
remove.setAttribute('data-sys-todo-remove-name', attachment.name || '完成截图');
remove.setAttribute('aria-pressed', 'false');
remove.setAttribute('aria-label', '删除截图:' + (attachment.name || '完成截图'));
remove.title = '标记删除,保存待办后生效';
var removeIcon = document.createElement('span');
removeIcon.className = 'material-icons-outlined';
removeIcon.setAttribute('aria-hidden', 'true');
removeIcon.textContent = 'delete_outline';
var removeLabel = document.createElement('span');
removeLabel.setAttribute('data-sys-todo-remove-label', '');
removeLabel.textContent = '删除';
remove.appendChild(removeIcon);
remove.appendChild(removeLabel);
item.appendChild(remove);
var removeInput = document.createElement('input');
removeInput.type = 'hidden';
removeInput.name = 'remove_attachments[]';
removeInput.value = attachment.id;
removeInput.disabled = true;
removeInput.setAttribute('data-sys-todo-remove-input', '');
item.appendChild(removeInput);
existing.appendChild(item);
});
@ -1389,6 +1443,13 @@
);
return;
}
var removeAttachment = event.target.closest('[data-sys-todo-remove-attachment]');
if (removeAttachment) {
event.preventDefault();
event.stopPropagation();
toggleAttachmentRemoval(removeAttachment);
return;
}
var inlineAdd = event.target.closest('[data-sys-todo-inline-add]');
if (inlineAdd) {
event.preventDefault();

View File

@ -64,6 +64,10 @@ class SystemizationTodosTest extends FeatureTestCase
->assertSeeText('+ 新增内容')
->assertSeeText('在类型、内容下方的+直接新增')
->assertSee('data-sys-todo-choose-files', false)
->assertSee('data-sys-todo-remove-attachment', false)
->assertSee('data-sys-todo-remove-input', false)
->assertSee('is-marked-for-removal', false)
->assertSee('保存后删除', false)
->assertSee('data-sys-todo-open-delete', false)
->assertSee('id="sysTodoDeleteConfirm"', false)
->assertSee('data-sys-todo-table-wrap', false)