feat: review entry reason picker uses dropdown instead of prompt
Add modal select for trade record review, expand options to two-level labels (反转/启动A), and accept legacy short labels on save. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -282,6 +282,91 @@
|
||||
el.style.display = html ? "flex" : "none";
|
||||
}
|
||||
|
||||
function promptReviewEntryReason(options, currentValue) {
|
||||
const opts = Array.isArray(options) ? options : [];
|
||||
const cur = String(currentValue == null ? "" : currentValue).trim();
|
||||
return new Promise(function (resolve) {
|
||||
const backdrop = document.createElement("div");
|
||||
backdrop.className = "review-entry-reason-backdrop open";
|
||||
const modal = document.createElement("div");
|
||||
modal.className = "review-entry-reason-modal";
|
||||
modal.setAttribute("role", "dialog");
|
||||
modal.setAttribute("aria-modal", "true");
|
||||
|
||||
const title = document.createElement("h3");
|
||||
title.textContent = "开仓类型";
|
||||
modal.appendChild(title);
|
||||
|
||||
const hint = document.createElement("p");
|
||||
hint.className = "review-entry-reason-hint";
|
||||
hint.textContent = "请选择下拉选项之一;选「不改该项」则保留原值。";
|
||||
modal.appendChild(hint);
|
||||
|
||||
const select = document.createElement("select");
|
||||
select.className = "review-entry-reason-select";
|
||||
const emptyOpt = document.createElement("option");
|
||||
emptyOpt.value = "";
|
||||
emptyOpt.textContent = "(不改该项)";
|
||||
select.appendChild(emptyOpt);
|
||||
|
||||
const seen = new Set([""]);
|
||||
if (cur && opts.indexOf(cur) < 0) {
|
||||
const curOpt = document.createElement("option");
|
||||
curOpt.value = cur;
|
||||
curOpt.textContent = cur + "(当前)";
|
||||
select.appendChild(curOpt);
|
||||
seen.add(cur);
|
||||
}
|
||||
opts.forEach(function (opt) {
|
||||
const v = String(opt || "").trim();
|
||||
if (!v || seen.has(v)) return;
|
||||
const o = document.createElement("option");
|
||||
o.value = v;
|
||||
o.textContent = v;
|
||||
select.appendChild(o);
|
||||
seen.add(v);
|
||||
});
|
||||
if (cur) select.value = cur;
|
||||
modal.appendChild(select);
|
||||
|
||||
const actions = document.createElement("div");
|
||||
actions.className = "review-entry-reason-actions";
|
||||
const cancelBtn = document.createElement("button");
|
||||
cancelBtn.type = "button";
|
||||
cancelBtn.className = "review-entry-reason-cancel";
|
||||
cancelBtn.textContent = "取消";
|
||||
const okBtn = document.createElement("button");
|
||||
okBtn.type = "button";
|
||||
okBtn.className = "review-entry-reason-ok";
|
||||
okBtn.textContent = "确定";
|
||||
actions.appendChild(cancelBtn);
|
||||
actions.appendChild(okBtn);
|
||||
modal.appendChild(actions);
|
||||
backdrop.appendChild(modal);
|
||||
document.body.appendChild(backdrop);
|
||||
|
||||
function cleanup(result) {
|
||||
document.removeEventListener("keydown", onKey);
|
||||
backdrop.remove();
|
||||
resolve(result);
|
||||
}
|
||||
function onKey(ev) {
|
||||
if (ev.key === "Escape") cleanup(null);
|
||||
}
|
||||
cancelBtn.addEventListener("click", function () {
|
||||
cleanup(null);
|
||||
});
|
||||
backdrop.addEventListener("click", function (ev) {
|
||||
if (ev.target === backdrop) cleanup(null);
|
||||
});
|
||||
okBtn.addEventListener("click", function () {
|
||||
cleanup(select.value);
|
||||
});
|
||||
document.addEventListener("keydown", onKey);
|
||||
select.focus();
|
||||
});
|
||||
}
|
||||
|
||||
function openTradeRecordDetailModal(tr) {
|
||||
const row = parseTradeRecordRow(tr);
|
||||
if (!row) return;
|
||||
@@ -327,5 +412,6 @@
|
||||
clearDetailActions: clearDetailActions,
|
||||
clearJournalDetailImages: clearJournalDetailImages,
|
||||
setJournalDetailImages: setJournalDetailImages,
|
||||
promptReviewEntryReason: promptReviewEntryReason,
|
||||
};
|
||||
})(typeof window !== "undefined" ? window : globalThis);
|
||||
|
||||
Reference in New Issue
Block a user