このコミットが含まれているのは:
2026-10-28 20:34:11 +09:00
コミット cb3f4c600a
14個のファイルの変更、208行の追加、33行の削除
+41 -2
ファイルの表示
@@ -1,6 +1,6 @@
import { createContext, useContext } from 'react'
import { translateUIMessage } from '@/lib/i18n'
import { i18n, translateUIMessage } from '@/lib/i18n'
import { apiGet } from '@/lib/api'
import type { LocaleCode } from '@/lib/locales'
@@ -26,6 +26,7 @@ export type CountsFieldMetadata = {
labels?: string[]; multiple?: boolean; candidateSource?: 'categories' | 'tags'
setType?: 'tag_reference'; inputTypes?: string[]
labelValues?: Record<string, string>
nameLocale?: CountField['nameLocale']
choices?: { value: string; label: string }[] }
export type CountsDefinition = {
fields: CountsFieldMetadata[]
@@ -46,10 +47,48 @@ export const useCountsDefinition = (): CountsDefinition => {
}
const localiseCountsDefinition = (
definition: CountsDefinition, locale: LocaleCode,
): CountsDefinition => {
const heading = (name: CountField['nameLocale'], aliasesFlg: boolean) => {
if (name == null) return null
const key = `languageNames.${name.languageCode}`
const language = i18n.exists (key, { ns: 'counts', lng: locale })
? translateUIMessage (key, 'counts', locale).text : name.languageCode
const scripts = new Set ((definition.nameColumns ?? [])
.filter (field => field.nameLocale?.languageCode === name.languageCode)
.map (field => field.nameLocale!.scriptCode.toLowerCase ()))
const label = aliasesFlg ? 'counts:localeAliases' : 'counts:localeName'
return { label: scripts.size > 1 ? `${label}WithScript` : label,
labelValues: { language, script: name.scriptCode } }
}
const columns = (fields: CountField[]): CountField[] => fields.map (field => ({
...field, ...heading (field.nameLocale, field.multipleValues === true),
...(field.children == null ? { } : { children: columns (field.children) }) }))
const metadata = (fields: CountsFieldMetadata[]): CountsFieldMetadata[] =>
fields.map (field => {
const aliasesFlg = field.key.split ('.').pop()?.startsWith ('aliases_') === true
const name = heading (field.nameLocale, aliasesFlg)
return name == null ? field : { ...field, labelValues: name.labelValues,
labels: field.labels?.map (label =>
['counts:localeName', 'counts:localeAliases'].includes (label) ? name.label : label) }
})
return { ...definition,
fields: metadata (definition.fields),
...(definition.outputFields == null ? { }
: { outputFields: columns (definition.outputFields) }),
...(definition.nameColumns == null ? { }
: { nameColumns: columns (definition.nameColumns) }),
...(definition.filterFields == null ? { }
: { filterFields: metadata (definition.filterFields) }) }
}
export const fetchCountsDefinition = (
resource: CountsResource, locale: LocaleCode = 'ja',
): Promise<CountsDefinition> => apiGet (
): Promise<CountsDefinition> => apiGet<CountsDefinition> (
`/counts/definitions/${encodeURIComponent (resource)}`, { locale })
.then (definition => localiseCountsDefinition (definition, locale))
export type CountsCandidate = {
value: string; id?: number; name: string | null; category?: string | null