New toasts (#1777)

This commit is contained in:
Matthew Diamant
2025-03-24 12:32:39 -07:00
committed by GitHub
parent 6f2842bfbf
commit 0cac3c148d
15 changed files with 242 additions and 136 deletions
@@ -1,37 +1,72 @@
import { toast } from 'react-toastify';
import { toast, ToastOptions } from 'react-toastify';
import React from 'react';
import { Model } from './ModelContext';
export function ToastSuccessModelSwitch(model: Model) {
const commonToastOptions: ToastOptions = {
position: 'top-right',
closeButton: false,
hideProgressBar: true,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
};
type ToastSuccessProps = { title?: string; msg?: string; toastOptions?: ToastOptions };
export function ToastSuccess({ title, msg, toastOptions = {} }: ToastSuccessProps) {
return toast.success(
<div>
<strong>Model Changed</strong>
<div>Switched to {model.alias ?? model.name}</div>
{title ? <strong className="font-medium">{title}</strong> : null}
{title ? <div>{msg}</div> : null}
</div>,
{
position: 'top-right',
autoClose: 5000,
hideProgressBar: true,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
}
{ ...commonToastOptions, autoClose: 3000, ...toastOptions }
);
}
export function ToastFailureGeneral(msg?: string) {
type ToastErrorProps = {
title?: string;
msg?: string;
errorMessage?: string;
toastOptions?: ToastOptions;
};
export function ToastError({ title, msg, errorMessage, toastOptions }: ToastErrorProps) {
return toast.error(
<div>
<strong>Error</strong>
<div>{msg}</div>
<div className="flex gap-4">
<div className="flex-grow">
{title ? <strong className="font-medium">{title}</strong> : null}
{msg ? <div>{msg}</div> : null}
</div>
<div className="flex-none flex items-center">
{errorMessage ? (
<button
className="text-textProminentInverse font-medium"
onClick={() => navigator.clipboard.writeText(errorMessage)}
>
Copy error
</button>
) : null}
</div>
</div>,
{
position: 'top-right',
autoClose: 3000,
hideProgressBar: true,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
}
{ ...commonToastOptions, autoClose: errorMessage ? false : 5000, ...toastOptions }
);
}
type ToastLoadingProps = { title?: string; msg?: string; toastOptions?: ToastOptions };
export function ToastLoading({ title, msg, toastOptions }: ToastLoadingProps) {
return toast.loading(
<div>
{title ? <strong className="font-medium">{title}</strong> : null}
{title ? <div>{msg}</div> : null}
</div>,
{ ...commonToastOptions, autoClose: false, ...toastOptions }
);
}
type ToastInfoProps = { title?: string; msg?: string; toastOptions?: ToastOptions };
export function ToastInfo({ title, msg, toastOptions }: ToastInfoProps) {
return toast.info(
<div>
{title ? <strong className="font-medium">{title}</strong> : null}
{msg ? <div>{msg}</div> : null}
</div>,
{ ...commonToastOptions, ...toastOptions }
);
}
@@ -2,7 +2,7 @@ import { useModel } from './ModelContext'; // Import the useModel hook
import { Model } from './ModelContext';
import { useMemo } from 'react';
import { gooseModels } from './GooseModels';
import { ToastFailureGeneral, ToastSuccessModelSwitch } from './toasts';
import { ToastError, ToastSuccess } from './toasts';
import { initializeSystem } from '../../../utils/providerUtils';
import { useRecentModels } from './RecentModels';
@@ -32,12 +32,19 @@ export function useHandleModelSelection() {
console.log(`[${componentName}] Switched to model: ${model.name} (${model.provider})`);
// Display a success toast notification
ToastSuccessModelSwitch(model);
ToastSuccess({
title: 'Model changed',
msg: `Switched to ${model.alias ?? model.name}`,
});
} catch (error) {
// Handle errors gracefully
console.error(`[${componentName}] Failed to switch model:`, error);
// Display an error toast notification
ToastFailureGeneral(`Failed to switch to model: ${model.name}`);
ToastError({
title: model.name,
msg: `Failed to switch to model`,
errorMessage: error.message,
});
}
};
}