Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions src/components/organisms/DataSearch/ReadingCards.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-explicit-any -- takes candidate specs as `any` and reads only the members it renders, tolerating any that is missing */
'use client';

import { useMemo } from 'react';
Expand All @@ -10,7 +9,7 @@ import Button from '@/components/atoms/Button/Button';
import { isClosestMatch } from '@/lib/search/departures';
import { basisNote, readingOf, readingsSummary } from '@/lib/search/readings';
import { tokenAbout } from '@/lib/search/tokenAbout';
import type { CandidatesPart } from '@/lib/search/types';
import type { CandidatesPart, Spec } from '@/lib/search/types';
import { statVarsUnreadable } from '@/lib/search/view';

/**
Expand All @@ -32,11 +31,11 @@ const ReadingCards = ({
part: CandidatesPart;
// The part's variable text, when the answer has several parts.
prefix: string | null;
onPick: (spec: any) => void;
onPick: (spec: Spec) => void;
// Re-runs the question, for a reading the client could not read.
onRetry: () => void;
}) => {
const specs: any[] = useMemo(() => part.candidates.specs, [part]);
const specs = useMemo(() => part.candidates.specs, [part]);
const readings = useMemo(
() =>
specs.map((spec) => {
Expand Down
9 changes: 4 additions & 5 deletions src/components/organisms/DataSearch/SearchCards.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-explicit-any -- takes specs as `any` and reads only the members it renders, tolerating any that is missing */
'use client';

import classNames from 'classnames';
Expand All @@ -21,12 +20,12 @@ import {
specOrigin,
statVarsUnreadable,
} from '@/lib/search/view';
import { knownPart, type ParsedPart, type Part } from '@/lib/search/types';
import { knownPart, type ParsedPart, type Part, type PartSpec } from '@/lib/search/types';

// A card's meta line, its coverage then its origin (specOrigin beside the
// spec's own sentence, shapeOrigin beside any other title). The line clamps
// at two lines, so the full text goes in the title attribute.
const CardMeta = ({ spec, origin }: { spec: any; origin: string | null }) => {
const CardMeta = ({ spec, origin }: { spec: PartSpec; origin: string | null }) => {
const meta = [coverageSummary(spec), origin].filter(Boolean).join(' · ');

return (
Expand Down Expand Up @@ -97,7 +96,7 @@ const SearchCards = ({
Multiple possible interpretations found. Select the best fit…
</p>
<div className={styles.cards}>
{specs.map((spec: any, index: number) => (
{specs.map((spec, index) => (
<button
key={spec.spec_id}
type="button"
Expand Down Expand Up @@ -206,7 +205,7 @@ const SearchCards = ({
<div className={styles.cardsBlock}>
<p className={styles.cardsTitle}>Largest Subsets</p>
<div className={styles.cards}>
{nearest.map((spec: any, index: number) => {
{nearest.map((spec, index) => {
const unreadable = statVarsUnreadable(spec);

// A shape the client couldn't parse has no title to
Expand Down
4 changes: 2 additions & 2 deletions src/components/organisms/DataSearch/SearchPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-explicit-any -- takes the spec as `any` and reads only the members the panel renders, tolerating any that is missing */
'use client';

import classNames from 'classnames';
Expand All @@ -11,6 +10,7 @@ import { type DatasetDownloaded, useDatasetDownload } from './useDatasetDownload

import Button from '@/components/atoms/Button/Button';
import { usePrefersReducedMotion } from '@/hooks/usePrefersReducedMotion';
import type { PartSpec } from '@/lib/search/types';
import { detailRows, downloadRowCount, formatCount } from '@/lib/search/view';

import { SourceName } from './WhyPanel';
Expand All @@ -24,7 +24,7 @@ const SearchPanel = ({
onStudio,
onDownloadStart,
}: {
spec: any;
spec: PartSpec;
// Says a download may differ from the preview (resultNotes downloadNote).
note?: string | null;
// Mints this result's share links; the Share button is hidden without it.
Expand Down
47 changes: 29 additions & 18 deletions src/components/organisms/DataSearch/SearchSentence.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-explicit-any -- takes specs, slots and options of either picker shape as `any` and reads only the members it renders, tolerating any that is missing */
'use client';

import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
Expand Down Expand Up @@ -73,8 +72,10 @@ import {
type NoDataOption,
type ParsedPart,
type PartSpec,
type Resolution,
type RoleAxis,
type SentenceToken,
type Slot,
type SlotOption,
type SpecAlternativeMeasure,
} from '@/lib/search/types';
Expand Down Expand Up @@ -251,9 +252,9 @@ const MethodChoices = ({
* already scoped to its own level.
*/
const renderLevelOptions = (
slot: any,
slot: Slot,
options: readonly SlotOption[],
onSelect: (binding: any) => void,
onSelect: (binding: Slot['binding']) => void,
) => {
const optionItem = (option: SlotOption, direction?: 'up' | 'down') => (
<DropdownMenu.Item
Expand Down Expand Up @@ -321,7 +322,11 @@ const renderLevelOptions = (
* total, so the hint never implies a count. Each option carries the
* graph's definition behind an info icon.
*/
const renderOptionMenu = (slot: any, entry: SlotOptionsEntry, onSelect: (binding: any) => void) => {
const renderOptionMenu = (
slot: Slot,
entry: SlotOptionsEntry,
onSelect: (binding: Slot['binding']) => void,
) => {
const { options, truncated } = entry;

return (
Expand All @@ -345,12 +350,12 @@ const FlatOptionList = ({
options,
onSelect,
}: {
slot: any;
slot: Slot;
options: SlotOption[];
onSelect: (binding: any) => void;
onSelect: (binding: Slot['binding']) => void;
}) => {
const [filter, setFilter] = useState('');
const boundDcid = slot.binding?.value?.ref?.ref;
const boundDcid = slot.binding.kind === 'value' ? slot.binding.value.ref?.ref : undefined;
const { current, rest } = splitCurrentPick(options, boundDcid);
const showFilter = shouldShowOptionFilter(rest.length);
const shown = showFilter
Expand Down Expand Up @@ -405,7 +410,7 @@ const FlatOptionList = ({
};

type SearchSentenceProps = {
response: any;
response: Resolution | null;
// Every part, in query order — the token routing target for a
// part-indexed slot, and the source of the definite/candidates/no_data/
// unsupported status a marked phrase reads.
Expand All @@ -427,21 +432,26 @@ type SearchSentenceProps = {
baseStreamOpen: boolean;
onEditSlot: (
partIndex: number,
spec: any,
spec: PartSpec,
slotIndex: number,
binding: any,
binding: Slot['binding'],
entityRole?: EntityRoleKey,
) => void;
onEditEntity: (partIndex: number, spec: any, role: RoleAxis, dcids: string[] | null) => void;
onEditWindow: (partIndex: number, spec: any, window: WindowApplyValue) => void;
onEditEntity: (
partIndex: number,
spec: PartSpec,
role: RoleAxis,
dcids: string[] | null,
) => void;
onEditWindow: (partIndex: number, spec: PartSpec, window: WindowApplyValue) => void;
// An alternative measure, or a related one from the variable's group,
// on each part a pick switches (several for a shared unit token).
onEditMeasure: (picks: readonly MeasurePick[]) => void;
// A facet axis bound or dropped on one part (the unit's currency and
// price basis).
onEditFacet: <A extends IdentityFacetAxis>(
partIndex: number,
spec: any,
spec: PartSpec,
axis: A,
binding: IdentityFacetBinding[A] | null,
) => void;
Expand Down Expand Up @@ -531,7 +541,7 @@ const placeField = (token: SentenceToken): string =>

/** The field an option-list slot edits ("Sector"), for its menu title and
* its trigger's accessible name. */
const slotField = (slot: any): string => slot.key.label ?? 'Value';
const slotField = (slot: Slot): string => slot.key.label ?? 'Value';

// The ref a token's menu changes when it edits the one binding the token
// carries: its binding_ref, or none.
Expand Down Expand Up @@ -666,8 +676,9 @@ const EntityOptionRows = ({
/** The composed sentence as displayed, notes left out. It names the hero
* <h1>, which would otherwise take its name from each slot trigger's longer
* accessible name. */
export const sentenceHeadingText = (response: any): string =>
planSentenceText(response?.sentence_plan);
export const sentenceHeadingText = (
response: Pick<Resolution, 'sentence_plan'> | null | undefined,
): string => planSentenceText(response?.sentence_plan);

/** The space between two heading blocks of a plan of separate sentences. */
const HEADING_JOIN: SentenceToken = { kind: 'text', text: ' ', segment: 'heading' };
Expand Down Expand Up @@ -1443,7 +1454,7 @@ export const SearchSentenceHeading = ({
}

const slot = slots[slotIndex];
const onSelect = (binding: any) =>
const onSelect = (binding: Slot['binding']) =>
onEditSlot(partIndex, spec, slotIndex, binding, token.role ?? 'observationAbout');
// A level-scoped constraint slot (relation populated) skips the
// free-text escape hatch renderOptionMenu's flat branch offers —
Expand Down Expand Up @@ -2232,7 +2243,7 @@ const RefineEntry = ({
}

const { slot, slotIndex, entry, current } = item;
const onSelect = (binding: any) => onEditSlot(part.index, spec, slotIndex, binding);
const onSelect = (binding: Slot['binding']) => onEditSlot(part.index, spec, slotIndex, binding);
const [only] = entry.options;

// An unbound slot with one option: its row picks it.
Expand Down
5 changes: 2 additions & 3 deletions src/components/organisms/DataSearch/SearchTable.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-explicit-any -- takes the spec as `any` and reads only the members the table renders, tolerating any that is missing */
'use client';

import classNames from 'classnames';
Expand All @@ -24,12 +23,12 @@ import {
resolveObservationsOmission,
} from '@/lib/search/view';
import { tableCaptionNotes } from '@/lib/search/resultNotes';
import type { Warning } from '@/lib/search/types';
import type { PartSpec, Warning } from '@/lib/search/types';

type TablePart = {
index: number;
variableText: string | null;
spec: any;
spec: PartSpec;
warnings?: Pick<Warning, 'code' | 'message' | 'params'>[];
};

Expand Down
5 changes: 2 additions & 3 deletions src/components/organisms/DataSearch/UnitPicker.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-explicit-any -- reads the flattened wire Spec */
'use client';

import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
Expand All @@ -10,7 +9,7 @@ import { OptionRow, stopMenuFieldTypeahead } from './SlotMenu';

import Button from '@/components/atoms/Button/Button';
import { currencyName } from '@/lib/search/tokenAbout';
import type { IdentityUnitRequest, UnitConversion } from '@/lib/search/types';
import type { IdentityUnitRequest, PartSpec, UnitConversion } from '@/lib/search/types';
import {
currencyMatches,
currencyRequest,
Expand Down Expand Up @@ -44,7 +43,7 @@ export const UnitPicker = ({
conversion,
onPick,
}: {
spec: any;
spec: PartSpec;
conversion: UnitConversion;
onPick: (request: IdentityUnitRequest) => void;
}) => {
Expand Down
4 changes: 2 additions & 2 deletions src/components/organisms/DataSearch/WhyPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Button from '@/components/atoms/Button/Button';
import Icon from '@/components/atoms/Icon/Icon';
import SourceLink from '@/components/atoms/SourceLink/SourceLink';
import { aboutAnswerNotes, type AboutAnswerNotes } from '@/lib/search/resultNotes';
import type { Assumption, Warning } from '@/lib/search/types';
import type { Assumption, PartSpec, Warning } from '@/lib/search/types';
import {
buildWhySummary,
formatCount,
Expand Down Expand Up @@ -149,7 +149,7 @@ const NoteGroup = ({ title, notes }: { title: string; notes: string[] }) =>
export type AboutPart = {
index: number;
variableText: string | null;
spec: Parameters<typeof buildWhySummary>[0];
spec: PartSpec;
warnings?: Warning[];
assumptions?: Assumption[];
};
Expand Down
Loading
Loading