Make the change log's slice column readable
A multi-slice operation logs an array of slices, and Object.entries over an array yields its indices -- so the column read "0 = [object Object], 1 = [object Object], ...", which says nothing about what was adjusted. Each slice now gets a line. And since a dragged region is one dimension walked across a fixed set of others, the shared part is pulled out: log 118 is five slices differing only in omon, which now reads as one line of the four fixed fields and one listing Dec through Apr, rather than the same four fields five times over. Only collapsed when exactly one key varies. Two independent axes would lose their pairing when flattened, so those stay listed slice by slice. Dates arrive as epoch millis and are shown as dates; the raw payload is on the cell's title for anything the rendering has flattened. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5376c25e04
commit
c566aab014
@ -1424,7 +1424,24 @@ export default function Forecast({ sources = [], sourceId, versions = [], versio
|
||||
{entry.operation}
|
||||
</span>
|
||||
</td>
|
||||
<td className="px-4 py-2 text-gray-600 font-mono">{fmtSlice(entry.slice)}</td>
|
||||
<td className="px-4 py-2 text-gray-600 font-mono align-top">
|
||||
{(() => {
|
||||
const lines = fmtSliceLines(entry.slice)
|
||||
if (lines.length === 0) return '—'
|
||||
// the raw payload is on the title, for the case where the
|
||||
// rendering has flattened something worth seeing
|
||||
return (
|
||||
<div title={JSON.stringify(entry.slice, null, 2)}>
|
||||
{lines.map((l, i) => (
|
||||
<div key={i} className="whitespace-nowrap">
|
||||
{lines.length > 1 && <span className="text-gray-400 mr-1">{i + 1}.</span>}
|
||||
{l}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
})()}
|
||||
</td>
|
||||
<LogCell entry={entry} field="tag" placeholder="add tag"
|
||||
editing={editingCell} setEditing={setEditingCell} onSave={saveLogField}
|
||||
listId="pf-tag-options"
|
||||
@ -1657,9 +1674,48 @@ function fmtStamp(stamp) {
|
||||
return new Date(stamp).toLocaleString(undefined, { month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit' })
|
||||
}
|
||||
|
||||
function fmtSlice(slice) {
|
||||
if (!slice || !Object.keys(slice).length) return '—'
|
||||
return Object.entries(slice).map(([k, v]) => `${k} = ${v}`).join(', ')
|
||||
// A multi-slice operation logs an array of slices, and Object.entries over an
|
||||
// array yields its indices -- which is where "0 = [object Object]" came from.
|
||||
// Each slice gets its own line; a date arrives as epoch millis and is useless
|
||||
// as a number.
|
||||
function fmtSliceLines(slice) {
|
||||
if (!slice) return []
|
||||
const one = (sl) => Object.entries(sl)
|
||||
.map(([k, v]) => `${k} = ${fmtSliceValue(v)}`)
|
||||
.join(' · ')
|
||||
if (!Array.isArray(slice)) return Object.keys(slice).length ? [one(slice)] : []
|
||||
|
||||
const list = slice.filter(sl => sl && Object.keys(sl).length)
|
||||
if (list.length <= 1) return list.map(one)
|
||||
|
||||
// A dragged region is one dimension walked across a fixed set of others -- the
|
||||
// five slices of log 118 differ only in omon. Printing the other four fields
|
||||
// five times buries the one that actually varies, so pull the shared part out
|
||||
// and list the varying values on their own line.
|
||||
const keys = [...new Set(list.flatMap(sl => Object.keys(sl)))]
|
||||
const varying = keys.filter(k => new Set(list.map(sl => JSON.stringify(sl[k]))).size > 1)
|
||||
|
||||
// Two or more independent axes would lose their pairing if flattened this way,
|
||||
// so only collapse when a single dimension is doing the varying.
|
||||
if (varying.length !== 1) return list.map(one)
|
||||
|
||||
const [vk] = varying
|
||||
const fixed = Object.fromEntries(keys.filter(k => k !== vk).map(k => [k, list[0][k]]))
|
||||
const values = [...new Set(list.map(sl => fmtSliceValue(sl[vk])))]
|
||||
return [
|
||||
...(Object.keys(fixed).length ? [one(fixed)] : []),
|
||||
`${vk} = ${values.join(', ')}`,
|
||||
]
|
||||
}
|
||||
|
||||
function fmtSliceValue(v) {
|
||||
if (v === null || v === undefined || v === '') return '∅'
|
||||
if (typeof v === 'number' && v > 1e11) {
|
||||
const d = new Date(v)
|
||||
if (!isNaN(d)) return d.toISOString().slice(0, 10)
|
||||
}
|
||||
if (typeof v === 'object') return JSON.stringify(v)
|
||||
return String(v)
|
||||
}
|
||||
|
||||
const OP_BADGE = {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user