97 lines
3.1 KiB
TypeScript
97 lines
3.1 KiB
TypeScript
import React, { useState } from 'react';
|
|
import { IoIosEye } from 'react-icons/io';
|
|
import { useLanguage } from '../../../../contexts/LanguageContext';
|
|
import { FilePreview } from '../../../FilePreview/FilePreview';
|
|
import styles from '../ActionButton.module.css';
|
|
|
|
export interface ViewActionButtonProps<T = any> {
|
|
row: T;
|
|
onView: (row: T) => Promise<void> | void;
|
|
disabled?: boolean | { disabled: boolean; message?: string };
|
|
loading?: boolean;
|
|
className?: string;
|
|
title?: string;
|
|
isViewing?: boolean;
|
|
hookData?: any; // Contains all hook data including operations
|
|
// Field mappings
|
|
idField?: string; // Field name for the unique identifier
|
|
nameField?: string; // Field name for display name
|
|
typeField?: string; // Field name for type/mime type
|
|
loadingStateName?: string; // Name of the loading state in hookData
|
|
}
|
|
|
|
export function ViewActionButton<T = any>({
|
|
row,
|
|
onView,
|
|
disabled = false,
|
|
loading = false,
|
|
className = '',
|
|
title,
|
|
isViewing = false,
|
|
hookData,
|
|
idField = 'id',
|
|
nameField = 'name',
|
|
typeField = 'type',
|
|
loadingStateName = 'previewingFiles'
|
|
}: ViewActionButtonProps<T>) {
|
|
const { t } = useLanguage();
|
|
const [internalLoading, setInternalLoading] = useState(false);
|
|
const [isPopupOpen, setIsPopupOpen] = useState(false);
|
|
|
|
// Extract disabled state and tooltip message
|
|
const isDisabled = typeof disabled === 'boolean' ? disabled : disabled?.disabled || false;
|
|
const disabledMessage = typeof disabled === 'object' ? disabled?.message : undefined;
|
|
|
|
const handleClick = async (e: React.MouseEvent) => {
|
|
e.stopPropagation();
|
|
if (!isDisabled && !loading && !isViewing && !internalLoading) {
|
|
setInternalLoading(true);
|
|
try {
|
|
|
|
// Call the onView callback if provided
|
|
if (onView) {
|
|
await onView(row);
|
|
}
|
|
// Open the file preview
|
|
setIsPopupOpen(true);
|
|
} finally {
|
|
setInternalLoading(false);
|
|
}
|
|
}
|
|
};
|
|
|
|
const buttonTitle = title || t('files.action.preview', 'Preview');
|
|
// Use hookData viewing state if available, otherwise use passed isViewing
|
|
const loadingState = hookData?.[loadingStateName];
|
|
const actualIsViewing = loadingState?.has((row as any)[idField]) || isViewing;
|
|
const isLoading = loading || actualIsViewing || internalLoading;
|
|
|
|
// Determine the final button title (tooltip)
|
|
const finalTitle = isDisabled && disabledMessage ? disabledMessage : buttonTitle;
|
|
|
|
return (
|
|
<>
|
|
<button
|
|
onClick={handleClick}
|
|
className={`${styles.actionButton} ${styles.view} ${isLoading ? styles.loading : ''} ${isDisabled ? styles.disabled : ''} ${className}`}
|
|
title={finalTitle}
|
|
disabled={isDisabled || isLoading}
|
|
>
|
|
<span className={styles.actionIcon}>
|
|
{isLoading ? '⏳' : <IoIosEye />}
|
|
</span>
|
|
</button>
|
|
|
|
{/* File Preview Component */}
|
|
<FilePreview
|
|
isOpen={isPopupOpen}
|
|
onClose={() => setIsPopupOpen(false)}
|
|
fileId={(row as any)[idField]}
|
|
fileName={(row as any)[nameField] || 'Unknown Item'}
|
|
mimeType={(row as any)[typeField]}
|
|
/>
|
|
</>
|
|
);
|
|
}
|
|
|
|
export default ViewActionButton;
|