Show the clone date offset without requiring a segment

The offset field was rendered only when a segment had been named, from when
that was the only way clone could reach reference rows. Once clone could read
them directly the field became unreachable in the ordinary case -- so
"shift dates by" was invisible and the only typeable-looking control was
"copy rows from", which is a dropdown.

It is shown whenever clone is open now, and the payload carries the offset
independently of from_logid: shifting a selection through time is the common
case, and narrowing to one segment is the occasional one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Paul Trowbridge 2026-09-17 02:40:58 -04:00
parent ee4a60475e
commit cc3d83268f
2 changed files with 12 additions and 11 deletions

View File

@ -806,9 +806,10 @@ export default function OperationPanel({
</select>
</div>
{/* Only meaningful when borrowing across time, so it
appears with the segment rather than always. */}
{cloneFrom && (
{/* Always shown. This was gated on picking a segment, from
when naming one was the only way to reach reference rows
-- once clone could read them directly, the offset became
unreachable in the ordinary case. */}
<div className="flex items-center gap-2 flex-wrap">
<span className="text-gray-500 whitespace-nowrap">shift dates by</span>
<input value={cloneOffset} list="pf-clone-offsets"
@ -822,8 +823,7 @@ export default function OperationPanel({
<option value="0 days" />
</datalist>
</div>
)}
{cloneFrom && (
{cloneOffset.trim() && cloneOffset.trim() !== '0 days' && (
<p className="text-gray-500 text-[11px] leading-snug max-w-sm">
The cells you have selected are what gets copied. Shifting
moves every date column, and the season and month

View File

@ -1241,10 +1241,11 @@ export default function Forecast({ sources = [], sourceId, versions = [], versio
} else if (op === 'clone') {
const set = Object.fromEntries(Object.entries(cloneSet).filter(([, v]) => v.trim()))
body = { ...body, note: cloneNote || undefined, set, scale: parseFloat(cloneScale) || 1 }
if (cloneFrom) {
body.from_logid = Number(cloneFrom)
body.date_offset = cloneOffset.trim() || '0 days'
}
// The offset stands on its own: shifting a selection through time is the
// common case, and it used to be sent only when a segment was named.
if (cloneFrom) body.from_logid = Number(cloneFrom)
const off = cloneOffset.trim()
if (off && off !== '0 days') body.date_offset = off
}
return body
}