2025-10-07 20:12:49 +02:00
|
|
|
import { useState, useRef, useCallback } from 'react';
|
2024-05-02 08:48:26 +02:00
|
|
|
import { Import } from 'lucide-react';
|
2025-10-07 14:47:21 -04:00
|
|
|
import { useQueryClient } from '@tanstack/react-query';
|
2026-04-01 17:20:39 -04:00
|
|
|
import type { TStartupConfig } from 'librechat-data-provider';
|
2025-10-07 20:12:49 +02:00
|
|
|
import { Spinner, useToastContext, Label, Button } from '@librechat/client';
|
2026-04-01 17:20:39 -04:00
|
|
|
import { startupConfigKey, useUploadConversationsMutation } from '~/data-provider';
|
2025-10-07 20:12:49 +02:00
|
|
|
import { NotificationSeverity } from '~/common';
|
2025-01-12 12:57:10 -05:00
|
|
|
import { useLocalize } from '~/hooks';
|
2025-10-07 20:12:49 +02:00
|
|
|
import { cn, logger } from '~/utils';
|
2024-05-02 08:48:26 +02:00
|
|
|
|
|
|
|
|
function ImportConversations() {
|
|
|
|
|
const localize = useLocalize();
|
2025-10-28 09:36:03 -04:00
|
|
|
const queryClient = useQueryClient();
|
2024-05-02 08:48:26 +02:00
|
|
|
const { showToast } = useToastContext();
|
2025-10-28 09:36:03 -04:00
|
|
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
2025-10-07 20:12:49 +02:00
|
|
|
const [isUploading, setIsUploading] = useState(false);
|
|
|
|
|
|
|
|
|
|
const handleSuccess = useCallback(() => {
|
|
|
|
|
showToast({
|
|
|
|
|
message: localize('com_ui_import_conversation_success'),
|
|
|
|
|
status: NotificationSeverity.SUCCESS,
|
|
|
|
|
});
|
|
|
|
|
setIsUploading(false);
|
|
|
|
|
}, [localize, showToast]);
|
|
|
|
|
|
|
|
|
|
const handleError = useCallback(
|
|
|
|
|
(error: unknown) => {
|
|
|
|
|
logger.error('Import error:', error);
|
|
|
|
|
setIsUploading(false);
|
|
|
|
|
|
|
|
|
|
const isUnsupportedType = error?.toString().includes('Unsupported import type');
|
|
|
|
|
|
|
|
|
|
showToast({
|
|
|
|
|
message: localize(
|
|
|
|
|
isUnsupportedType
|
|
|
|
|
? 'com_ui_import_conversation_file_type_error'
|
|
|
|
|
: 'com_ui_import_conversation_error',
|
|
|
|
|
),
|
|
|
|
|
status: NotificationSeverity.ERROR,
|
|
|
|
|
});
|
2024-05-02 08:48:26 +02:00
|
|
|
},
|
2025-10-07 20:12:49 +02:00
|
|
|
[localize, showToast],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const uploadFile = useUploadConversationsMutation({
|
|
|
|
|
onSuccess: handleSuccess,
|
|
|
|
|
onError: handleError,
|
|
|
|
|
onMutate: () => setIsUploading(true),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const handleFileUpload = useCallback(
|
|
|
|
|
async (file: File) => {
|
|
|
|
|
try {
|
2026-04-01 17:20:39 -04:00
|
|
|
const startupConfig = queryClient.getQueryData<TStartupConfig>(startupConfigKey(true));
|
2025-10-28 09:36:03 -04:00
|
|
|
const maxFileSize = startupConfig?.conversationImportMaxFileSize;
|
2025-10-07 14:47:21 -04:00
|
|
|
if (maxFileSize && file.size > maxFileSize) {
|
|
|
|
|
const size = (maxFileSize / (1024 * 1024)).toFixed(2);
|
|
|
|
|
showToast({
|
|
|
|
|
message: localize('com_error_files_upload_too_large', { 0: size }),
|
|
|
|
|
status: NotificationSeverity.ERROR,
|
|
|
|
|
});
|
|
|
|
|
setIsUploading(false);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-07 20:12:49 +02:00
|
|
|
const formData = new FormData();
|
|
|
|
|
formData.append('file', file, encodeURIComponent(file.name || 'File'));
|
|
|
|
|
uploadFile.mutate(formData);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
logger.error('File processing error:', error);
|
|
|
|
|
setIsUploading(false);
|
2024-05-02 08:48:26 +02:00
|
|
|
showToast({
|
2025-10-07 20:12:49 +02:00
|
|
|
message: localize('com_ui_import_conversation_upload_error'),
|
|
|
|
|
status: NotificationSeverity.ERROR,
|
2024-05-02 08:48:26 +02:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
},
|
2025-10-28 09:36:03 -04:00
|
|
|
[uploadFile, showToast, localize, queryClient],
|
2025-10-07 20:12:49 +02:00
|
|
|
);
|
2024-05-02 08:48:26 +02:00
|
|
|
|
2025-10-07 20:12:49 +02:00
|
|
|
const handleFileChange = useCallback(
|
|
|
|
|
(event: React.ChangeEvent<HTMLInputElement>) => {
|
|
|
|
|
const file = event.target.files?.[0];
|
|
|
|
|
if (file) {
|
2025-10-07 14:47:21 -04:00
|
|
|
setIsUploading(true);
|
2025-10-07 20:12:49 +02:00
|
|
|
handleFileUpload(file);
|
|
|
|
|
}
|
|
|
|
|
event.target.value = '';
|
|
|
|
|
},
|
|
|
|
|
[handleFileUpload],
|
|
|
|
|
);
|
2024-05-02 08:48:26 +02:00
|
|
|
|
2025-10-07 20:12:49 +02:00
|
|
|
const handleImportClick = useCallback(() => {
|
2024-09-10 10:11:39 -09:00
|
|
|
fileInputRef.current?.click();
|
2025-10-07 20:12:49 +02:00
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const handleKeyDown = useCallback(
|
|
|
|
|
(event: React.KeyboardEvent<HTMLButtonElement>) => {
|
|
|
|
|
if (event.key === 'Enter' || event.key === ' ') {
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
handleImportClick();
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
[handleImportClick],
|
|
|
|
|
);
|
2024-09-10 10:11:39 -09:00
|
|
|
|
2025-10-07 20:12:49 +02:00
|
|
|
const isImportDisabled = isUploading;
|
2024-09-10 10:11:39 -09:00
|
|
|
|
2024-05-02 08:48:26 +02:00
|
|
|
return (
|
|
|
|
|
<div className="flex items-center justify-between">
|
2025-10-07 20:12:49 +02:00
|
|
|
<Label id="import-conversation-label">{localize('com_ui_import_conversation_info')}</Label>
|
|
|
|
|
<Button
|
|
|
|
|
variant="outline"
|
2024-09-10 10:11:39 -09:00
|
|
|
onClick={handleImportClick}
|
|
|
|
|
onKeyDown={handleKeyDown}
|
2025-10-07 20:12:49 +02:00
|
|
|
disabled={isImportDisabled}
|
2025-02-18 01:09:36 +01:00
|
|
|
aria-label={localize('com_ui_import')}
|
2025-10-07 20:12:49 +02:00
|
|
|
aria-labelledby="import-conversation-label"
|
2024-09-10 10:11:39 -09:00
|
|
|
>
|
2025-10-07 20:12:49 +02:00
|
|
|
{isUploading ? (
|
🪟 feat: DataTable update + Various UI enhancements (#9698)
* 🎨 feat: Enhance Import Conversations UI with loading state and new localization key
* fix: Correct pluralization in selected items message in translation.json
* Refactor Chat Input File Table Headers to Use SortFilterHeader Component
- Replaced button-based sorting headers in the Chat Input Files Table with a new SortFilterHeader component for better code organization and consistency.
- Updated the header for filename, updatedAt, and bytes columns to utilize the new component.
Enhance Navigation Component with Skeleton Loading States
- Added Skeleton loading states to the Nav component for better user experience during data fetching.
- Updated Suspense fallbacks for AgentMarketplaceButton and BookmarkNav components to display Skeletons.
Refactor Avatar Component for Improved UI
- Enhanced the Avatar component by adding a Label for drag-and-drop functionality.
- Improved styling and structure for the file upload area.
Update Shared Links Component for Better Error Handling and Sorting
- Improved error handling in the Shared Links component for fetching next pages and deleting shared links.
- Simplified the header rendering for sorting columns and added sorting functionality to the title and createdAt columns.
Refactor Archived Chats Component
- Merged ArchivedChats and ArchivedChatsTable components into a single ArchivedChats component for better maintainability.
- Implemented sorting and searching functionality with debouncing for improved performance.
- Enhanced the UI with better loading states and error handling.
Update DataTable Component for Sorting Icons
- Added sorting icons (ChevronUp, ChevronDown, ChevronsUpDown) to the DataTable headers for better visual feedback on sorting state.
Localization Updates
- Updated translation.json to fix missing translations and improve existing ones for better user experience.
* ✨ feat: Update DataTable component to streamline props and enhance sorting icons
* fix: TS issues
* feat: polish and redefine DataTable + shared links and archived chats
* feat: enhance DataTable with column pinning and improve sorting functionality
* feat: enhance deepEqual function for array support and improve column style stability
* refactor: DataTable and ArchivedChats; fix: sorting ArchivedChats API
* feat(DataTable): Implement new DataTable component with hooks and optimized features
- Added DataTable component with support for virtual scrolling, row selection, and customizable columns.
- Introduced hooks for debouncing search input, managing row selection, and calculating column styles.
- Enhanced accessibility with keyboard navigation and selection checkboxes.
- Implemented skeleton loading state for better user experience during data fetching.
- Added DataTableSearch component for filtering data with debounced input.
- Created utility logger for improved debugging in development.
- Updated translations to support new UI elements and actions.
* refactor: update SharedLinks and ArchivedChats to use desktopOnly instead of hideOnMobile; remove unused DataTableColumnHeader component
* fix: ensure desktopOnly columns are hidden on mobile in DataTable
* refactor: reorganize imports in DataTable components and update index exports
* refactor: improve styling and animations in Artifacts, ArtifactsSubMenu, and MCPSubMenu components; update border-radius in style.css
* refactor(Artifacts): enhance button toggle functionality and manage expanded state with useEffect
* refactor: comment out desktopOnly property in SharedLinks and ArchivedChats components; update translation.json with new keys for link actions
* refactor(DataTable): streamline column visibility logic and enhance type definitions; improve cleanup timers and optimize rendering
* refactor(DataTable): enhance type definitions for processed data rows and update custom actions renderer type
* refactor(DataTable): optimize processed data handling and improve warning for missing IDs; streamline DataTableComponents imports
* refactor(DataTable): enhance accessibility features and improve localization for selection and loading states
* refactor: improve padding in dialog content and enhance row selection functionality in ArchivedChats and DataTable components
* refactor(DataTable): remove unnecessary role and tabindex attributes from select all button for improved accessibility
* refactor(translation): remove outdated error messages and unused UI strings for cleaner localization
* refactor(DataTable): enhance virtualization and scrolling performance with dynamic overscan adjustments
* refactor(DataTableErrorBoundary): enhance error handling and localization support
* refactor(DataTable): improve column sizing and visibility handling; remove deprecated features
* refactor: enhance UI components with improved class handling and state management
* refactor(DataTable): improve column width handling and responsiveness; disable row selection
* refactor(DataTable): enhance accessibility with row header support and improve column visibility handling
* chore(DataTable): comments update
* refactor(Table): add unwrapped prop for direct table rendering; adjust minWidth calculation for responsiveness
* refactor(DataTable): simplify search handling by removing unnecessary trimming; adjust column width handling for better responsiveness
* refactor(translation): remove redundant drag and drop UI text for clarity
* refactor(parsers): change uiResources to a constant and streamline artifacts handling
* chore: remove unused file, bump @librechat/client to 0.3.2; fix(SharedLinks): missing import;
* refactor: change button variant from destructive to ghost for delete actions in SharedLinks and ArchivedChats components
* refactor(DataTable): simplify aria-sort assignment for better readability
* refactor(DataTable): update aria-label and ariaLabel to use indexed placeholder for localization
* refactor(translation): update no data messages for consistency
* Refactor code structure for improved readability and maintainability
* chore: restore linting fixes
* chore: restore linting fixes 2; refactor: remove unused translation keys
* feat(tests): add unit tests for DataTable components and error handling
- Implement tests for SelectionCheckbox and SkeletonRows components in DataTable.
- Add tests for DataTableErrorBoundary to ensure proper error handling and UI rendering.
- Create tests for DataTableSearch to validate search functionality and accessibility.
- Update DialogTemplate tests to reflect hardcoded cancel text.
- Remove redundant IntersectionObserver mock in SplitText tests.
- Unmock react-i18next in Translation tests to validate actual i18n functionality.
* refactor: Remove jest-environment-jsdom dependency from package.json; fix: reset package-lock
* chore: revert lint fixes
* chore: clean up package.json by removing unused devDependencies and redundant test scripts
* chore: update package dependencies in package.json and package-lock.json
- Added new devDependencies: @babel/core, @babel/preset-env, @babel/preset-react, @babel/preset-typescript, @tanstack/react-table, @tanstack/react-virtual, @testing-library/jest-dom, identity-obj-proxy, jest, jest-environment-jsdom, and lucide-react.
- Updated existing devDependencies to their latest versions.
- Added new module @asamuzakjp/css-color to package-lock.json with its dependencies.
- Updated version of @babel/plugin-transform-destructuring and added @babel/plugin-transform-explicit-resource-management in package-lock.json.
---------
Co-authored-by: Danny Avila <danny@librechat.ai>
2025-12-10 02:08:41 +01:00
|
|
|
<>
|
|
|
|
|
<Spinner className="mr-1 w-4" />
|
|
|
|
|
<span>{localize('com_ui_importing')}</span>
|
|
|
|
|
</>
|
2025-10-07 20:12:49 +02:00
|
|
|
) : (
|
🪟 feat: DataTable update + Various UI enhancements (#9698)
* 🎨 feat: Enhance Import Conversations UI with loading state and new localization key
* fix: Correct pluralization in selected items message in translation.json
* Refactor Chat Input File Table Headers to Use SortFilterHeader Component
- Replaced button-based sorting headers in the Chat Input Files Table with a new SortFilterHeader component for better code organization and consistency.
- Updated the header for filename, updatedAt, and bytes columns to utilize the new component.
Enhance Navigation Component with Skeleton Loading States
- Added Skeleton loading states to the Nav component for better user experience during data fetching.
- Updated Suspense fallbacks for AgentMarketplaceButton and BookmarkNav components to display Skeletons.
Refactor Avatar Component for Improved UI
- Enhanced the Avatar component by adding a Label for drag-and-drop functionality.
- Improved styling and structure for the file upload area.
Update Shared Links Component for Better Error Handling and Sorting
- Improved error handling in the Shared Links component for fetching next pages and deleting shared links.
- Simplified the header rendering for sorting columns and added sorting functionality to the title and createdAt columns.
Refactor Archived Chats Component
- Merged ArchivedChats and ArchivedChatsTable components into a single ArchivedChats component for better maintainability.
- Implemented sorting and searching functionality with debouncing for improved performance.
- Enhanced the UI with better loading states and error handling.
Update DataTable Component for Sorting Icons
- Added sorting icons (ChevronUp, ChevronDown, ChevronsUpDown) to the DataTable headers for better visual feedback on sorting state.
Localization Updates
- Updated translation.json to fix missing translations and improve existing ones for better user experience.
* ✨ feat: Update DataTable component to streamline props and enhance sorting icons
* fix: TS issues
* feat: polish and redefine DataTable + shared links and archived chats
* feat: enhance DataTable with column pinning and improve sorting functionality
* feat: enhance deepEqual function for array support and improve column style stability
* refactor: DataTable and ArchivedChats; fix: sorting ArchivedChats API
* feat(DataTable): Implement new DataTable component with hooks and optimized features
- Added DataTable component with support for virtual scrolling, row selection, and customizable columns.
- Introduced hooks for debouncing search input, managing row selection, and calculating column styles.
- Enhanced accessibility with keyboard navigation and selection checkboxes.
- Implemented skeleton loading state for better user experience during data fetching.
- Added DataTableSearch component for filtering data with debounced input.
- Created utility logger for improved debugging in development.
- Updated translations to support new UI elements and actions.
* refactor: update SharedLinks and ArchivedChats to use desktopOnly instead of hideOnMobile; remove unused DataTableColumnHeader component
* fix: ensure desktopOnly columns are hidden on mobile in DataTable
* refactor: reorganize imports in DataTable components and update index exports
* refactor: improve styling and animations in Artifacts, ArtifactsSubMenu, and MCPSubMenu components; update border-radius in style.css
* refactor(Artifacts): enhance button toggle functionality and manage expanded state with useEffect
* refactor: comment out desktopOnly property in SharedLinks and ArchivedChats components; update translation.json with new keys for link actions
* refactor(DataTable): streamline column visibility logic and enhance type definitions; improve cleanup timers and optimize rendering
* refactor(DataTable): enhance type definitions for processed data rows and update custom actions renderer type
* refactor(DataTable): optimize processed data handling and improve warning for missing IDs; streamline DataTableComponents imports
* refactor(DataTable): enhance accessibility features and improve localization for selection and loading states
* refactor: improve padding in dialog content and enhance row selection functionality in ArchivedChats and DataTable components
* refactor(DataTable): remove unnecessary role and tabindex attributes from select all button for improved accessibility
* refactor(translation): remove outdated error messages and unused UI strings for cleaner localization
* refactor(DataTable): enhance virtualization and scrolling performance with dynamic overscan adjustments
* refactor(DataTableErrorBoundary): enhance error handling and localization support
* refactor(DataTable): improve column sizing and visibility handling; remove deprecated features
* refactor: enhance UI components with improved class handling and state management
* refactor(DataTable): improve column width handling and responsiveness; disable row selection
* refactor(DataTable): enhance accessibility with row header support and improve column visibility handling
* chore(DataTable): comments update
* refactor(Table): add unwrapped prop for direct table rendering; adjust minWidth calculation for responsiveness
* refactor(DataTable): simplify search handling by removing unnecessary trimming; adjust column width handling for better responsiveness
* refactor(translation): remove redundant drag and drop UI text for clarity
* refactor(parsers): change uiResources to a constant and streamline artifacts handling
* chore: remove unused file, bump @librechat/client to 0.3.2; fix(SharedLinks): missing import;
* refactor: change button variant from destructive to ghost for delete actions in SharedLinks and ArchivedChats components
* refactor(DataTable): simplify aria-sort assignment for better readability
* refactor(DataTable): update aria-label and ariaLabel to use indexed placeholder for localization
* refactor(translation): update no data messages for consistency
* Refactor code structure for improved readability and maintainability
* chore: restore linting fixes
* chore: restore linting fixes 2; refactor: remove unused translation keys
* feat(tests): add unit tests for DataTable components and error handling
- Implement tests for SelectionCheckbox and SkeletonRows components in DataTable.
- Add tests for DataTableErrorBoundary to ensure proper error handling and UI rendering.
- Create tests for DataTableSearch to validate search functionality and accessibility.
- Update DialogTemplate tests to reflect hardcoded cancel text.
- Remove redundant IntersectionObserver mock in SplitText tests.
- Unmock react-i18next in Translation tests to validate actual i18n functionality.
* refactor: Remove jest-environment-jsdom dependency from package.json; fix: reset package-lock
* chore: revert lint fixes
* chore: clean up package.json by removing unused devDependencies and redundant test scripts
* chore: update package dependencies in package.json and package-lock.json
- Added new devDependencies: @babel/core, @babel/preset-env, @babel/preset-react, @babel/preset-typescript, @tanstack/react-table, @tanstack/react-virtual, @testing-library/jest-dom, identity-obj-proxy, jest, jest-environment-jsdom, and lucide-react.
- Updated existing devDependencies to their latest versions.
- Added new module @asamuzakjp/css-color to package-lock.json with its dependencies.
- Updated version of @babel/plugin-transform-destructuring and added @babel/plugin-transform-explicit-resource-management in package-lock.json.
---------
Co-authored-by: Danny Avila <danny@librechat.ai>
2025-12-10 02:08:41 +01:00
|
|
|
<>
|
|
|
|
|
<Import className="mr-1 flex h-4 w-4 items-center stroke-1" aria-hidden="true" />
|
|
|
|
|
<span>{localize('com_ui_import')}</span>
|
|
|
|
|
</>
|
🌿 feat: Fork Messages/Conversations (#2617)
* typedef for ImportBatchBuilder
* feat: first pass, fork conversations
* feat: fork - getMessagesUpToTargetLevel
* fix: additional tests and fix getAllMessagesUpToParent
* chore: arrow function return
* refactor: fork 3 options
* chore: remove unused genbuttons
* chore: remove unused hover buttons code
* feat: fork first pass
* wip: fork remember setting
* style: user icon
* chore: move clear chats to data tab
* WIP: fork UI options
* feat: data-provider fork types/services/vars and use generic MutationOptions
* refactor: use single param for fork option, use enum, fix mongo errors, use Date.now(), add records flag for testing, use endpoint from original convo and messages, pass originalConvo to finishConversation
* feat: add fork mutation hook and consolidate type imports
* refactor: use enum
* feat: first pass, fork mutation
* chore: add enum for target level fork option
* chore: add enum for target level fork option
* show toast when checking remember selection
* feat: splitAtTarget
* feat: split at target option
* feat: navigate to new fork, show toasts, set result query data
* feat: hover info for all fork options
* refactor: add Messages settings tab
* fix(Fork): remember text info
* ci: test for single message and is target edge case
* feat: additional tests for getAllMessagesUpToParent
* ci: additional tests and cycle detection for getMessagesUpToTargetLevel
* feat: circular dependency checks for getAllMessagesUpToParent
* fix: getMessagesUpToTargetLevel circular dep. check
* ci: more tests for getMessagesForConversation
* style: hover text for checkbox fork items
* refactor: add statefulness to conversation import
2024-05-05 11:48:20 -04:00
|
|
|
)}
|
2025-10-07 20:12:49 +02:00
|
|
|
</Button>
|
2024-09-10 10:11:39 -09:00
|
|
|
<input
|
|
|
|
|
ref={fileInputRef}
|
|
|
|
|
type="file"
|
|
|
|
|
className={cn('hidden')}
|
|
|
|
|
accept=".json"
|
|
|
|
|
onChange={handleFileChange}
|
|
|
|
|
aria-hidden="true"
|
|
|
|
|
/>
|
2024-05-02 08:48:26 +02:00
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default ImportConversations;
|