このコミットが含まれているのは:
2026-10-28 20:34:11 +09:00
コミット cb3f4c600a
14個のファイルの変更、208行の追加、33行の削除
+13 -4
ファイルの表示
@@ -98,6 +98,7 @@ export type CountsResult = {
export type CountSort = { key: string; direction: 'asc' | 'desc' }
export type CountField = { key: string; label: string; children?: CountField[]
labelValues?: Record<string, string>
multipleValues?: boolean
nameLocale?: { code: string; languageCode: string; scriptCode: string } }
export type CountRecord = Record<string, unknown>
@@ -335,12 +336,17 @@ export const normaliseCountsParams = (
const params = new URLSearchParams (source)
if (definition?.nameColumns != null)
{
const names = definition.nameColumns.map (field => field.key)
const names = definition.nameColumns.filter (field => !field.multipleValues)
.map (field => field.key)
const current = definition.nameColumns.find (field =>
field.nameLocale?.code === currentViewingLocale ())?.key
!field.multipleValues && field.nameLocale?.code === currentViewingLocale ())?.key
const aliases = definition.nameColumns.find (field =>
field.multipleValues && field.nameLocale?.code === currentViewingLocale ())?.key
const rootKey = (key: string) => (key === 'name' && current != null) ? current
: ((key === 'aliases' && aliases != null) ? aliases : key)
if (resource === 'tags' && params.has ('columns'))
params.set ('columns', params.get ('columns')!.split (' ').flatMap (key =>
key === 'names' ? names : [key === 'name' && current != null ? current : key])
key === 'names' ? names : [rootKey (key)])
.join (' '))
if (params.has ('children'))
{
@@ -348,12 +354,15 @@ export const normaliseCountsParams = (
params.set ('children', selected.flatMap (key => {
if (['tags.names', 'parents.names'].includes (key))
return names.map (name => `${key.slice (0, -6)}.${name}`)
if (['tags.aliases', 'parents.aliases'].includes (key) && aliases != null)
return [`${key.slice (0, -8)}.${aliases}`]
if (key.startsWith ('tags.aliases.') || key.startsWith ('parents.aliases.')) return []
return key.startsWith ('tags.names.') || key.startsWith ('parents.names.') ? [] : [key]
}).join (' '))
}
if (resource === 'tags' && params.has ('order'))
params.set ('order', params.get ('order')!.split (' ').flatMap (key =>
key === 'names' ? names : [key === 'name' && current != null ? current : key])
key === 'names' ? names : [rootKey (key)])
.join (' '))
}
for (const [key, value] of params)
+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
+4
ファイルの表示
@@ -58,6 +58,7 @@ export const countsCellText = (
case 'created_at': return date (row.createdAt)
default:
{
if (column.startsWith ('aliases_')) return countsLogicalName (row, column, locale).text
const key = column.replace (/_([a-z])/g, (_, letter: string) => letter.toUpperCase ())
const value = row[key]
if (['discarded_at', 'updated_at'].includes (column) && typeof value === 'string')
@@ -123,6 +124,9 @@ export const countsLogicalName = (
): { text: string; language?: string } => {
const value = countsFieldValue (row, field)
if (value == null) return { text: '' }
if (field.startsWith ('aliases_') && Array.isArray (value))
return { text: value.map (entry => typeof entry === 'string' ? entry
: String (entry?.name ?? '')).join ('\n') }
if (field === 'sections')
return { text: (countsSectionRanges (value, locale) ?? []).join (
translateUIMessage ('sections.separator', 'counts', locale).text) }