Show warning if there's uncommitted changes (#92)
This commit is contained in:
@@ -58,7 +58,10 @@ import { useVersions } from "@/hooks/useVersions";
|
|||||||
import { useAttachments } from "@/hooks/useAttachments";
|
import { useAttachments } from "@/hooks/useAttachments";
|
||||||
import { AttachmentsList } from "./AttachmentsList";
|
import { AttachmentsList } from "./AttachmentsList";
|
||||||
import { DragDropOverlay } from "./DragDropOverlay";
|
import { DragDropOverlay } from "./DragDropOverlay";
|
||||||
|
import {
|
||||||
|
showError as showErrorToast,
|
||||||
|
showUncommittedFilesWarning,
|
||||||
|
} from "@/lib/toast";
|
||||||
const showTokenBarAtom = atom(false);
|
const showTokenBarAtom = atom(false);
|
||||||
|
|
||||||
export function ChatInput({ chatId }: { chatId?: number }) {
|
export function ChatInput({ chatId }: { chatId?: number }) {
|
||||||
@@ -189,6 +192,9 @@ export function ChatInput({ chatId }: { chatId?: number }) {
|
|||||||
console.error("Failed to approve proposal:", result.error);
|
console.error("Failed to approve proposal:", result.error);
|
||||||
setError(result.error || "Failed to approve proposal");
|
setError(result.error || "Failed to approve proposal");
|
||||||
}
|
}
|
||||||
|
if (result.uncommittedFiles) {
|
||||||
|
showUncommittedFilesWarning(result.uncommittedFiles);
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Error approving proposal:", err);
|
console.error("Error approving proposal:", err);
|
||||||
setError((err as Error)?.message || "An error occurred while approving");
|
setError((err as Error)?.message || "An error occurred while approving");
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { useChats } from "./useChats";
|
|||||||
import { useLoadApp } from "./useLoadApp";
|
import { useLoadApp } from "./useLoadApp";
|
||||||
import { selectedAppIdAtom } from "@/atoms/appAtoms";
|
import { selectedAppIdAtom } from "@/atoms/appAtoms";
|
||||||
import { useVersions } from "./useVersions";
|
import { useVersions } from "./useVersions";
|
||||||
import { showError } from "@/lib/toast";
|
import { showError, showUncommittedFilesWarning } from "@/lib/toast";
|
||||||
import { useProposal } from "./useProposal";
|
import { useProposal } from "./useProposal";
|
||||||
import { useSearch } from "@tanstack/react-router";
|
import { useSearch } from "@tanstack/react-router";
|
||||||
import { useRunApp } from "./useRunApp";
|
import { useRunApp } from "./useRunApp";
|
||||||
@@ -87,6 +87,9 @@ export function useStreamChat({
|
|||||||
setIsPreviewOpen(true);
|
setIsPreviewOpen(true);
|
||||||
refreshAppIframe();
|
refreshAppIframe();
|
||||||
}
|
}
|
||||||
|
if (response.uncommittedFiles) {
|
||||||
|
showUncommittedFilesWarning(response.uncommittedFiles);
|
||||||
|
}
|
||||||
refreshProposal(chatId);
|
refreshProposal(chatId);
|
||||||
|
|
||||||
// Keep the same as below
|
// Keep the same as below
|
||||||
|
|||||||
@@ -486,6 +486,7 @@ This conversation includes one or more image attachments. When the user uploads
|
|||||||
event.sender.send("chat:response:end", {
|
event.sender.send("chat:response:end", {
|
||||||
chatId: req.chatId,
|
chatId: req.chatId,
|
||||||
updatedFiles: status.updatedFiles ?? false,
|
updatedFiles: status.updatedFiles ?? false,
|
||||||
|
uncommittedFiles: status.uncommittedFiles,
|
||||||
} satisfies ChatResponseEnd);
|
} satisfies ChatResponseEnd);
|
||||||
} else {
|
} else {
|
||||||
event.sender.send("chat:response:end", {
|
event.sender.send("chat:response:end", {
|
||||||
|
|||||||
@@ -331,7 +331,11 @@ const getProposalHandler = async (
|
|||||||
const approveProposalHandler = async (
|
const approveProposalHandler = async (
|
||||||
_event: IpcMainInvokeEvent,
|
_event: IpcMainInvokeEvent,
|
||||||
{ chatId, messageId }: { chatId: number; messageId: number }
|
{ chatId, messageId }: { chatId: number; messageId: number }
|
||||||
): Promise<{ success: boolean; error?: string }> => {
|
): Promise<{
|
||||||
|
success: boolean;
|
||||||
|
error?: string;
|
||||||
|
uncommittedFiles?: string[];
|
||||||
|
}> => {
|
||||||
logger.log(
|
logger.log(
|
||||||
`IPC: approve-proposal called for chatId: ${chatId}, messageId: ${messageId}`
|
`IPC: approve-proposal called for chatId: ${chatId}, messageId: ${messageId}`
|
||||||
);
|
);
|
||||||
@@ -380,7 +384,7 @@ const approveProposalHandler = async (
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return { success: true };
|
return { success: true, uncommittedFiles: processResult.uncommittedFiles };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`Error approving proposal for messageId ${messageId}:`, error);
|
logger.error(`Error approving proposal for messageId ${messageId}:`, error);
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -111,10 +111,10 @@ export class IpcClient {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.ipcRenderer.on("chat:response:end", (payload) => {
|
this.ipcRenderer.on("chat:response:end", (payload) => {
|
||||||
const { chatId, updatedFiles } = payload as unknown as ChatResponseEnd;
|
const { chatId } = payload as unknown as ChatResponseEnd;
|
||||||
const callbacks = this.chatStreams.get(chatId);
|
const callbacks = this.chatStreams.get(chatId);
|
||||||
if (callbacks) {
|
if (callbacks) {
|
||||||
callbacks.onEnd({ chatId, updatedFiles });
|
callbacks.onEnd(payload as unknown as ChatResponseEnd);
|
||||||
console.debug("chat:response:end");
|
console.debug("chat:response:end");
|
||||||
this.chatStreams.delete(chatId);
|
this.chatStreams.delete(chatId);
|
||||||
} else {
|
} else {
|
||||||
@@ -734,13 +734,21 @@ export class IpcClient {
|
|||||||
}: {
|
}: {
|
||||||
chatId: number;
|
chatId: number;
|
||||||
messageId: number;
|
messageId: number;
|
||||||
}): Promise<{ success: boolean; error?: string }> {
|
}): Promise<{
|
||||||
|
success: boolean;
|
||||||
|
error?: string;
|
||||||
|
uncommittedFiles?: string[];
|
||||||
|
}> {
|
||||||
try {
|
try {
|
||||||
const result = await this.ipcRenderer.invoke("approve-proposal", {
|
const result = await this.ipcRenderer.invoke("approve-proposal", {
|
||||||
chatId,
|
chatId,
|
||||||
messageId,
|
messageId,
|
||||||
});
|
});
|
||||||
return result as { success: boolean; error?: string };
|
return result as {
|
||||||
|
success: boolean;
|
||||||
|
error?: string;
|
||||||
|
uncommittedFiles?: string[];
|
||||||
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
showError(error);
|
showError(error);
|
||||||
return { success: false, error: (error as Error).message };
|
return { success: false, error: (error as Error).message };
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ export interface ChatStreamParams {
|
|||||||
export interface ChatResponseEnd {
|
export interface ChatResponseEnd {
|
||||||
chatId: number;
|
chatId: number;
|
||||||
updatedFiles: boolean;
|
updatedFiles: boolean;
|
||||||
|
uncommittedFiles?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CreateAppParams {
|
export interface CreateAppParams {
|
||||||
|
|||||||
@@ -175,7 +175,11 @@ export async function processFullResponseActions(
|
|||||||
chatSummary,
|
chatSummary,
|
||||||
messageId,
|
messageId,
|
||||||
}: { chatSummary: string | undefined; messageId: number }
|
}: { chatSummary: string | undefined; messageId: number }
|
||||||
): Promise<{ updatedFiles?: boolean; error?: string }> {
|
): Promise<{
|
||||||
|
updatedFiles?: boolean;
|
||||||
|
error?: string;
|
||||||
|
uncommittedFiles?: string[];
|
||||||
|
}> {
|
||||||
logger.log("processFullResponseActions for chatId", chatId);
|
logger.log("processFullResponseActions for chatId", chatId);
|
||||||
// Get the app associated with the chat
|
// Get the app associated with the chat
|
||||||
const chatWithApp = await db.query.chats.findFirst({
|
const chatWithApp = await db.query.chats.findFirst({
|
||||||
@@ -453,6 +457,13 @@ export async function processFullResponseActions(
|
|||||||
})
|
})
|
||||||
.where(eq(messages.id, messageId));
|
.where(eq(messages.id, messageId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for any uncommitted changes after the commit
|
||||||
|
const statusMatrix = await git.statusMatrix({ fs, dir: appPath });
|
||||||
|
const uncommittedFiles = statusMatrix
|
||||||
|
.filter((row) => row[1] !== 1 || row[2] !== 1 || row[3] !== 1)
|
||||||
|
.map((row) => row[0]); // Get just the file paths
|
||||||
|
|
||||||
logger.log("mark as approved: hasChanges", hasChanges);
|
logger.log("mark as approved: hasChanges", hasChanges);
|
||||||
// Update the message to approved
|
// Update the message to approved
|
||||||
await db
|
await db
|
||||||
@@ -461,7 +472,12 @@ export async function processFullResponseActions(
|
|||||||
approvalState: "approved",
|
approvalState: "approved",
|
||||||
})
|
})
|
||||||
.where(eq(messages.id, messageId));
|
.where(eq(messages.id, messageId));
|
||||||
return { updatedFiles: hasChanges };
|
|
||||||
|
return {
|
||||||
|
updatedFiles: hasChanges,
|
||||||
|
uncommittedFiles:
|
||||||
|
uncommittedFiles.length > 0 ? uncommittedFiles : undefined,
|
||||||
|
};
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
logger.error("Error processing files:", error);
|
logger.error("Error processing files:", error);
|
||||||
return { error: (error as any).toString() };
|
return { error: (error as any).toString() };
|
||||||
|
|||||||
@@ -21,6 +21,15 @@ export const showError = (message: any) => {
|
|||||||
console.error(message);
|
console.error(message);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a warning toast
|
||||||
|
* @param message The warning message to display
|
||||||
|
*/
|
||||||
|
export const showWarning = (message: string) => {
|
||||||
|
toast.warning(message);
|
||||||
|
console.warn(message);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show an info toast
|
* Show an info toast
|
||||||
* @param message The info message to display
|
* @param message The info message to display
|
||||||
@@ -49,5 +58,12 @@ export const showLoading = <T>(
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const showUncommittedFilesWarning = (files: string[]) => {
|
||||||
|
showWarning(
|
||||||
|
`Some changed files were not committed. Please use git to manually commit them.
|
||||||
|
\n\n${files.join("\n")}`
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
// Re-export for direct use
|
// Re-export for direct use
|
||||||
export { toast };
|
export { toast };
|
||||||
|
|||||||
Reference in New Issue
Block a user