Modal, header, mobile display and workflow UI updates

This commit is contained in:
willchen96 2026-06-11 22:43:13 +08:00
parent 8a2dc05181
commit 3132e04ac0
34 changed files with 1635 additions and 1076 deletions

View file

@ -11,6 +11,7 @@ import { getUserApiKeys as getStoredUserApiKeys } from "./userApiKeys";
export type UserModelSettings = {
title_model: string;
tabular_model: string;
legal_research_us: boolean;
api_keys: UserApiKeys;
};
@ -32,7 +33,7 @@ export async function getUserModelSettings(
const client = db ?? createServerSupabase();
const { data } = await client
.from("user_profiles")
.select("title_model, tabular_model")
.select("title_model, tabular_model, legal_research_us")
.eq("user_id", userId)
.single();
const api_keys = await getStoredUserApiKeys(userId, client);
@ -40,6 +41,9 @@ export async function getUserModelSettings(
return {
title_model: resolveModel(data?.title_model, resolveTitleModel(api_keys)),
tabular_model: resolveModel(data?.tabular_model, DEFAULT_TABULAR_MODEL),
legal_research_us:
(data as { legal_research_us?: boolean | null } | null)
?.legal_research_us !== false,
api_keys,
};
}
@ -51,31 +55,3 @@ export async function getUserApiKeys(
const client = db ?? createServerSupabase();
return getStoredUserApiKeys(userId, client);
}
/**
* Whether the user has US legal research (CourtListener) tools enabled in
* chat. Controlled by the Features > Legal Research > Jurisdiction > US
* toggle in account settings. Defaults to enabled both when the user has
* no profile row yet and when the column is missing (migration not applied),
* so existing behaviour is preserved on partially-migrated deployments.
*/
export async function getLegalResearchUsEnabled(
userId: string,
db?: ReturnType<typeof createServerSupabase>,
): Promise<boolean> {
const client = db ?? createServerSupabase();
try {
const { data, error } = await client
.from("user_profiles")
.select("legal_research_us")
.eq("user_id", userId)
.maybeSingle();
if (error || !data) return true;
return (
(data as { legal_research_us?: boolean | null })
.legal_research_us !== false
);
} catch {
return true;
}
}

View file

@ -16,8 +16,6 @@ import {
} from "../lib/chatTools";
import { completeText } from "../lib/llm";
import {
getLegalResearchUsEnabled,
getUserApiKeys,
getUserModelSettings,
} from "../lib/userSettings";
import { checkProjectAccess } from "../lib/access";
@ -556,7 +554,10 @@ chatRouter.post("/", requireAuth, async (req, res) => {
db,
docIndex,
);
const legalResearchUs = await getLegalResearchUsEnabled(userId, db);
const {
api_keys: apiKeys,
legal_research_us: legalResearchUs,
} = await getUserModelSettings(userId, db);
const apiMessages = buildMessages(
enrichedMessages,
docAvailability,
@ -586,8 +587,6 @@ chatRouter.post("/", requireAuth, async (req, res) => {
if (!streamFinished) streamAbort.abort();
});
const apiKeys = await getUserApiKeys(userId, db);
try {
write(`data: ${JSON.stringify({ type: "chat_id", chatId })}\n\n`);

View file

@ -16,8 +16,7 @@ import {
type ChatMessage,
} from "../lib/chatTools";
import {
getLegalResearchUsEnabled,
getUserApiKeys,
getUserModelSettings,
} from "../lib/userSettings";
import { checkProjectAccess } from "../lib/access";
import { safeErrorLog, safeErrorMessage } from "../lib/safeError";
@ -144,7 +143,10 @@ projectChatRouter.post("/", requireAuth, async (req, res) => {
systemPromptExtra += `\n\nUSER-ATTACHED DOCUMENTS FOR THIS TURN:\nThe user has attached the following document(s) directly to their latest message. Treat these as the primary focus of the request unless their message clearly says otherwise.\n${lines.join("\n")}`;
}
const legalResearchUs = await getLegalResearchUsEnabled(userId, db);
const {
api_keys: apiKeys,
legal_research_us: legalResearchUs,
} = await getUserModelSettings(userId, db);
const apiMessages = buildMessages(
messagesForLLM,
docAvailability,
@ -168,8 +170,6 @@ projectChatRouter.post("/", requireAuth, async (req, res) => {
if (!streamFinished) streamAbort.abort();
});
const apiKeys = await getUserApiKeys(userId, db);
try {
write(`data: ${JSON.stringify({ type: "chat_id", chatId })}\n\n`);

View file

@ -70,20 +70,6 @@ async function attachDocumentOwnerLabels(
.filter((id, index, arr) => arr.indexOf(id) === index);
if (ownerIds.length === 0) return;
const emailByUserId = new Map<string, string>();
const userResults = await Promise.allSettled(
ownerIds.map(async (id) => {
const { data, error } = await db.auth.admin.getUserById(id);
if (error) throw error;
return { id, email: data.user?.email ?? null };
}),
);
for (const result of userResults) {
if (result.status === "fulfilled" && result.value.email) {
emailByUserId.set(result.value.id, result.value.email);
}
}
const displayNameByUserId = new Map<string, string>();
const { data: profiles, error: profilesError } = await db
.from("user_profiles")
@ -108,7 +94,7 @@ async function attachDocumentOwnerLabels(
owner_display_name?: string | null;
})[]) {
if (!doc.user_id) continue;
doc.owner_email = emailByUserId.get(doc.user_id) ?? null;
doc.owner_email = null;
doc.owner_display_name = displayNameByUserId.get(doc.user_id) ?? null;
}
}