このコミットが含まれているのは:
2026-10-29 12:38:03 +09:00
コミット 549a45e9d5
8個のファイルの変更、71行の追加、19行の削除
+27 -12
ファイルの表示
@@ -17,17 +17,18 @@ import { useClientMotion } from '@/lib/useClientMotion'
import { inputClass } from '@/lib/utils'
import { useUITranslation } from '@/lib/useUITranslation'
import { readCountState, setCountState } from '@/lib/queryState'
import { readCountState, setCountState, encodeCountState } from '@/lib/queryState'
import type { ReactNode } from 'react'
import type { CountsResource } from '@/lib/counts'
import type { CountsResource, CountsResult } from '@/lib/counts'
const CountsControls = (
{ resource, applied, open, setOpen, execute, displayJSON, displayRowNumbers,
displayThumbnail, reorder, actions, pending = false }: {
displayThumbnail, reorder, actions, conditionLabels, pending = false }: {
resource: CountsResource; applied: URLSearchParams; open: boolean
conditionLabels?: CountsResult['conditionLabels']
pending?: boolean
setOpen: (open: boolean) => void
execute: (params: URLSearchParams) => void
@@ -92,6 +93,27 @@ const CountsControls = (
const update = (key: string, value: string) => setDraft (previous => {
const next = new URLSearchParams (previous)
setCountState (next, key, value)
if (key === 'tags')
{
const tokens = value.split (/\s+/).filter (token => token
&& token.toLowerCase () !== 'type:or')
const remaining = [...tokens]
const references = readCountState<Record<string, string | number | boolean>[]> (
previous, 'tag_refs', []).flatMap (reference => {
const name = String (reference.name)
const exact = remaining.indexOf (name)
const index = exact >= 0 ? exact : remaining.findIndex (token =>
token.replace (/^not:/i, '') === name.replace (/^not:/i, ''))
if (index < 0) return []
const [token] = remaining.splice (index, 1)
return [token === name ? reference : { ...reference, name: token,
negative: token.toLowerCase ().startsWith ('not:') }]
})
for (const name of [...next.keys ()])
if (name === 'tag_refs' || name.startsWith ('tag_refs.')) next.delete (name)
if (references.length > 0)
setCountState (next, 'tag_refs', encodeCountState ('tag_refs', references))
}
if (key === 'limit') next.delete ('page')
if (next.toString () === previous.toString ()) return previous
if (['rows', 'cols'].includes (key) && next.get ('sort') !== '') next.delete ('sort')
@@ -248,14 +270,6 @@ const CountsControls = (
<option value="all">AND</option><option value="any">OR</option>
</select>
{draft.get ('tags') && <>
{readCountState<Record<string, string | number>[]> (
draft, 'tag_refs', []).map ((reference, index) => (
<span key={index} className="text-sm">
{reference.name} ({[reference.tag_id == null ? ''
: `internal:${reference.tag_id}`,
reference.external_tag_id == null ? ''
: `external:${reference.external_tag_id}`].filter (Boolean).join (' ')})
</span>))}
<Button type="button" variant="ghost" size="sm"
aria-label={message ('remove').text} onClick={() => setDraft (previous => {
const next = new URLSearchParams (previous)
@@ -267,7 +281,8 @@ const CountsControls = (
</>}
</div>}
</FormField>}
<CountsAdditionalConditions params={draft} update={update}/>
<CountsAdditionalConditions params={draft} update={update}
conditionLabels={conditionLabels}/>
</fieldset>
</div>
</div>