このコミットが含まれているのは:
2026-10-25 23:08:48 +09:00
コミット 8642225b94
21個のファイルの変更、920行の追加、360行の削除
+66 -24
ファイルの表示
@@ -1,52 +1,94 @@
import { isCountsState, selectedCountFields } from '@/lib/counts'
import { translateUIMessage } from '@/lib/i18n'
import type { CountField, CountsStateRow } from '@/lib/counts'
import type { CountField, CountsResource, CountsResult } from '@/lib/counts'
import type { LocaleCode } from '@/lib/locales'
export type CountsSummaryRow = {
key: string | number | null
name: string | null
count: number | null
kind?: 'internal' | 'external'
tagId?: number
deprecated?: string | null
at?: string }
export const countsStateFields = (trend: boolean): CountField[] => trend
? [{ key: 'period', label: 'counts:state.period' },
{ key: 'count', label: 'counts:state.postCount' }]
: [{ key: 'kind', label: 'counts:columns.kind' },
export const countsSummaryFields = (
resource: CountsResource,
params: URLSearchParams,
): CountField[] => (isCountsState (params) && params.get ('axis') === 'tags')
? [{ key: 'kind', label: 'counts:columns.kind' },
{ key: 'tag_id', label: 'counts:columns.resourceId' },
{ key: 'name', label: 'history:tagName' },
{ key: 'deprecated', label: 'counts:columns.deprecated' },
{ key: 'count', label: 'counts:state.postCount' }]
: [{ key: 'group', label: `counts:axes.${params.get ('axis') ?? 'month'}` },
{ key: 'count', label: isCountsState (params)
? `counts:state.totals.${resource}` : 'counts:metric' }]
export const countsStateCell = (
row: CountsStateRow,
export const selectedCountsSummaryFields = (
resource: CountsResource,
params: URLSearchParams,
): CountField[] => selectedCountFields (
countsSummaryFields (resource, params), params, 'summary_columns', 'summary')
export const countsSummaryRows = (data: CountsResult): CountsSummaryRow[] =>
data.stateRows != null
? data.stateRows.map (row => ({ ...row, key: `${row.kind}:${row.tagId}` }))
: data.groups ?? []
export const countsSummaryCell = (
row: CountsSummaryRow,
key: string,
locale: LocaleCode,
): string => {
): { text: string; language?: string } => {
switch (key)
{
case 'period': return row.period ?? ''
case 'count': return row.count == null ? '—' : String (row.count)
case 'tag_id': return String (row.tagId)
case 'kind': return translateUIMessage (`kinds.${row.kind}`, 'counts', locale).text
case 'name': return row.name ?? translateUIMessage ('notRegistered', 'counts', locale).text
case 'group': return row.key == null
? translateUIMessage ('history:bot', 'counts', locale)
: { text: row.name ?? String (row.key) }
case 'count': return { text: row.count == null ? '—' : String (row.count) }
case 'tag_id': return { text: String (row.tagId) }
case 'kind': return translateUIMessage (`kinds.${row.kind}`, 'counts', locale)
case 'name': return row.name == null
? translateUIMessage ('notRegistered', 'counts', locale) : { text: row.name }
case 'deprecated': return row.deprecated
? translateUIMessage ('common:states.deprecated', 'counts', locale).text : ''
default: return ''
? translateUIMessage ('common:states.deprecated', 'counts', locale) : { text: '' }
default: return { text: '' }
}
}
export const countsStateDrill = (
export const countsSummaryDrill = (
resource: CountsResource,
params: URLSearchParams,
at: string,
resource = 'posts',
row?: CountsStateRow,
row: CountsSummaryRow,
): string => {
const next = new URLSearchParams (params)
for (const key of ['sort', 'page', 'tag', 'from', 'before']) next.delete (key)
next.set ('mode', 'snapshot')
next.set ('at', at)
if (row != null)
for (const key of ['sort', 'page']) next.delete (key)
next.set ('mode', 'details')
if (row.at) next.set ('at', row.at)
if (row.tagId != null)
{
next.set ('kind', row.kind)
next.set ('kind', row.kind!)
next.set ('tag', String (row.tagId))
}
else if (params.get ('axis') === 'user') next.set ('user_id', String (row.key ?? 'none'))
else
{
const first = `${row.key}-01T00:00:00Z`
const date = new Date (first)
date.setUTCMonth (date.getUTCMonth () + 1)
const last = date.toISOString ()
const from = next.get ('from')
const before = next.get ('before')
next.set ('from', (from != null && Date.parse (from) > Date.parse (first)) ? from : first)
next.set ('before',
(before != null && Date.parse (before) < Date.parse (last)) ? before : last)
}
return `/counts/${resource}?${next}`
}