Merge branch 't3code/expand-research-management-plan'
# Conflicts: # app/analysis/page.tsx # app/watchlist/page.tsx # components/shell/app-shell.tsx # lib/api.ts # lib/query/options.ts # lib/server/api/app.ts # lib/server/db/index.test.ts # lib/server/db/index.ts # lib/server/db/schema.ts # lib/server/repos/research-journal.ts # lib/types.ts
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import type { LucideIcon } from 'lucide-react';
|
||||
import { Activity, BookOpenText, ChartCandlestick, Eye, Landmark, LineChart, LogOut, Menu, Search } from 'lucide-react';
|
||||
import { Activity, BarChart3, BookOpenText, ChartCandlestick, Eye, Landmark, LineChart, LogOut, Menu, NotebookTabs, Search } from 'lucide-react';
|
||||
import Link from 'next/link';
|
||||
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
@@ -11,6 +11,7 @@ import { TaskDetailModal } from '@/components/notifications/task-detail-modal';
|
||||
import { TaskNotificationsTrigger } from '@/components/notifications/task-notifications-trigger';
|
||||
import {
|
||||
companyAnalysisQueryOptions,
|
||||
companyFinancialStatementsQueryOptions,
|
||||
filingsQueryOptions,
|
||||
holdingsQueryOptions,
|
||||
latestPortfolioInsightQueryOptions,
|
||||
@@ -18,6 +19,7 @@ import {
|
||||
recentTasksQueryOptions,
|
||||
watchlistQueryOptions
|
||||
} from '@/lib/query/options';
|
||||
import { buildGraphingHref } from '@/lib/graphing/catalog';
|
||||
import type { ActiveContext, NavGroup, NavItem } from '@/lib/types';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { useTaskNotificationsCenter } from '@/hooks/use-task-notifications-center';
|
||||
@@ -56,6 +58,26 @@ const NAV_ITEMS: NavConfigItem[] = [
|
||||
preserveTicker: true,
|
||||
mobilePrimary: true
|
||||
},
|
||||
{
|
||||
id: 'research',
|
||||
href: '/research',
|
||||
label: 'Research',
|
||||
icon: NotebookTabs,
|
||||
group: 'research',
|
||||
matchMode: 'exact',
|
||||
preserveTicker: true,
|
||||
mobilePrimary: true
|
||||
},
|
||||
{
|
||||
id: 'graphing',
|
||||
href: '/graphing',
|
||||
label: 'Graphing',
|
||||
icon: BarChart3,
|
||||
group: 'research',
|
||||
matchMode: 'exact',
|
||||
preserveTicker: true,
|
||||
mobilePrimary: false
|
||||
},
|
||||
{
|
||||
id: 'financials',
|
||||
href: '/financials',
|
||||
@@ -127,6 +149,10 @@ function toTickerHref(baseHref: string, activeTicker: string | null) {
|
||||
}
|
||||
|
||||
function resolveNavHref(item: NavItem, context: ActiveContext) {
|
||||
if (item.href === '/graphing') {
|
||||
return buildGraphingHref(context.activeTicker);
|
||||
}
|
||||
|
||||
if (!item.preserveTicker) {
|
||||
return item.href;
|
||||
}
|
||||
@@ -144,6 +170,8 @@ function isItemActive(item: NavItem, pathname: string) {
|
||||
|
||||
function buildDefaultBreadcrumbs(pathname: string, activeTicker: string | null) {
|
||||
const analysisHref = toTickerHref('/analysis', activeTicker);
|
||||
const researchHref = toTickerHref('/research', activeTicker);
|
||||
const graphingHref = buildGraphingHref(activeTicker);
|
||||
const financialsHref = toTickerHref('/financials', activeTicker);
|
||||
const filingsHref = toTickerHref('/filings', activeTicker);
|
||||
|
||||
@@ -163,6 +191,13 @@ function buildDefaultBreadcrumbs(pathname: string, activeTicker: string | null)
|
||||
return [{ label: 'Analysis' }];
|
||||
}
|
||||
|
||||
if (pathname.startsWith('/research')) {
|
||||
return [
|
||||
{ label: 'Analysis', href: analysisHref },
|
||||
{ label: 'Research', href: researchHref }
|
||||
];
|
||||
}
|
||||
|
||||
if (pathname.startsWith('/financials')) {
|
||||
return [
|
||||
{ label: 'Analysis', href: analysisHref },
|
||||
@@ -170,6 +205,14 @@ function buildDefaultBreadcrumbs(pathname: string, activeTicker: string | null)
|
||||
];
|
||||
}
|
||||
|
||||
if (pathname.startsWith('/graphing')) {
|
||||
return [
|
||||
{ label: 'Analysis', href: analysisHref },
|
||||
{ label: 'Graphing', href: graphingHref },
|
||||
{ label: activeTicker ?? 'Compare Set' }
|
||||
];
|
||||
}
|
||||
|
||||
if (pathname.startsWith('/filings')) {
|
||||
return [
|
||||
{ label: 'Analysis', href: analysisHref },
|
||||
@@ -298,6 +341,20 @@ export function AppShell({ title, subtitle, actions, activeTicker, breadcrumbs,
|
||||
return;
|
||||
}
|
||||
|
||||
if (href.startsWith('/graphing')) {
|
||||
if (context.activeTicker) {
|
||||
void queryClient.prefetchQuery(companyFinancialStatementsQueryOptions({
|
||||
ticker: context.activeTicker,
|
||||
surfaceKind: 'income_statement',
|
||||
cadence: 'annual',
|
||||
includeDimensions: false,
|
||||
includeFacts: false,
|
||||
limit: 16
|
||||
}));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (href.startsWith('/filings')) {
|
||||
void queryClient.prefetchQuery(filingsQueryOptions({
|
||||
ticker: context.activeTicker ?? undefined,
|
||||
@@ -341,7 +398,7 @@ export function AppShell({ title, subtitle, actions, activeTicker, breadcrumbs,
|
||||
};
|
||||
|
||||
const runPrefetch = () => {
|
||||
const prioritized = navEntries.filter((entry) => entry.id === 'analysis' || entry.id === 'filings' || entry.id === 'portfolio');
|
||||
const prioritized = navEntries.filter((entry) => entry.id === 'analysis' || entry.id === 'graphing' || entry.id === 'filings' || entry.id === 'portfolio');
|
||||
for (const entry of prioritized) {
|
||||
prefetchForHref(entry.href);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user