emojiSelectHandler(i)}
diff --git a/interface/app/$libraryId/settings/library/locations/AddLocationDialog.tsx b/interface/app/$libraryId/settings/library/locations/AddLocationDialog.tsx
index 060241a7a..aaa16bf2e 100644
--- a/interface/app/$libraryId/settings/library/locations/AddLocationDialog.tsx
+++ b/interface/app/$libraryId/settings/library/locations/AddLocationDialog.tsx
@@ -206,7 +206,7 @@ export const AddLocationDialog = ({
: ''
}
>
-
+
diff --git a/packages/client/src/utils/explorerItem.ts b/packages/client/src/utils/explorerItem.ts
index 1ada12b31..e7f0baabe 100644
--- a/packages/client/src/utils/explorerItem.ts
+++ b/packages/client/src/utils/explorerItem.ts
@@ -63,7 +63,7 @@ export function getExplorerItemData(data?: null | ExplorerItem) {
itemData.fullName = `${filePath.name}${filePath.extension ? `.${filePath.extension}` : ''}`;
itemData.size = byteSize(filePath.size_in_bytes_bytes);
itemData.isDir = filePath.is_dir ?? false;
- itemData.extension = filePath.extension;
+ itemData.extension = filePath.extension?.toLocaleLowerCase() ?? null;
if ('kind' in filePath) itemData.kind = ObjectKind[filePath.kind] ?? 'Unknown';
if ('cas_id' in filePath) itemData.casId = filePath.cas_id;
if ('location_id' in filePath) itemData.locationId = filePath.location_id;
diff --git a/packages/ui/src/Toast.tsx b/packages/ui/src/Toast.tsx
index e9f91e50a..90d5e486f 100644
--- a/packages/ui/src/Toast.tsx
+++ b/packages/ui/src/Toast.tsx
@@ -1,6 +1,6 @@
import { CheckCircle, Icon, Info, Warning, WarningCircle, X } from '@phosphor-icons/react';
import clsx from 'clsx';
-import { CSSProperties, ReactNode, useEffect, useState } from 'react';
+import { CSSProperties, ForwardedRef, forwardRef, ReactNode, useEffect, useState } from 'react';
import { toast as SonnerToast } from 'sonner';
import { Button } from './Button';
@@ -20,7 +20,7 @@ const toastClassName = clsx(
export type ToastId
= T;
type ToastType = 'info' | 'success' | 'error' | 'warning';
-type ToastMessage = ReactNode | { title: ReactNode; body?: ReactNode };
+export type ToastMessage = ReactNode | { title: ReactNode; body?: ReactNode };
type ToastPromiseData = unknown;
type ToastPromise = Promise | (() => Promise);
type ToastAction = { label: string; onClick: () => void; className?: string };
@@ -28,6 +28,7 @@ type ToastCloseEvent = 'on-dismiss' | 'on-auto-close' | 'on-action' | 'on-cancel
interface ToastOptions {
id?: ToastId;
+ ref?: React.Ref;
type?: ToastType;
icon?: ReactNode;
duration?: number;
@@ -42,7 +43,7 @@ interface ToastOptions {
}
interface PromiseToastOptions
- extends Omit {
+ extends Omit {
loading: ToastMessage;
success: ToastMessage | ((data: T) => ToastMessage);
error: ToastMessage | ((error: unknown) => ToastMessage);
@@ -73,107 +74,111 @@ const icons: Record = {
warning: Warning
};
-const Toast = ({ closable = true, action, cancel, ...props }: ToastProps) => {
- const message = typeof props.message === 'function' ? props.message(props.id) : props.message;
+const Toast = forwardRef(
+ ({ closable = true, action, cancel, ...props }, ref) => {
+ const message =
+ typeof props.message === 'function' ? props.message(props.id) : props.message;
- const title =
- message && typeof message === 'object' && 'title' in message ? message.title : message;
+ const title =
+ message && typeof message === 'object' && 'title' in message ? message.title : message;
- const body =
- message && typeof message === 'object' && 'body' in message ? message.body : undefined;
+ const body =
+ message && typeof message === 'object' && 'body' in message ? message.body : undefined;
+
+ const typeIcon = (type: ToastType) => {
+ const Icon = icons[type];
+ return (
+
+ );
+ };
- const typeIcon = (type: ToastType) => {
- const Icon = icons[type];
return (
-
+ {(props.icon || props.type) && (
+
+ {props.icon || (props.type && typeIcon(props.type))}
+
)}
- />
- );
- };
- return (
-
- {(props.icon || props.type) && (
-
- {props.icon || (props.type && typeIcon(props.type))}
+
+ {title && (
+
+ {title}
+
+ )}
+
+ {body && (
+
+ {body}
+
+ )}
+
+ {(action || cancel) && (
+
+ {action && (
+
+ )}
+
+ {cancel && (
+
+ )}
+
+ )}
- )}
-
- {title && (
-
- {title}
-
- )}
-
- {body && (
-
- {body}
-
- )}
-
- {(action || cancel) && (
-
- {action && (
-
- )}
-
- {cancel && (
-
- )}
-
+ {closable && (
+
)}
-
- {closable && (
-
- )}
-
- );
-};
+ );
+ }
+);
interface PromiseToastProps
extends Pick<
@@ -244,6 +249,7 @@ const PromiseToast = ({
const renderToast = (
message: ToastMessage | ((id: ToastId) => ToastMessage),
{
+ ref,
type,
icon,
action,
@@ -259,6 +265,7 @@ const renderToast = (
(id) => (