このコミットが含まれているのは:
2026-10-27 01:02:53 +09:00
コミット 53ea010f82
7個のファイルの変更、160行の追加、94行の削除
+34 -24
ファイルの表示
@@ -40,11 +40,9 @@ const CountsControls = (
const id = useId ()
const motion = useClientMotion ()
const [draft, setDraft] = useState (() => new URLSearchParams (applied))
const order = applied.get ('order')
const nestedJSON = applied.get ('nested_json')
const rowNumbers = applied.get ('row_numbers')
const thumbnail = selectedCountColumns (resource, applied, definition).includes ('thumbnail')
const previousThumbnail = useRef (thumbnail)
const previousApplied = useRef ({ resource, params: new URLSearchParams (applied) })
const appliedState = applied.toString ()
const mode = draft.get ('mode') ?? 'summary'
const columns = selectedCountColumns (resource, draft, definition)
const details = mode === 'details'
@@ -53,30 +51,42 @@ const CountsControls = (
&& !countsNestedIsScalar (field.children, field.key, draft)
&& field.children.some (child => selectedCountChildren (draft)
.has (`${field.key}.${child.key}`)))
// Preserve absent columns until a real presentation change or an explicit edit.
useEffect (() => {
if (previousThumbnail.current === thumbnail) return
previousThumbnail.current = thumbnail
setDraft (previous => {
const next = new URLSearchParams (previous)
const columns = selectedCountColumns (resource, previous, definition)
.filter (column => column !== 'thumbnail')
next.set ('columns', (thumbnail ? ['thumbnail', ...columns] : columns).join (' '))
return next
})
}, [thumbnail, resource, definition])
useEffect (() => {
setDraft (previous => {
const next = new URLSearchParams (previous)
const display = { order, nested_json: nestedJSON, row_numbers: rowNumbers }
for (const [key, value] of Object.entries (display))
const nextApplied = new URLSearchParams (appliedState)
const previous = previousApplied.current
previousApplied.current = { resource, params: nextApplied }
setDraft (draft => {
if (previous.resource !== resource
|| previous.params.get ('definition') !== nextApplied.get ('definition'))
return nextApplied
const keys = new Set ([...previous.params.keys (), ...nextApplied.keys ()])
const changed = [...keys].filter (key =>
previous.params.get (key) !== nextApplied.get (key))
const before = selectedCountColumns (resource, previous.params, definition)
const after = selectedCountColumns (resource, nextApplied, definition)
const selectionChanged = before.filter (column => column !== 'thumbnail').join (' ')
!== after.filter (column => column !== 'thumbnail').join (' ')
const internal = ['execution_at', 'timezone', 'order', 'nested_json', 'row_numbers']
if (changed.some (key => key === 'columns' ? selectionChanged : !internal.includes (key)))
return nextApplied
// Internal URL enrichment and immediate display changes preserve pending edits.
const next = new URLSearchParams (draft)
for (const key of changed)
{
if (value == null) next.delete (key)
else next.set (key, value)
if (key === 'columns')
{
const columns = selectedCountColumns (resource, draft, definition)
.filter (column => column !== 'thumbnail')
next.set ('columns', (after.includes ('thumbnail')
? ['thumbnail', ...columns] : columns).join (' '))
continue
}
next.delete (key)
for (const value of nextApplied.getAll (key)) next.append (key, value)
}
return next
return next.toString () === draft.toString () ? draft : next
})
}, [order, nestedJSON, rowNumbers])
}, [appliedState, resource, definition])
const history = draft.get ('definition') === 'history'
const update = (key: string, value: string) => setDraft (previous => {
const next = new URLSearchParams (previous)