apps/chat/src/components/Chatbar/ChatbarSettings.tsx (227 lines of code) (raw):
import {
IconFileArrowLeft,
IconFileArrowRight,
IconPaperclip,
IconScale,
IconSquareCheck,
IconSquareOff,
IconTrashX,
} from '@tabler/icons-react';
import { useCallback, useMemo, useState } from 'react';
import { useTranslation } from 'next-i18next';
import { getConversationRootId } from '@/src/utils/app/id';
import { FeatureType } from '@/src/types/common';
import { SupportedExportFormats } from '@/src/types/import-export';
import { DisplayMenuItemProps } from '@/src/types/menu';
import { Translation } from '@/src/types/translation';
import {
ConversationsActions,
ConversationsSelectors,
} from '@/src/store/conversations/conversations.reducers';
import { useAppDispatch, useAppSelector } from '@/src/store/hooks';
import { ImportExportActions } from '@/src/store/import-export/importExport.reducers';
import { SettingsSelectors } from '@/src/store/settings/settings.reducers';
import { UIActions, UISelectors } from '@/src/store/ui/ui.reducers';
import { DEFAULT_CONVERSATION_NAME } from '@/src/constants/default-ui-settings';
import { PINNED_CONVERSATIONS_SECTION_NAME } from '@/src/constants/sections';
import { ConfirmDialog } from '@/src/components/Common/ConfirmDialog';
import SidebarMenu from '@/src/components/Common/SidebarMenu';
import { FileManagerModal } from '@/src/components/Files/FileManagerModal';
import { Import } from '@/src/components/Settings/Import';
import FolderPlus from '@/public/images/icons/folder-plus.svg';
import { Feature } from '@epam/ai-dial-shared';
export const ChatbarSettings = () => {
const { t } = useTranslation(Translation.SideBar);
const [isClearModalOpen, setIsClearModalOpen] = useState(false);
const dispatch = useAppDispatch();
const isStreaming = useAppSelector(
ConversationsSelectors.selectIsConversationsStreaming,
);
const enabledFeatures = useAppSelector(
SettingsSelectors.selectEnabledFeatures,
);
const [isSelectFilesDialogOpened, setIsSelectFilesDialogOpened] =
useState(false);
const maximumAttachmentsAmount = useAppSelector(
ConversationsSelectors.selectMaximumAttachmentsAmount,
);
const isMyItemsExist = useAppSelector(
ConversationsSelectors.selectDoesAnyMyItemExist,
);
const isSelectMode = useAppSelector(
ConversationsSelectors.selectIsSelectMode,
);
const collapsedSectionsSelector = useMemo(
() => UISelectors.selectCollapsedSections(FeatureType.Chat),
[],
);
const collapsedSections = useAppSelector(collapsedSectionsSelector);
const handleToggleCompare = useCallback(() => {
dispatch(
ConversationsActions.createNewConversations({
names: [DEFAULT_CONVERSATION_NAME, DEFAULT_CONVERSATION_NAME],
}),
);
}, [dispatch]);
const jsonImportHandler = useCallback(
(jsonContent: SupportedExportFormats) => {
dispatch(
ImportExportActions.importConversations({
data: jsonContent as SupportedExportFormats,
}),
);
},
[dispatch],
);
const zipImportHandler = useCallback(
(zipFile: File) => {
dispatch(ImportExportActions.importZipConversations({ zipFile }));
},
[dispatch],
);
const deleteTerm = isSelectMode ? 'selected' : 'all';
const menuItems: DisplayMenuItemProps[] = useMemo(
() => [
{
name: t('Select all'),
dataQa: 'select-all',
Icon: IconSquareCheck,
onClick: () => {
dispatch(ConversationsActions.setAllChosenConversations());
},
display: isMyItemsExist,
disabled: isStreaming,
},
{
name: t('Unselect all'),
dataQa: 'unselect-all',
Icon: IconSquareOff,
onClick: () => {
dispatch(ConversationsActions.resetChosenConversations());
},
display: isSelectMode,
disabled: isStreaming,
},
{
name: t('Create new folder'),
dataQa: 'create-folder',
Icon: FolderPlus,
onClick: () => {
dispatch(
UIActions.setCollapsedSections({
featureType: FeatureType.Chat,
collapsedSections: collapsedSections.filter(
(section) => section !== PINNED_CONVERSATIONS_SECTION_NAME,
),
}),
);
dispatch(
ConversationsActions.createFolder({
parentId: getConversationRootId(),
}),
);
},
display: !isSelectMode,
disabled: isStreaming,
},
{
name: t('Import conversations'),
onClick: (importArgs: unknown) => {
const typedArgs = importArgs as { content: unknown; zip?: boolean };
if (!typedArgs.zip) {
jsonImportHandler(typedArgs.content as SupportedExportFormats);
}
if (typedArgs.zip) {
zipImportHandler(typedArgs.content as File);
}
},
Icon: IconFileArrowLeft,
dataQa: 'import',
CustomTriggerRenderer: Import,
display: !isSelectMode,
disabled: isStreaming,
},
{
name: t('Export conversations without attachments'),
dataQa: 'export',
className: 'max-w-[158px]',
Icon: IconFileArrowRight,
display: isMyItemsExist && !isSelectMode,
onClick: () => {
dispatch(ImportExportActions.exportConversations());
},
disabled: isStreaming,
},
{
name: t(`Delete ${deleteTerm} conversations`),
display: isMyItemsExist,
dataQa: 'delete-entities',
Icon: IconTrashX,
onClick: () => {
setIsClearModalOpen(true);
},
disabled: isStreaming,
},
{
name: t('Compare mode'),
dataQa: 'compare',
Icon: IconScale,
disabled: isStreaming,
onClick: () => {
handleToggleCompare();
},
display: !isSelectMode,
},
{
name: t('Attachments'),
display:
enabledFeatures.has(Feature.AttachmentsManager) && !isSelectMode,
dataQa: 'attachments',
Icon: IconPaperclip,
disabled: isStreaming,
onClick: () => {
setIsSelectFilesDialogOpened(true);
},
},
],
[
t,
isMyItemsExist,
isStreaming,
isSelectMode,
deleteTerm,
enabledFeatures,
dispatch,
collapsedSections,
jsonImportHandler,
zipImportHandler,
handleToggleCompare,
],
);
return (
<>
<SidebarMenu menuItems={menuItems} featureType={FeatureType.Chat} />
{isSelectFilesDialogOpened && (
<FileManagerModal
isOpen
allowedTypes={['*/*']}
maximumAttachmentsAmount={maximumAttachmentsAmount}
onClose={() => {
setIsSelectFilesDialogOpened(false);
}}
headerLabel={t('Manage attachments')}
forceShowSelectCheckBox
forceHideSelectFolders
showTooltip
/>
)}
<ConfirmDialog
isOpen={isClearModalOpen}
heading={t(`Confirm deleting ${deleteTerm} conversations`)}
description={
t(
`Are you sure that you want to delete ${deleteTerm} conversations?`,
) || ''
}
confirmLabel={t('Delete')}
cancelLabel={t('Cancel')}
onClose={(result) => {
setIsClearModalOpen(false);
if (result) {
if (!isSelectMode) {
dispatch(ConversationsActions.clearConversations());
} else {
dispatch(ConversationsActions.deleteChosenConversations());
}
}
}}
/>
</>
);
};