このコミットが含まれているのは:
@@ -2,7 +2,7 @@ import { countsFieldLabel } from '@/lib/countsDefinitions'
|
||||
import { apiDownload, apiGet } from '@/lib/api'
|
||||
import { currentViewingLocale, localeLanguage } from '@/lib/locales'
|
||||
|
||||
import { readCountState, encodeCountState } from '@/lib/queryState'
|
||||
import { readCountState, encodeCountState, setCountState } from '@/lib/queryState'
|
||||
|
||||
import type { CountsAxis, CountsDefinition } from '@/lib/countsDefinitions'
|
||||
import type { LocaleCode } from '@/lib/locales'
|
||||
@@ -368,6 +368,22 @@ export const normaliseCountsParams = (
|
||||
definition?: CountsDefinition,
|
||||
): URLSearchParams => {
|
||||
const params = new URLSearchParams (source)
|
||||
const drills = readCountState<Record<string, unknown>[]> (params, 'drill', [])
|
||||
if (params.get ('tag'))
|
||||
{
|
||||
drills.push ({ field: 'tags', value: `${params.get ('kind') ?? 'internal'}:${
|
||||
params.get ('tag')}` })
|
||||
params.delete ('tag')
|
||||
params.delete ('kind')
|
||||
}
|
||||
if (drills.length > 0)
|
||||
{
|
||||
const conditions = readCountState<Record<string, unknown>[]> (params, 'conditions', [])
|
||||
setCountState (params, 'conditions', encodeCountState ('conditions', [
|
||||
...conditions, ...drills.map (entry => ({ ...entry, operator: 'axis_eq' }))]))
|
||||
for (const key of [...params.keys ()])
|
||||
if (key === 'drill' || key.startsWith ('drill.')) params.delete (key)
|
||||
}
|
||||
if (!params.has ('limit')) params.set ('limit', '100')
|
||||
const nameScope = params.get ('name_scope')
|
||||
if (definition?.conditionAliases != null && (nameScope == null || nameScope === 'locale'))
|
||||
|
||||
@@ -8,7 +8,7 @@ import type { CountField, CountsResource } from '@/lib/counts'
|
||||
|
||||
export type CountsAxis = { field: string; grain?: string }
|
||||
export type CountsCondition = {
|
||||
field: string; operator: string; value?: string; end?: string; blank?: boolean
|
||||
field: string; operator: string; grain?: string; value?: string; end?: string; blank?: boolean
|
||||
input?: 'single' | 'multiple' | 'list'; values?: (string | number | boolean)[] }
|
||||
export type CountsFieldType = 'string' | 'integer' | 'datetime' | 'enum'
|
||||
| 'json' | 'boolean' | 'interval'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Public URL grammar: space-delimited tokens and indexed scalar fields, never JSON.
|
||||
export type QueryRecord = Record<string, string | number | boolean | null | undefined>
|
||||
const schemas: Record<string, string[]> = {
|
||||
conditions: ['field', 'operator', 'value', 'end', 'blank', 'input', 'values'],
|
||||
conditions: ['field', 'operator', 'value', 'end', 'blank', 'input', 'values', 'grain', 'value_type'],
|
||||
condition_values: ['condition', 'value', 'value_type'],
|
||||
drill: ['field', 'grain', 'value', 'value_type'],
|
||||
tag_refs: ['name', 'tag_id', 'external_tag_id', 'negative', 'missing'],
|
||||
@@ -54,7 +54,8 @@ export const setQueryRecords = (
|
||||
if (!schemas[key]?.includes (field)) continue
|
||||
const name = `${key}.${index}.${field}`
|
||||
if (field === 'value'
|
||||
&& ['drill', 'measures', 'column_order', 'condition_values'].includes (key))
|
||||
&& (['drill', 'measures', 'column_order', 'condition_values'].includes (key)
|
||||
|| (key === 'conditions' && record.operator === 'axis_eq')))
|
||||
params.set (`${key}.${index}.value_type`, value == null ? 'null' : typeof value)
|
||||
if (value == null) continue
|
||||
params.set (name, typeof value === 'boolean'
|
||||
@@ -71,7 +72,8 @@ export const readCountState = <T,> (
|
||||
key: string,
|
||||
fallback: T,
|
||||
): T => {
|
||||
if (!params.has (key)) return fallback
|
||||
if (!params.has (key) && ![...params.keys ()].some (name =>
|
||||
name.startsWith (`${key}.`))) return fallback
|
||||
if (key === 'rows' || key === 'cols')
|
||||
return queryList (params.get (key)).map (token => {
|
||||
const [field, grain] = token.split (':')
|
||||
|
||||
新しいイシューから参照
ユーザーをブロックする