diff --git a/web/biome.json b/web/biome.json index c49f63244..e1eee3d77 100644 --- a/web/biome.json +++ b/web/biome.json @@ -30,7 +30,7 @@ "lineWidth": 100 }, "organizeImports": { - "enabled": true + "enabled": false }, "linter": { "enabled": true, diff --git a/web/next.config.mjs b/web/next.config.mjs index a50cceef4..60dc09911 100644 --- a/web/next.config.mjs +++ b/web/next.config.mjs @@ -60,6 +60,10 @@ const nextConfig = { eslint: { ignoreDuringBuilds: true }, + // Disable TypeScript type checking during builds + typescript: { + ignoreBuildErrors: true + }, sassOptions: { includePaths: [path.join(__dirname, 'styles')], silenceDeprecations: ['legacy-js-api'] diff --git a/web/package.json b/web/package.json index 565af09c2..3412bc2f5 100644 --- a/web/package.json +++ b/web/package.json @@ -4,14 +4,16 @@ "private": true, "scripts": { "dev": "next dev --turbo", - "build": "npm run lint:biome && next build", + "build": "npm run lint:biome && npm run typecheck && next build", "build:skip-lint": "next build", "start": "next start", - "lint": "npx biome check && next lint", + "lint": "npx biome check && npm run typecheck && next lint", "lint:biome": "npx biome check", "lint:eslint": "next lint", - "lint:ci": "npx biome check", + "lint:ci": "npx biome check && npm run typecheck", "lint:fix": "npx biome check --write", + "typecheck": "tsc --noEmit", + "typecheck:watch": "tsc --noEmit --watch", "test": "vitest", "test:watch": "vitest --watch", "test:ui": "vitest --ui", @@ -80,7 +82,7 @@ "monaco-sql-languages": "^0.15.0", "monaco-yaml": "^5.4.0", "mutative": "^1.2.0", - "next": "14.2.28", + "next": "14.2.29", "next-themes": "^0.4.6", "papaparse": "^5.5.3", "pluralize": "^8.0.0", diff --git a/web/src/components/ui/charts/BusterChartJS/core/plugins/chartjs-plugin-trendlines/canSupportTrendline.test.ts b/web/src/components/ui/charts/BusterChartJS/core/plugins/chartjs-plugin-trendlines/canSupportTrendline.test.ts index f923fca4b..8811a5812 100644 --- a/web/src/components/ui/charts/BusterChartJS/core/plugins/chartjs-plugin-trendlines/canSupportTrendline.test.ts +++ b/web/src/components/ui/charts/BusterChartJS/core/plugins/chartjs-plugin-trendlines/canSupportTrendline.test.ts @@ -9,7 +9,7 @@ vi.mock('@/lib/messages', () => ({ isNumericColumnType: vi.fn() })); -const mockedIsNumericColumnType = isNumericColumnType as anyedFunction; +const mockedIsNumericColumnType = vi.mocked(isNumericColumnType); describe('canSupportTrendlineRecord', () => { const trendlineTypes: Trendline['type'][] = [ diff --git a/web/src/components/ui/charts/BusterChartJS/hooks/useOptions/axisHooks/useXAxisTitle.test.ts b/web/src/components/ui/charts/BusterChartJS/hooks/useOptions/axisHooks/useXAxisTitle.test.ts index 8f7016614..03bd41e8c 100644 --- a/web/src/components/ui/charts/BusterChartJS/hooks/useOptions/axisHooks/useXAxisTitle.test.ts +++ b/web/src/components/ui/charts/BusterChartJS/hooks/useOptions/axisHooks/useXAxisTitle.test.ts @@ -44,8 +44,8 @@ describe('useXAxisTitle', () => { beforeEach(() => { vi.clearAllMocks(); // Default mock implementations - (formatLabel as any).mockImplementation((value) => `formatted_${value}`); - (truncateWithEllipsis as any).mockImplementation((text) => text); + (formatLabel as any).mockImplementation((value: string) => `formatted_${value}`); + (truncateWithEllipsis as any).mockImplementation((text: string) => text); }); it('should return empty string when chart type is not supported', () => { diff --git a/web/src/components/ui/charts/BusterChartJS/hooks/useOptions/axisHooks/useY2AxisTitle.test.ts b/web/src/components/ui/charts/BusterChartJS/hooks/useOptions/axisHooks/useY2AxisTitle.test.ts index f89e7536e..6310dd9a7 100644 --- a/web/src/components/ui/charts/BusterChartJS/hooks/useOptions/axisHooks/useY2AxisTitle.test.ts +++ b/web/src/components/ui/charts/BusterChartJS/hooks/useOptions/axisHooks/useY2AxisTitle.test.ts @@ -42,8 +42,8 @@ describe('useY2AxisTitle', () => { beforeEach(() => { vi.clearAllMocks(); // Default mock implementations - (formatLabel as any).mockImplementation((value) => `formatted_${value}`); - (truncateWithEllipsis as any).mockImplementation((text) => text); + (formatLabel as any).mockImplementation((value: string) => `formatted_${value}`); + (truncateWithEllipsis as any).mockImplementation((text: string) => text); }); it('should return empty string when chart type is not supported', () => { diff --git a/web/src/components/ui/charts/BusterChartJS/hooks/useOptions/axisHooks/useYAxisTitle.test.ts b/web/src/components/ui/charts/BusterChartJS/hooks/useOptions/axisHooks/useYAxisTitle.test.ts index e7b97d97c..479a50ed2 100644 --- a/web/src/components/ui/charts/BusterChartJS/hooks/useOptions/axisHooks/useYAxisTitle.test.ts +++ b/web/src/components/ui/charts/BusterChartJS/hooks/useOptions/axisHooks/useYAxisTitle.test.ts @@ -48,8 +48,8 @@ describe('useYAxisTitle', () => { beforeEach(() => { vi.clearAllMocks(); // Default mock implementations - (formatLabel as any).mockImplementation((value) => `formatted_${value}`); - (truncateWithEllipsis as any).mockImplementation((text) => text); + (formatLabel as any).mockImplementation((value: string) => `formatted_${value}`); + (truncateWithEllipsis as any).mockImplementation((text: string) => text); }); it('should return empty string when chart type is not supported', () => { diff --git a/web/src/components/ui/charts/BusterChartJS/hooks/useSeriesOptions/barSeriesBuilder.test.ts b/web/src/components/ui/charts/BusterChartJS/hooks/useSeriesOptions/barSeriesBuilder.test.ts index eaa219bd2..32af7ff6c 100644 --- a/web/src/components/ui/charts/BusterChartJS/hooks/useSeriesOptions/barSeriesBuilder.test.ts +++ b/web/src/components/ui/charts/BusterChartJS/hooks/useSeriesOptions/barSeriesBuilder.test.ts @@ -52,11 +52,10 @@ describe('barSeriesBuilder', () => { yAxisKeys: ['sales'], y2AxisKeys: [], xAxisKeys: ['date'], - categoryKeys: [], + trendlines: [], sizeOptions: null, scatterDotSize: [5, 5], - lineGroupType: null, - selectedChartType: ChartType.Bar + lineGroupType: null }; // Act @@ -143,11 +142,10 @@ describe('barSeriesBuilder', () => { yAxisKeys: ['sales2022', 'sales2023'], y2AxisKeys: [], xAxisKeys: ['quarter'], - categoryKeys: [], + trendlines: [], sizeOptions: null, scatterDotSize: [5, 5], - lineGroupType: null, - selectedChartType: ChartType.Bar + lineGroupType: null }; // Act @@ -220,11 +218,10 @@ describe('barSeriesBuilder', () => { yAxisKeys: ['marketShare'], y2AxisKeys: [], xAxisKeys: ['product'], - categoryKeys: [], sizeOptions: null, scatterDotSize: [5, 5], lineGroupType: null, - selectedChartType: ChartType.Bar + trendlines: [] }; // Act diff --git a/web/src/components/ui/charts/BusterChartJS/hooks/useSeriesOptions/comboSeriesBuilder.test.ts b/web/src/components/ui/charts/BusterChartJS/hooks/useSeriesOptions/comboSeriesBuilder.test.ts index e9ea77d9d..6483162e8 100644 --- a/web/src/components/ui/charts/BusterChartJS/hooks/useSeriesOptions/comboSeriesBuilder.test.ts +++ b/web/src/components/ui/charts/BusterChartJS/hooks/useSeriesOptions/comboSeriesBuilder.test.ts @@ -44,7 +44,8 @@ describe('comboSeriesBuilder_data', () => { scatterDotSize: [5, 10] as [number, number], barShowTotalAtTop: false, yAxisKeys: ['metric1'], - y2AxisKeys: ['metric2'] + y2AxisKeys: ['metric2'], + trendlines: [] }; const result = comboSeriesBuilder_data(props); @@ -82,7 +83,8 @@ describe('comboSeriesBuilder_data', () => { scatterDotSize: [5, 10] as [number, number], barShowTotalAtTop: false, yAxisKeys: ['metric1'], - y2AxisKeys: [] + y2AxisKeys: [], + trendlines: [] }; const result = comboSeriesBuilder_data(props); diff --git a/web/src/components/ui/charts/BusterChartJS/hooks/useSeriesOptions/lineSeriesBuilder.test.ts b/web/src/components/ui/charts/BusterChartJS/hooks/useSeriesOptions/lineSeriesBuilder.test.ts index 788ce7b15..d6df9c6a4 100644 --- a/web/src/components/ui/charts/BusterChartJS/hooks/useSeriesOptions/lineSeriesBuilder.test.ts +++ b/web/src/components/ui/charts/BusterChartJS/hooks/useSeriesOptions/lineSeriesBuilder.test.ts @@ -121,6 +121,7 @@ describe('lineSeriesBuilder', () => { xAxisKeys: ['category'] as ChartEncodes['x'], lineGroupType: undefined, index: 0, + trendlines: [], dataset: { id: 'm1', axisType: 'y' as const, diff --git a/web/src/context/Assets/useGetFileLink.test.tsx b/web/src/context/Assets/useGetFileLink.test.tsx index 6eacf47c3..35a835483 100644 --- a/web/src/context/Assets/useGetFileLink.test.tsx +++ b/web/src/context/Assets/useGetFileLink.test.tsx @@ -25,7 +25,7 @@ describe('useGetFileLink', () => { vi.clearAllMocks(); // Mock useChatLayoutContextSelector to return our test values - (useChatLayoutContextSelector as any).mockImplementation((selector) => { + (useChatLayoutContextSelector as any).mockImplementation((selector: any) => { const contextValues = { metricVersionNumber: mockMetricVersionNumber, dashboardVersionNumber: mockDashboardVersionNumber, @@ -38,7 +38,12 @@ describe('useGetFileLink', () => { // Mock assetParamsToRoute to return predictable values for testing (assetParamsToRoute as any).mockImplementation( - ({ assetId, type, versionNumber, secondaryView }) => { + ({ + assetId, + type, + versionNumber, + secondaryView + }: { assetId: string; type: string; versionNumber: number; secondaryView: string }) => { if (type === 'metric') { return `/metrics/${assetId}${versionNumber ? `/v${versionNumber}` : ''}${secondaryView ? `/${secondaryView}` : ''}`; } diff --git a/web/src/layouts/ChatLayout/ChatContainer/ChatContent/ChatInput/useChatInputFlow.test.tsx b/web/src/layouts/ChatLayout/ChatContainer/ChatContent/ChatInput/useChatInputFlow.test.tsx index 2ec13b680..20ed3ac24 100644 --- a/web/src/layouts/ChatLayout/ChatContainer/ChatContent/ChatInput/useChatInputFlow.test.tsx +++ b/web/src/layouts/ChatLayout/ChatContainer/ChatContent/ChatInput/useChatInputFlow.test.tsx @@ -30,7 +30,7 @@ describe('useChatInputFlow', () => { beforeEach(() => { vi.clearAllMocks(); - (useBusterNewChatContextSelector as any).mockImplementation((selector) => { + (useBusterNewChatContextSelector as any).mockImplementation((selector: any) => { const state = { onStartNewChat: mockOnStartNewChat, onFollowUpChat: mockOnFollowUpChat, @@ -50,7 +50,7 @@ describe('useChatInputFlow', () => { }; it('should handle followup-chat flow', async () => { - (useChatIndividualContextSelector as any).mockImplementation((selector) => { + (useChatIndividualContextSelector as any).mockImplementation((selector: any) => { const state = { hasChat: true, chatId: 'test-chat-id', @@ -75,7 +75,7 @@ describe('useChatInputFlow', () => { }); it('should handle followup-metric flow', async () => { - (useChatIndividualContextSelector as any).mockImplementation((selector) => { + (useChatIndividualContextSelector as any).mockImplementation((selector: any) => { const state = { hasChat: false, chatId: 'test-chat-id', @@ -101,7 +101,7 @@ describe('useChatInputFlow', () => { }); it('should handle followup-dashboard flow', async () => { - (useChatIndividualContextSelector as any).mockImplementation((selector) => { + (useChatIndividualContextSelector as any).mockImplementation((selector: any) => { const state = { hasChat: false, chatId: 'test-chat-id', @@ -127,7 +127,7 @@ describe('useChatInputFlow', () => { }); it('should handle new chat flow', async () => { - (useChatIndividualContextSelector as any).mockImplementation((selector) => { + (useChatIndividualContextSelector as any).mockImplementation((selector: any) => { const state = { hasChat: false, chatId: 'test-chat-id', @@ -151,7 +151,7 @@ describe('useChatInputFlow', () => { }); it('should handle stop chat', () => { - (useChatIndividualContextSelector as any).mockImplementation((selector) => { + (useChatIndividualContextSelector as any).mockImplementation((selector: any) => { const state = { hasChat: true, chatId: 'test-chat-id', @@ -175,7 +175,7 @@ describe('useChatInputFlow', () => { }); it('should not submit when disabled', async () => { - (useChatIndividualContextSelector as any).mockImplementation((selector) => { + (useChatIndividualContextSelector as any).mockImplementation((selector: any) => { const state = { hasChat: true, chatId: 'test-chat-id', @@ -196,7 +196,7 @@ describe('useChatInputFlow', () => { }); it('should stop chat when loading', async () => { - (useChatIndividualContextSelector as any).mockImplementation((selector) => { + (useChatIndividualContextSelector as any).mockImplementation((selector: any) => { const state = { hasChat: true, chatId: 'test-chat-id', diff --git a/web/src/layouts/ChatLayout/ChatLayoutContext/useLayoutConfig/useLayoutConfig.test.tsx b/web/src/layouts/ChatLayout/ChatLayoutContext/useLayoutConfig/useLayoutConfig.test.tsx index e579f450c..c6a7768c6 100644 --- a/web/src/layouts/ChatLayout/ChatLayoutContext/useLayoutConfig/useLayoutConfig.test.tsx +++ b/web/src/layouts/ChatLayout/ChatLayoutContext/useLayoutConfig/useLayoutConfig.test.tsx @@ -32,7 +32,7 @@ describe('useLayoutConfig', () => { beforeEach(() => { vi.clearAllMocks(); - (useAppLayoutContextSelector as any).mockImplementation((selector) => { + (useAppLayoutContextSelector as any).mockImplementation((selector: any) => { const state = { onChangePage: mockOnChangePage, onChangeQueryParams: mockOnChangeQueryParams diff --git a/web/src/layouts/ChatLayout/ChatLayoutContext/useSelectedFile/createSelectedFile.ts b/web/src/layouts/ChatLayout/ChatLayoutContext/useSelectedFile/createSelectedFile.ts index d51df68e5..6cf6be915 100644 --- a/web/src/layouts/ChatLayout/ChatLayoutContext/useSelectedFile/createSelectedFile.ts +++ b/web/src/layouts/ChatLayout/ChatLayoutContext/useSelectedFile/createSelectedFile.ts @@ -1,9 +1,15 @@ import type { SelectedFile } from '../../interfaces'; -import type { useGetChatParams } from '../useGetChatParams'; -export const createSelectedFile = ( - params: ReturnType -): SelectedFile | null => { +export const createSelectedFile = (params: { + metricId?: string; + collectionId?: string; + datasetId?: string; + dashboardId?: string; + chatId?: string; + messageId?: string; + metricVersionNumber?: number; + dashboardVersionNumber?: number; +}): SelectedFile | null => { const { metricId, collectionId, diff --git a/web/src/layouts/ChatLayout/ChatLayoutContext/useSelectedFile/useSelectedFile.test.tsx b/web/src/layouts/ChatLayout/ChatLayoutContext/useSelectedFile/useSelectedFile.test.tsx index 0edbf53f8..22e549b46 100644 --- a/web/src/layouts/ChatLayout/ChatLayoutContext/useSelectedFile/useSelectedFile.test.tsx +++ b/web/src/layouts/ChatLayout/ChatLayoutContext/useSelectedFile/useSelectedFile.test.tsx @@ -2,7 +2,7 @@ import type { FileType } from '@/api/asset_interfaces/chat'; import type { AppSplitterRef } from '@/components/ui/layouts/AppSplitter'; import { BusterRoutes } from '@/routes'; import { act, renderHook } from '@testing-library/react'; -import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { type MockedFunction, beforeEach, describe, expect, it, vi } from 'vitest'; import type { SelectedFile } from '../../interfaces'; import type { FileViewSecondary } from '../useLayoutConfig'; import { createSelectedFile } from './createSelectedFile'; @@ -17,7 +17,7 @@ vi.mock('@/context/BusterAppLayout', () => ({ useAppLayoutContextSelector: vi.fn((selector) => mockOnChangePage) })); -const mockCreateSelectedFile = createSelectedFile as anyedFunction; +const mockCreateSelectedFile = createSelectedFile as MockedFunction; describe('useSelectedFile', () => { const mockAnimateOpenSplitter = vi.fn(); diff --git a/web/src/layouts/ChatLayout/FileContainer/FileContainerHeader/FileContainerHeaderVersionHistory/useCloseVersionHistory.test.ts b/web/src/layouts/ChatLayout/FileContainer/FileContainerHeader/FileContainerHeaderVersionHistory/useCloseVersionHistory.test.ts index 63ac2a7b9..8097a9059 100644 --- a/web/src/layouts/ChatLayout/FileContainer/FileContainerHeader/FileContainerHeaderVersionHistory/useCloseVersionHistory.test.ts +++ b/web/src/layouts/ChatLayout/FileContainer/FileContainerHeader/FileContainerHeaderVersionHistory/useCloseVersionHistory.test.ts @@ -18,7 +18,7 @@ describe('useCloseVersionHistory', () => { vi.clearAllMocks(); // Mock useAppLayoutContextSelector - (useAppLayoutContextSelector as any).mockImplementation((selector) => { + (useAppLayoutContextSelector as any).mockImplementation((selector: any) => { return selector({ onChangePage: mockOnChangePage }); }); @@ -35,7 +35,7 @@ describe('useCloseVersionHistory', () => { mockGetInitialChatFileHref.mockReturnValue(expectedHref); // Mock chat layout context values - (useChatLayoutContextSelector as any).mockImplementation((selector) => + (useChatLayoutContextSelector as any).mockImplementation((selector: any) => selector({ chatId: 'chat-123', metricId: 'metric-123', @@ -62,7 +62,7 @@ describe('useCloseVersionHistory', () => { mockGetInitialChatFileHref.mockReturnValue(null); // Mock chat layout context values - (useChatLayoutContextSelector as any).mockImplementation((selector) => + (useChatLayoutContextSelector as any).mockImplementation((selector: any) => selector({ chatId: 'chat-123', metricId: 'metric-123', @@ -81,7 +81,7 @@ describe('useCloseVersionHistory', () => { mockGetInitialChatFileHref.mockReturnValue(expectedHref); // Mock chat layout context values - (useChatLayoutContextSelector as any).mockImplementation((selector) => + (useChatLayoutContextSelector as any).mockImplementation((selector: any) => selector({ chatId: 'chat-123', metricId: 'metric-123', @@ -98,7 +98,7 @@ describe('useCloseVersionHistory', () => { it('should return correct href when chatId is not present', () => { // Mock chat layout context values - (useChatLayoutContextSelector as any).mockImplementation((selector) => + (useChatLayoutContextSelector as any).mockImplementation((selector: any) => selector({ chatId: undefined, metricId: 'metric-123', @@ -119,7 +119,7 @@ describe('useCloseVersionHistory', () => { mockGetInitialChatFileHref.mockReturnValue(expectedHref); // Mock chat layout context values - (useChatLayoutContextSelector as any).mockImplementation((selector) => + (useChatLayoutContextSelector as any).mockImplementation((selector: any) => selector({ chatId: undefined, metricId: 'metric-123', diff --git a/web/src/layouts/ChatLayout/FileContainer/FileContainerHeader/MetricContainerHeaderButtons/MetricThreeDotMenu.tsx b/web/src/layouts/ChatLayout/FileContainer/FileContainerHeader/MetricContainerHeaderButtons/MetricThreeDotMenu.tsx index 088d9291c..50f22bc2f 100644 --- a/web/src/layouts/ChatLayout/FileContainer/FileContainerHeader/MetricContainerHeaderButtons/MetricThreeDotMenu.tsx +++ b/web/src/layouts/ChatLayout/FileContainer/FileContainerHeader/MetricContainerHeaderButtons/MetricThreeDotMenu.tsx @@ -263,13 +263,13 @@ const useCollectionSelectMenu = ({ metricId }: { metricId: string }) => { openInfoMessage('Metrics removed from collections'); }); - const { modal, ...dropdownProps } = useSaveToCollectionsDropdownContent({ + const { ModalComponent, ...dropdownProps } = useSaveToCollectionsDropdownContent({ onSaveToCollection, onRemoveFromCollection, selectedCollections }); - const collectionSubMenu = useMemo(() => { + const CollectionSubMenu = useMemo(() => { return ; }, [dropdownProps]); @@ -280,11 +280,11 @@ const useCollectionSelectMenu = ({ metricId }: { metricId: string }) => { icon: , items: [ - {collectionSubMenu} {modal} + {CollectionSubMenu} {ModalComponent} ] }), - [collectionSubMenu] + [CollectionSubMenu] ); return collectionDropdownItem; diff --git a/web/src/lib/assets/assetParamsToRoute.test.ts b/web/src/lib/assets/assetParamsToRoute.test.ts index febbee2b1..93e8a236d 100644 --- a/web/src/lib/assets/assetParamsToRoute.test.ts +++ b/web/src/lib/assets/assetParamsToRoute.test.ts @@ -211,7 +211,7 @@ describe('assetParamsToRoute', () => { ); }); it('unsupported file type', () => { - const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(); + const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}); const result = assetParamsToRoute({ chatId: mockChatId, assetId: mockAssetId,