portfolio-edit: rebuild form as compact inline strip
Replace the multi-row wizard-style form (Ticker / Qty on row 1, mode radios on row 2, Date+Cost on row 3) with a single horizontal strip that sits unobtrusively above the portfolio table. The radio toggle is gone; a small calendar icon next to the Cost input pops out a date picker that auto-fills cost on selection and then hides itself. Same input IDs, so the existing validate/Add/× handlers work unchanged. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
70da4cdf84
commit
a9b7d4d8bb
3 changed files with 95 additions and 98 deletions
|
|
@ -177,32 +177,26 @@
|
|||
}
|
||||
});
|
||||
|
||||
// ---- Cost mode toggle + historical lookup --------------------------
|
||||
// ---- Calendar-icon → historical lookup -----------------------------
|
||||
|
||||
const dateField = document.getElementById('pf-add-date-field');
|
||||
const dateBtn = document.getElementById('pf-add-date-btn');
|
||||
const dateInput = document.getElementById('pf-add-date');
|
||||
const dateStatus = document.getElementById('pf-add-date-status');
|
||||
const costInput = document.getElementById('pf-add-cost');
|
||||
|
||||
function onModeChange() {
|
||||
const mode = document.querySelector(
|
||||
'input[name="pf-cost-mode"]:checked'
|
||||
).value;
|
||||
if (mode === 'date') {
|
||||
dateField.hidden = false;
|
||||
costInput.readOnly = true;
|
||||
costInput.placeholder = 'auto-filled from date';
|
||||
dateBtn.addEventListener('click', function () {
|
||||
if (!validated) {
|
||||
setStatus(dateStatus, 'enter a valid ticker first', 'err');
|
||||
return;
|
||||
}
|
||||
dateInput.hidden = !dateInput.hidden;
|
||||
if (!dateInput.hidden) {
|
||||
dateInput.focus();
|
||||
if (typeof dateInput.showPicker === 'function') dateInput.showPicker();
|
||||
} else {
|
||||
dateField.hidden = true;
|
||||
costInput.readOnly = false;
|
||||
costInput.placeholder = '150.25';
|
||||
setStatus(dateStatus, '', '');
|
||||
}
|
||||
}
|
||||
|
||||
document.querySelectorAll('input[name="pf-cost-mode"]').forEach(r =>
|
||||
r.addEventListener('change', onModeChange)
|
||||
);
|
||||
});
|
||||
|
||||
async function fetchHistorical() {
|
||||
if (!validated) {
|
||||
|
|
@ -212,8 +206,6 @@
|
|||
const d = dateInput.value;
|
||||
if (!d) {
|
||||
setStatus(dateStatus, '', '');
|
||||
costInput.value = '';
|
||||
updateSubmitState();
|
||||
return;
|
||||
}
|
||||
setStatus(dateStatus, 'looking up…', 'pending');
|
||||
|
|
@ -225,7 +217,6 @@
|
|||
if (r.status === 400) {
|
||||
const j = await r.json().catch(() => ({detail: 'invalid date'}));
|
||||
setStatus(dateStatus, '✗ ' + (j.detail || 'invalid date'), 'err');
|
||||
costInput.value = '';
|
||||
updateSubmitState();
|
||||
return;
|
||||
}
|
||||
|
|
@ -236,18 +227,18 @@
|
|||
? '✓ from ' + j.actual_date
|
||||
: '✓';
|
||||
setStatus(dateStatus, tag, 'ok');
|
||||
// Hide the date picker after a successful fill — keeps the row clean.
|
||||
dateInput.hidden = true;
|
||||
} else {
|
||||
setStatus(dateStatus, '✗ ' + (j.error || 'no data'), 'err');
|
||||
costInput.value = '';
|
||||
}
|
||||
} catch (e) {
|
||||
setStatus(dateStatus, '✗ couldn\'t fetch — try again', 'err');
|
||||
costInput.value = '';
|
||||
}
|
||||
updateSubmitState();
|
||||
}
|
||||
|
||||
dateInput.addEventListener('blur', fetchHistorical);
|
||||
dateInput.addEventListener('change', fetchHistorical);
|
||||
|
||||
// ---- Per-row delete (event delegation) -----------------------------
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue