Prettier 2: Electric Boogaloo (#6113)

# Description of Changes
When I added Prettier formatting in #6052, my aim was to use just the
default settings in Prettier. Turns out, Prettier looks _really hard_
for any config files if it's not explicitly given one, which means that
if a developer has some sort of Prettier config file lying around on
their system, Prettier might find it and use it. Also, Prettier changes
its defaults based on stuff in `.editorconfig` without any good way of
disabling that behaviour explicitly in its config file.

To solve both of these issues, I've introduced a `.prettierrc` file
which sets Prettier's defaults explicitly, and then reformatted all our
code _again_ in Prettier's actual default settings. This should achieve
the aim of #6052 and remove the possibility for it breaking on different
dev computers.
This commit is contained in:
James Brunton
2026-04-17 09:50:16 +00:00
committed by GitHub
parent de8c483054
commit 8ab060a4be
1207 changed files with 52646 additions and 15352 deletions
@@ -4,9 +4,16 @@ import { ChatProvider } from "@app/components/chat/ChatContext";
export type { AppProvidersProps };
export function AppProviders({ children, appConfigRetryOptions, appConfigProviderProps }: AppProvidersProps) {
export function AppProviders({
children,
appConfigRetryOptions,
appConfigProviderProps,
}: AppProvidersProps) {
return (
<ProprietaryAppProviders appConfigRetryOptions={appConfigRetryOptions} appConfigProviderProps={appConfigProviderProps}>
<ProprietaryAppProviders
appConfigRetryOptions={appConfigRetryOptions}
appConfigProviderProps={appConfigProviderProps}
>
<ChatProvider>{children}</ChatProvider>
</ProprietaryAppProviders>
);
@@ -1,4 +1,11 @@
import { createContext, useContext, useReducer, useCallback, useRef, type ReactNode } from "react";
import {
createContext,
useContext,
useReducer,
useCallback,
useRef,
type ReactNode,
} from "react";
import { useAllFiles } from "@app/contexts/FileContext";
import { getAuthHeaders } from "@app/services/apiClientSetup";
@@ -82,7 +89,10 @@ function formatWorkflowResponse(data: AiWorkflowResponse): string {
case "not_found":
return data.reason ?? "I couldn't find the requested information.";
case "unsupported_capability":
return data.message ?? `Unsupported capability: ${data.capability ?? "unknown"}`;
return (
data.message ??
`Unsupported capability: ${data.capability ?? "unknown"}`
);
case "cannot_continue":
return data.reason ?? "Something went wrong and I can't continue.";
case "plan":
@@ -91,9 +101,13 @@ function formatWorkflowResponse(data: AiWorkflowResponse): string {
: JSON.stringify(data.steps, null, 2);
case "need_content":
case "tool_call":
return data.rationale ?? data.summary ?? `Processing (${data.outcome})...`;
return (
data.rationale ?? data.summary ?? `Processing (${data.outcome})...`
);
default:
return data.answer ?? data.summary ?? data.message ?? JSON.stringify(data);
return (
data.answer ?? data.summary ?? data.message ?? JSON.stringify(data)
);
}
}
@@ -178,7 +192,10 @@ export function ChatProvider({ children }: { children: ReactNode }) {
const abortRef = useRef<AbortController | null>(null);
const toggleOpen = useCallback(() => dispatch({ type: "TOGGLE_OPEN" }), []);
const setOpen = useCallback((open: boolean) => dispatch({ type: "SET_OPEN", open }), []);
const setOpen = useCallback(
(open: boolean) => dispatch({ type: "SET_OPEN", open }),
[],
);
const sendMessage = useCallback(
async (content: string) => {
@@ -220,7 +237,10 @@ export function ChatProvider({ children }: { children: ReactNode }) {
await consumeSSEStream(response, {
onProgress: (data) => {
dispatch({ type: "SET_PROGRESS", phase: data.phase as AiWorkflowPhase });
dispatch({
type: "SET_PROGRESS",
phase: data.phase as AiWorkflowPhase,
});
},
onResult: (data) => {
receivedResult = true;
@@ -262,7 +282,8 @@ export function ChatProvider({ children }: { children: ReactNode }) {
message: {
id: crypto.randomUUID(),
role: "assistant",
content: "Failed to get a response. The AI engine may not be available yet.",
content:
"Failed to get a response. The AI engine may not be available yet.",
timestamp: Date.now(),
},
});
@@ -15,7 +15,8 @@
display: flex;
flex-direction: column;
background: var(--mantine-color-body);
border-left: 1px solid var(--border-subtle, var(--mantine-color-default-border));
border-left: 1px solid
var(--border-subtle, var(--mantine-color-default-border));
z-index: 999;
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
}
@@ -25,7 +26,8 @@
align-items: center;
justify-content: space-between;
padding: 0.75rem 1rem;
border-bottom: 1px solid var(--border-subtle, var(--mantine-color-default-border));
border-bottom: 1px solid
var(--border-subtle, var(--mantine-color-default-border));
flex-shrink: 0;
}
@@ -38,7 +40,8 @@
display: flex;
gap: 0.5rem;
padding: 0.75rem;
border-top: 1px solid var(--border-subtle, var(--mantine-color-default-border));
border-top: 1px solid
var(--border-subtle, var(--mantine-color-default-border));
flex-shrink: 0;
}
@@ -1,13 +1,30 @@
import { useRef, useEffect, useState, type KeyboardEvent } from "react";
import { useTranslation } from "react-i18next";
import { ActionIcon, ScrollArea, TextInput, Stack, Text, Paper, Box, Transition, Loader, Group } from "@mantine/core";
import {
ActionIcon,
ScrollArea,
TextInput,
Stack,
Text,
Paper,
Box,
Transition,
Loader,
Group,
} from "@mantine/core";
import SendIcon from "@mui/icons-material/Send";
import ChatBubbleOutlineIcon from "@mui/icons-material/ChatBubbleOutline";
import CloseIcon from "@mui/icons-material/Close";
import { useChat } from "@app/components/chat/ChatContext";
import "@app/components/chat/ChatPanel.css";
function ChatMessageBubble({ role, content }: { role: "user" | "assistant"; content: string }) {
function ChatMessageBubble({
role,
content,
}: {
role: "user" | "assistant";
content: string;
}) {
return (
<div className={`chat-message chat-message-${role}`}>
<Paper className={`chat-bubble chat-bubble-${role}`} p="xs" radius="md">
@@ -21,14 +38,24 @@ function ChatMessageBubble({ role, content }: { role: "user" | "assistant"; cont
export function ChatPanel() {
const { t } = useTranslation();
const { messages, isOpen, isLoading, progressPhase, toggleOpen, sendMessage } = useChat();
const {
messages,
isOpen,
isLoading,
progressPhase,
toggleOpen,
sendMessage,
} = useChat();
const [input, setInput] = useState("");
const scrollRef = useRef<HTMLDivElement>(null);
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
if (scrollRef.current) {
scrollRef.current.scrollTo({ top: scrollRef.current.scrollHeight, behavior: "smooth" });
scrollRef.current.scrollTo({
top: scrollRef.current.scrollHeight,
behavior: "smooth",
});
}
}, [messages]);
@@ -78,7 +105,12 @@ export function ChatPanel() {
<Text fw={600} size="sm">
AI Assistant
</Text>
<ActionIcon variant="subtle" size="sm" onClick={toggleOpen} aria-label="Close chat">
<ActionIcon
variant="subtle"
size="sm"
onClick={toggleOpen}
aria-label="Close chat"
>
<CloseIcon sx={{ fontSize: 16 }} />
</ActionIcon>
</div>
@@ -88,19 +120,30 @@ export function ChatPanel() {
<Stack gap="sm" p="sm">
{messages.length === 0 && (
<Text size="sm" c="dimmed" ta="center" py="xl">
Ask a question about your documents or get help with PDF tools.
Ask a question about your documents or get help with PDF
tools.
</Text>
)}
{messages.map((msg) => (
<ChatMessageBubble key={msg.id} role={msg.role} content={msg.content} />
<ChatMessageBubble
key={msg.id}
role={msg.role}
content={msg.content}
/>
))}
{isLoading && (
<div className="chat-message chat-message-assistant">
<Paper className="chat-bubble chat-bubble-assistant" p="xs" radius="md">
<Paper
className="chat-bubble chat-bubble-assistant"
p="xs"
radius="md"
>
<Group gap="xs" wrap="nowrap">
<Loader size="xs" type="dots" />
<Text size="sm" c="dimmed">
{progressPhase ? t(`chat.progress.${progressPhase}`) : t("chat.progress.thinking")}
{progressPhase
? t(`chat.progress.${progressPhase}`)
: t("chat.progress.thinking")}
</Text>
</Group>
</Paper>
+8 -1
View File
@@ -8,5 +8,12 @@
"@core/*": ["src/core/*"]
}
},
"include": ["../global.d.ts", "../*.js", "../*.ts", "../*.tsx", "../core/setupTests.ts", "."]
"include": [
"../global.d.ts",
"../*.js",
"../*.ts",
"../*.tsx",
"../core/setupTests.ts",
"."
]
}