diff --git a/backend/app/services/counts_population.rb b/backend/app/services/counts_population.rb index e71ed48..6c7e4cb 100644 --- a/backend/app/services/counts_population.rb +++ b/backend/app/services/counts_population.rb @@ -195,9 +195,10 @@ class CountsPopulation end return unless params['tags'].present? - refs = PostTagSearch.parse_references(params, params['tags'].split) raw = params['tags'] - literals = PostTagSearch.literals(nil, raw, references: refs) + tokens = raw.split.reject { _1.downcase == 'type:or' } + refs = PostTagSearch.parse_references(params, tokens, partial: true) + literals = PostTagSearch.literals(nil, tokens.join(' '), references: refs) predicates = literals.map do |literal| reference = literal[:reference] expression = if reference diff --git a/backend/app/services/counts_table_query.rb b/backend/app/services/counts_table_query.rb index bf48084..ceb29fe 100644 --- a/backend/app/services/counts_table_query.rb +++ b/backend/app/services/counts_table_query.rb @@ -57,7 +57,7 @@ class CountsTableQuery end def metadata - { population_count: nil, population_count_computed: false, + { condition_labels: condition_labels, population_count: nil, population_count_computed: false, excluded_count: nil, excluded_count_scope: 'current_query', population_count_scope: 'all_recorded_versions', page:, limit:, execution_at: population.at.iso8601(6), at: @params['at'].presence, @@ -378,6 +378,21 @@ class CountsTableQuery end end + def condition_labels + entries = QueryState.records(@params, 'conditions').select { _1['operator'] == 'axis_eq' } + entries += QueryState.records(@params, 'drill') + entries.group_by { _1['field'] }.to_h do |field, conditions| + values = conditions.map { _1['value'] }.compact.uniq + labels = case field + when 'tags' then tag_labels(values) + when 'user' + User.where(id: values).pluck(:id, :name).to_h.transform_keys(&:to_s) + else {} + end + [field, labels] + end + end + def axis_labels(records, column_values) result = {} @axis_names = {} diff --git a/backend/app/services/post_tag_search.rb b/backend/app/services/post_tag_search.rb index cbff09f..ce3ae88 100644 --- a/backend/app/services/post_tag_search.rb +++ b/backend/app/services/post_tag_search.rb @@ -1,6 +1,6 @@ # Shared literal parsing and reference resolution for current and snapshot post search. class PostTagSearch - def self.parse_references(raw, literals) + def self.parse_references(raw, literals, partial: false) return nil unless raw.key?('tag_refs') references = QueryState.records(raw, 'tag_refs') @@ -15,6 +15,16 @@ class PostTagSearch end raise ArgumentError unless valid + if partial + remaining = references.dup + result = literals.map do |literal| + index = remaining.index { _1['name'] == literal } + index ? remaining.delete_at(index) : nil + end + raise ArgumentError if remaining.any? + + return result + end references.map { _1['name'] } == literals ? references : nil end diff --git a/frontend/src/components/counts/CountsAdditionalConditions.tsx b/frontend/src/components/counts/CountsAdditionalConditions.tsx index 5048195..aa170cf 100644 --- a/frontend/src/components/counts/CountsAdditionalConditions.tsx +++ b/frontend/src/components/counts/CountsAdditionalConditions.tsx @@ -15,6 +15,7 @@ import { useUITranslation } from '@/lib/useUITranslation' import { readCountState, encodeCountState } from '@/lib/queryState' +import type { CountsResult } from '@/lib/counts' import type { DialogueFormControls } from '@/lib/dialogues/useDialogue' import type { CountsCondition, CountsDefinition } from '@/lib/countsDefinitions' @@ -93,7 +94,8 @@ const ConditionEditor = ( } -const CountsAdditionalConditions = ({ params, update }: { +const CountsAdditionalConditions = ({ params, update, conditionLabels }: { + conditionLabels?: CountsResult['conditionLabels'] params: URLSearchParams update: (key: string, value: string) => void }, ) => { @@ -162,7 +164,7 @@ const CountsAdditionalConditions = ({ params, update }: { {countsAxisLabel (condition, definition, locale).text} {label ('operatorSymbols.eq')} {countsConditionValue (condition.value, condition, locale, - params.get ('timezone') ?? 'UTC')} + params.get ('timezone') ?? 'UTC', conditionLabels)}