diff --git a/src/app/core/dashboard/characteristics/characteristics.tsx b/src/app/core/dashboard/characteristics/characteristics.tsx index 426fc54..edc332b 100644 --- a/src/app/core/dashboard/characteristics/characteristics.tsx +++ b/src/app/core/dashboard/characteristics/characteristics.tsx @@ -4,10 +4,10 @@ import Box from '@mui/joy/Box'; import { DEFAULT_PATHNAME } from '@/constants'; import { Heatmap } from '@/components/charts/heatmap'; -import { HeadField, PatentSearchArgs } from '@/types'; +import { HeadField, PatentCharacteristic, PatentSearchArgs } from '@/types'; import { fetchPatentCharacteristics } from './actions'; -import { PatentCharacteristicsControl } from './control'; +import { PatentCharacteristicsControl, getClickUrl } from './control'; const CharacteristicsInner = async ({ pathname = DEFAULT_PATHNAME, @@ -17,12 +17,11 @@ const CharacteristicsInner = async ({ const data = await fetchPatentCharacteristics(args); return ( - + getClickUrl={getClickUrl} data={data} pathname={pathname} - tooltipFields={['documents']} + tooltipFields={['head', 'concept', 'documents']} xField="head" yField="concept" /> diff --git a/src/app/core/dashboard/characteristics/control.tsx b/src/app/core/dashboard/characteristics/control.tsx index e5fbf5a..e3b0b83 100644 --- a/src/app/core/dashboard/characteristics/control.tsx +++ b/src/app/core/dashboard/characteristics/control.tsx @@ -6,14 +6,15 @@ import Typography from '@mui/joy/Typography'; import { Section } from '@/components/layout/section'; import { Select } from '@/components/input'; import { useNavigation } from '@/hooks/navigation'; -import { HeadField, PatentSearchArgs } from '@/types'; +import { HeadField, PatentCharacteristic, PatentSearchArgs } from '@/types'; +import { DEFAULT_PATHNAME } from '@/constants'; export const PatentCharacteristicsControl = ({ headField, terms, children, }: PatentSearchArgs & { children: ReactNode; headField: HeadField }) => { - const { params, navigate } = useNavigation(); + const { setParam } = useNavigation(); return ( <> @@ -31,11 +32,7 @@ export const PatentCharacteristicsControl = ({ label="Dimension" onChange={(e: unknown, value: HeadField | null) => { if (value) { - const newParams = new URLSearchParams(params); - newParams.set('headField', value); - navigate(`?${newParams.toString()}`, { - scroll: false, - }); + setParam('headField', value); } }} options={['priority_date', 'id']} @@ -46,3 +43,12 @@ export const PatentCharacteristicsControl = ({ ); }; + +export const getClickUrl = ( + object: PatentCharacteristic, + pathname: string = DEFAULT_PATHNAME +) => { + const ids = object.documents?.join(';'); + const term = `${object.concept} x ${object.head}`; + return `${pathname}/patents?ids=${ids}&terms=${term}`; +}; diff --git a/src/app/core/dashboard/content.tsx b/src/app/core/dashboard/content.tsx index 4693b1d..6b3477b 100644 --- a/src/app/core/dashboard/content.tsx +++ b/src/app/core/dashboard/content.tsx @@ -16,12 +16,16 @@ import { PatentCharacteristics } from './characteristics'; import { OverTime } from './over-time'; import { Summary } from './summary'; -export type ContentArgs = PatentSearchArgs & { headField: HeadField }; +export type ContentArgs = PatentSearchArgs & { + headField: HeadField; + tab: string; +}; -export const Content = (args: ContentArgs) => { +export const Content = ({ tab, ...args }: ContentArgs) => { try { const tabs = [ { + id: 'assets', label: 'Assets', panel: ( }> @@ -30,6 +34,7 @@ export const Content = (args: ContentArgs) => { ), }, { + id: 'summary', label: 'Summary', panel: ( }> @@ -38,6 +43,7 @@ export const Content = (args: ContentArgs) => { ), }, { + id: 'over-time', label: 'Over Time', panel: ( }> @@ -46,6 +52,7 @@ export const Content = (args: ContentArgs) => { ), }, { + id: 'characteristics', label: 'Characteristics', panel: ( }> @@ -56,7 +63,7 @@ export const Content = (args: ContentArgs) => { ]; return ( - + ); } catch (e) { diff --git a/src/app/core/dashboard/page.tsx b/src/app/core/dashboard/page.tsx index 4c3e83d..8c17363 100644 --- a/src/app/core/dashboard/page.tsx +++ b/src/app/core/dashboard/page.tsx @@ -25,6 +25,7 @@ const Page = ({ searchParams }: { searchParams: Record }) => { ? parseInt(searchParams.endYear, 10) : undefined; const headField = (searchParams.headField as HeadField) || 'priority_date'; + const { tab } = searchParams; return ( <> @@ -57,6 +58,7 @@ const Page = ({ searchParams }: { searchParams: Record }) => { headField={headField} queryType={queryType} startYear={startYear} + tab={tab} terms={terms || []} /> diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 00ee8cc..eebbc01 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,4 +1,5 @@ import type { Metadata } from 'next'; +import { Suspense } from 'react'; import { Mulish } from 'next/font/google'; import MuiXLicense from '@/components/data/mui-license'; @@ -26,7 +27,9 @@ const RootLayout = ({ > - {children} + + {children} + diff --git a/src/components/charts/heatmap.tsx b/src/components/charts/heatmap.tsx index 45856ce..81f4ce9 100644 --- a/src/components/charts/heatmap.tsx +++ b/src/components/charts/heatmap.tsx @@ -4,8 +4,6 @@ import { useRouter } from 'next/navigation'; import Typography from '@mui/joy/Typography'; import { Vega, VisualizationSpec } from 'react-vega'; -import { PatentCharacteristics } from '@/types'; - import { BaseChartProps } from './types'; type HeadmapSpecProps = { @@ -17,10 +15,9 @@ type HeadmapSpecProps = { yFieldTitle?: string; }; -type HeatmapProps = BaseChartProps & { - clickBaseUrl?: string; // TODO: both or neither with clickField - clickField?: string; - data: PatentCharacteristics; // TODO: make generic +type HeatmapProps
> = BaseChartProps & { + data: DT[]; + getClickUrl?: (obj: DT) => string; } & HeadmapSpecProps; const getSpec: (props: HeadmapSpecProps) => VisualizationSpec = ({ @@ -95,27 +92,26 @@ const getSpec: (props: HeadmapSpecProps) => VisualizationSpec = ({ /** * Graph chart */ -export const Heatmap = ({ +export const Heatmap =
>({ data, - clickBaseUrl, - clickField, colorField, + getClickUrl, tooltipFields = [], title, xField, yField, xFieldTitle = '', yFieldTitle = '', -}: HeatmapProps): JSX.Element => { +}: HeatmapProps
): JSX.Element => { const router = useRouter(); const signalListeners = { select: (_: unknown, value: unknown) => { - if (!clickField || typeof value !== 'object') { + if (!getClickUrl || typeof value !== 'object') { return; } - const obj = value as Record; - const urlParams = (obj[clickField] as string[]).join(';'); - router.push(`${clickBaseUrl}${urlParams}`); + const obj = value as DT; + const url = getClickUrl(obj); + router.push(url); }, }; diff --git a/src/components/composite/search/search-bar.tsx b/src/components/composite/search/search-bar.tsx index 4eeb7a7..ec6c6fd 100644 --- a/src/components/composite/search/search-bar.tsx +++ b/src/components/composite/search/search-bar.tsx @@ -18,7 +18,7 @@ import { FetchAutocompletions } from './types'; */ export const SearchBar = ({ endYear = 2024, - exemplarPatents, + // exemplarPatents, fetchAutocompletions, queryType, startYear = 2014, @@ -29,9 +29,9 @@ export const SearchBar = ({ const { navigate } = useNavigation(); const pathname = usePathname(); const [newTerms, setTerms] = useState(terms); - const [newExemplarPatents, setExemplarPatents] = useState( - exemplarPatents || null - ); + // const [newExemplarPatents, setExemplarPatents] = useState( + // exemplarPatents || null + // ); const [newQueryType, setQueryType] = useState( queryType || null ); @@ -72,6 +72,7 @@ export const SearchBar = ({ minDistance={2} max={2025} size="lg" + sx={{ mr: 3 }} valueLabelDisplay="on" /> @@ -90,7 +91,7 @@ export const SearchBar = ({ /> - + {/* isMultiple @@ -116,7 +117,7 @@ export const SearchBar = ({ variant="soft" /> - + */}