fix: Resolve all ESLint errors and warnings in web package
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Fixes all 542 ESLint problems in the web package to achieve 0 errors and 0 warnings. Changes: - Fixed 144 issues: nullish coalescing, return types, unused variables - Fixed 118 issues: unnecessary conditions, type safety, template literals - Fixed 79 issues: non-null assertions, unsafe assignments, empty functions - Fixed 67 issues: explicit return types, promise handling, enum comparisons - Fixed 45 final warnings: missing return types, optional chains - Fixed 25 typecheck-related issues: async/await, type assertions, formatting - Fixed JSX.Element namespace errors across 90+ files All Quality Rails violations resolved. Lint and typecheck both pass with 0 problems. Files modified: 118 components, tests, hooks, and utilities Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -21,7 +21,7 @@ const createWrapper = () => {
|
||||
},
|
||||
});
|
||||
|
||||
return ({ children }: { children: ReactNode }) => (
|
||||
return ({ children }: { children: ReactNode }): React.JSX.Element => (
|
||||
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
||||
);
|
||||
};
|
||||
@@ -64,7 +64,12 @@ describe("useLayouts", (): void => {
|
||||
});
|
||||
|
||||
it("should show loading state", (): void => {
|
||||
(global.fetch as ReturnType<typeof vi.fn>).mockImplementation(() => new Promise(() => {}));
|
||||
(global.fetch as ReturnType<typeof vi.fn>).mockImplementation(
|
||||
() =>
|
||||
new Promise((): void => {
|
||||
// Intentionally empty to keep promise pending
|
||||
})
|
||||
);
|
||||
|
||||
const { result } = renderHook(() => useLayouts(), {
|
||||
wrapper: createWrapper(),
|
||||
|
||||
@@ -209,7 +209,7 @@ export function useChat(options: UseChatOptions = {}): UseChatReturn {
|
||||
|
||||
// Add error message to chat
|
||||
const errorMessage: Message = {
|
||||
id: `error-${Date.now()}`,
|
||||
id: `error-${String(Date.now())}`,
|
||||
role: "assistant",
|
||||
content: `Error: ${errorMsg}`,
|
||||
createdAt: new Date().toISOString(),
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
*/
|
||||
|
||||
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import type { UseQueryResult, UseMutationResult } from "@tanstack/react-query";
|
||||
import type { UserLayout, WidgetPlacement } from "@mosaic/shared";
|
||||
|
||||
const LAYOUTS_KEY = ["layouts"];
|
||||
@@ -25,15 +26,15 @@ interface UpdateLayoutData {
|
||||
/**
|
||||
* Fetch all layouts for the current user
|
||||
*/
|
||||
export function useLayouts() {
|
||||
export function useLayouts(): UseQueryResult<UserLayout[]> {
|
||||
return useQuery<UserLayout[]>({
|
||||
queryKey: LAYOUTS_KEY,
|
||||
queryFn: async () => {
|
||||
queryFn: async (): Promise<UserLayout[]> => {
|
||||
const response = await fetch("/api/layouts");
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch layouts");
|
||||
}
|
||||
return response.json();
|
||||
return response.json() as Promise<UserLayout[]>;
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -41,15 +42,15 @@ export function useLayouts() {
|
||||
/**
|
||||
* Fetch a single layout by ID
|
||||
*/
|
||||
export function useLayout(id: string) {
|
||||
export function useLayout(id: string): UseQueryResult<UserLayout> {
|
||||
return useQuery<UserLayout>({
|
||||
queryKey: [...LAYOUTS_KEY, id],
|
||||
queryFn: async () => {
|
||||
queryFn: async (): Promise<UserLayout> => {
|
||||
const response = await fetch(`/api/layouts/${id}`);
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch layout");
|
||||
}
|
||||
return response.json();
|
||||
return response.json() as Promise<UserLayout>;
|
||||
},
|
||||
enabled: !!id,
|
||||
});
|
||||
@@ -58,15 +59,15 @@ export function useLayout(id: string) {
|
||||
/**
|
||||
* Fetch the default layout
|
||||
*/
|
||||
export function useDefaultLayout() {
|
||||
export function useDefaultLayout(): UseQueryResult<UserLayout> {
|
||||
return useQuery<UserLayout>({
|
||||
queryKey: [...LAYOUTS_KEY, "default"],
|
||||
queryFn: async () => {
|
||||
queryFn: async (): Promise<UserLayout> => {
|
||||
const response = await fetch("/api/layouts/default");
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch default layout");
|
||||
}
|
||||
return response.json();
|
||||
return response.json() as Promise<UserLayout>;
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -74,11 +75,11 @@ export function useDefaultLayout() {
|
||||
/**
|
||||
* Create a new layout
|
||||
*/
|
||||
export function useCreateLayout() {
|
||||
export function useCreateLayout(): UseMutationResult<UserLayout, Error, CreateLayoutData> {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async (data: CreateLayoutData) => {
|
||||
mutationFn: async (data: CreateLayoutData): Promise<UserLayout> => {
|
||||
const response = await fetch("/api/layouts", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
@@ -91,11 +92,11 @@ export function useCreateLayout() {
|
||||
throw new Error("Failed to create layout");
|
||||
}
|
||||
|
||||
return response.json();
|
||||
return response.json() as Promise<UserLayout>;
|
||||
},
|
||||
onSuccess: () => {
|
||||
onSuccess: (): void => {
|
||||
// Invalidate layouts cache to refetch
|
||||
queryClient.invalidateQueries({ queryKey: LAYOUTS_KEY });
|
||||
void queryClient.invalidateQueries({ queryKey: LAYOUTS_KEY });
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -103,11 +104,11 @@ export function useCreateLayout() {
|
||||
/**
|
||||
* Update an existing layout
|
||||
*/
|
||||
export function useUpdateLayout() {
|
||||
export function useUpdateLayout(): UseMutationResult<UserLayout, Error, UpdateLayoutData> {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async ({ id, ...data }: UpdateLayoutData) => {
|
||||
mutationFn: async ({ id, ...data }: UpdateLayoutData): Promise<UserLayout> => {
|
||||
const response = await fetch(`/api/layouts/${id}`, {
|
||||
method: "PATCH",
|
||||
headers: {
|
||||
@@ -120,12 +121,12 @@ export function useUpdateLayout() {
|
||||
throw new Error("Failed to update layout");
|
||||
}
|
||||
|
||||
return response.json();
|
||||
return response.json() as Promise<UserLayout>;
|
||||
},
|
||||
onSuccess: (_, variables) => {
|
||||
onSuccess: (_data, variables): void => {
|
||||
// Invalidate affected queries
|
||||
queryClient.invalidateQueries({ queryKey: LAYOUTS_KEY });
|
||||
queryClient.invalidateQueries({ queryKey: [...LAYOUTS_KEY, variables.id] });
|
||||
void queryClient.invalidateQueries({ queryKey: LAYOUTS_KEY });
|
||||
void queryClient.invalidateQueries({ queryKey: [...LAYOUTS_KEY, variables.id] });
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -133,11 +134,11 @@ export function useUpdateLayout() {
|
||||
/**
|
||||
* Delete a layout
|
||||
*/
|
||||
export function useDeleteLayout() {
|
||||
export function useDeleteLayout(): UseMutationResult<void, Error, string> {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async (id: string) => {
|
||||
mutationFn: async (id: string): Promise<void> => {
|
||||
const response = await fetch(`/api/layouts/${id}`, {
|
||||
method: "DELETE",
|
||||
});
|
||||
@@ -146,22 +147,28 @@ export function useDeleteLayout() {
|
||||
throw new Error("Failed to delete layout");
|
||||
}
|
||||
|
||||
return response.json();
|
||||
await response.json();
|
||||
},
|
||||
onSuccess: () => {
|
||||
onSuccess: (): void => {
|
||||
// Invalidate layouts cache to refetch
|
||||
queryClient.invalidateQueries({ queryKey: LAYOUTS_KEY });
|
||||
void queryClient.invalidateQueries({ queryKey: LAYOUTS_KEY });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
interface UseSaveLayoutReturn {
|
||||
saveLayout: (layout: WidgetPlacement[]) => void;
|
||||
isSaving: boolean;
|
||||
error: Error | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper hook to save layout changes with debouncing
|
||||
*/
|
||||
export function useSaveLayout(layoutId: string) {
|
||||
export function useSaveLayout(layoutId: string): UseSaveLayoutReturn {
|
||||
const updateLayout = useUpdateLayout();
|
||||
|
||||
const saveLayout = (layout: WidgetPlacement[]) => {
|
||||
const saveLayout = (layout: WidgetPlacement[]): void => {
|
||||
updateLayout.mutate({
|
||||
id: layoutId,
|
||||
layout,
|
||||
|
||||
@@ -64,7 +64,7 @@ export function useWebSocket(
|
||||
|
||||
useEffect(() => {
|
||||
// Get WebSocket URL from environment or default to API URL
|
||||
const wsUrl = process.env.NEXT_PUBLIC_API_URL || "http://localhost:3001";
|
||||
const wsUrl = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:3001";
|
||||
|
||||
// Create socket connection
|
||||
const newSocket = io(wsUrl, {
|
||||
|
||||
Reference in New Issue
Block a user