added multiselect logic, implemented trash and multi trash

This commit is contained in:
subnub
2024-06-27 23:31:45 -04:00
parent 99201318b5
commit 9f0821253d
28 changed files with 707 additions and 63 deletions
+54 -12
View File
@@ -5,24 +5,31 @@ import {
deleteFileAPI,
renameFileAPI,
downloadFileAPI,
trashFileAPI,
} from "../../api/filesAPI";
import { useFilesClient, useQuickFilesClient } from "../../hooks/files";
import { useFoldersClient } from "../../hooks/folders";
import { useDispatch } from "react-redux";
import { setMoverID } from "../../actions/mover";
import { setShareSelected } from "../../actions/selectedItem";
import { deleteFolder, renameFolder } from "../../api/foldersAPI";
import {
deleteFolder,
renameFolder,
trashFolderAPI,
} from "../../api/foldersAPI";
import { useClickOutOfBounds } from "../../hooks/utils";
import { useAppDispatch } from "../../hooks/store";
import { setMultiSelectMode } from "../../reducers/selected";
const ContextMenu = (props) => {
const { invalidateFilesCache } = useFilesClient();
const { invalidateFoldersCache } = useFoldersClient();
const { invalidateQuickFilesCache } = useQuickFilesClient();
const { wrapperRef } = useClickOutOfBounds(props.closeContext);
const dispatch = useDispatch();
const dispatch = useAppDispatch();
const liClassname =
"flex w-full px-[20px] py-[12px] items-center font-normal text-[#637381] justify-start no-underline transition-all duration-400 ease-in-out text- hover:bg-[#f6f5fd] hover:text-[#3c85ee] hover:font-medium";
const spanClassname = "inline-flex mr-[18px]";
const spanClassname = "flex items-center justify-center mr-[18px]";
const renameItem = async () => {
props.closeContext();
@@ -67,32 +74,32 @@ const ContextMenu = (props) => {
props.closeContext();
if (!props.folderMode) {
const result = await Swal.fire({
title: "Confirm Deletion",
text: "You cannot undo this action",
title: "Move to trash?",
text: "Items in the trash will eventually be deleted.",
icon: "warning",
showCancelButton: true,
confirmButtonColor: "#3085d6",
cancelButtonColor: "#d33",
confirmButtonText: "Yes, delete",
confirmButtonText: "Yes",
});
if (result.value) {
await deleteFileAPI(props.file._id);
await trashFileAPI(props.file._id);
invalidateFilesCache();
invalidateQuickFilesCache();
}
} else {
const result = await Swal.fire({
title: "Confirm Deletion",
text: "You cannot undo this action",
title: "Move to trash?",
text: "Items in the trash will eventually be deleted.",
icon: "warning",
showCancelButton: true,
confirmButtonColor: "#3085d6",
cancelButtonColor: "#d33",
confirmButtonText: "Yes, delete",
confirmButtonText: "Yes",
});
if (result.value) {
await deleteFolder(props.folder._id, props.folder.parentList);
await trashFolderAPI(props.folder._id);
invalidateFoldersCache();
}
}
@@ -117,6 +124,29 @@ const ContextMenu = (props) => {
downloadFileAPI(props.file._id);
};
const selectItemMultiSelect = () => {
props.closeContext();
if (props.folderMode) {
dispatch(
setMultiSelectMode({
type: "folder",
id: props.folder._id,
file: null,
folder: props.folder,
})
);
} else {
dispatch(
setMultiSelectMode({
type: props.quickItemMode ? "quick-item" : "file",
id: props.file._id,
file: props.file,
folder: null,
})
);
}
};
return (
<div
onClick={props.stopPropagation}
@@ -136,6 +166,18 @@ const ContextMenu = (props) => {
}
>
<ul className="p-0 list-none m-0 ">
<li onClick={selectItemMultiSelect} className={liClassname}>
<a className="flex">
<span className={spanClassname}>
<img
src="/assets/checkbox-multiple-outline.svg"
alt="multiselect"
className="w-[19px] h-[20px]"
/>
</span>
Multi select
</a>
</li>
<li onClick={renameItem} className={liClassname}>
<a className="flex">
<span className={spanClassname}>
@@ -180,7 +222,7 @@ const ContextMenu = (props) => {
<span className={spanClassname}>
<img src="/assets/filesetting5.svg" alt="setting" />
</span>
Delete
Trash
</a>
</li>
</ul>
+36 -2
View File
@@ -3,9 +3,15 @@ import Folders from "../Folders";
import { useFiles } from "../../hooks/files";
import { useInfiniteScroll } from "../../hooks/infiniteScroll";
import Files from "../Files";
import { memo, useEffect, useState } from "react";
import { memo, useCallback, useEffect, useRef, useState } from "react";
import SpinnerPage from "../SpinnerPage";
import SearchBar from "../SearchBar";
import { useAppDispatch } from "../../hooks/store";
import { startAddFile } from "../../actions/files";
import { useParams } from "react-router-dom";
import classNames from "classnames";
import { useDragAndDrop } from "../../hooks/utils";
import MultiSelectBar from "../MultiSelectBar";
const DataForm = memo(() => {
const {
@@ -13,8 +19,10 @@ const DataForm = memo(() => {
isFetchingNextPage,
data: fileList,
} = useFiles();
const dispatch = useAppDispatch();
const { sentinelRef, reachedIntersect } = useInfiniteScroll();
const [initialLoad, setInitialLoad] = useState(true);
const params = useParams();
useEffect(() => {
if (initialLoad) {
@@ -28,8 +36,34 @@ const DataForm = memo(() => {
}
}, [reachedIntersect, initialLoad, isFetchingNextPage]);
const addFile = useCallback(
(file) => {
dispatch(startAddFile(file, params.id));
},
[params.id]
);
const {
isDraggingFile,
onDragDropEvent,
onDragEvent,
onDragEnterEvent,
stopDrag,
} = useDragAndDrop(addFile);
return (
<div className="w-full p-[65px_40px] overflow-y-scroll">
<div
className={classNames("w-full p-[17px_40px] overflow-y-scroll", {
"opacity-50": isDraggingFile,
})}
onDrop={onDragDropEvent}
onDragOver={onDragEvent}
onDragLeave={onDragEvent}
onDragEnter={onDragEnterEvent}
onMouseLeave={stopDrag}
>
<MultiSelectBar />
<QuickAccess />
<Folders />
+37 -9
View File
@@ -12,7 +12,7 @@ import { startSetSelectedItem } from "../../actions/selectedItem";
import { setPopupFile } from "../../actions/popupFile";
import bytes from "bytes";
import { useAppDispatch, useAppSelector } from "../../hooks/store";
import { setMainSelect } from "../../reducers/selected";
import { setMainSelect, setMultiSelectMode } from "../../reducers/selected";
const FileItem = React.memo((props) => {
const { file } = props;
@@ -20,6 +20,14 @@ const FileItem = React.memo((props) => {
if (state.selected.mainSection.type !== "file") return false;
return state.selected.mainSection.id === file._id;
});
const elementMultiSelected = useAppSelector((state) => {
if (!state.selected.multiSelectMode) return false;
const selected = state.selected.multiSelectMap[file._id];
return selected && selected.type === "file";
});
const multiSelectMode = useAppSelector(
(state) => state.selected.multiSelectMode
);
const listView = useSelector((state) => state.filter.listView);
const { image, hasThumbnail, imageOnError } = useThumbnail(
file.metadata.hasThumbnail,
@@ -58,6 +66,18 @@ const FileItem = React.memo((props) => {
// TODO: See if we can memoize this
const fileClick = () => {
if (multiSelectMode) {
dispatch(
setMultiSelectMode({
type: "file",
id: file._id,
file: file,
folder: null,
})
);
return;
}
const currentDate = Date.now();
if (!elementSelected) {
@@ -82,7 +102,7 @@ const FileItem = React.memo((props) => {
<tr
className={classNames(
"text-[14px] font-normal border-y",
!elementSelected
!elementSelected && !elementMultiSelected
? "text-[#212b36] hover:bg-[#f6f5fd]"
: "bg-[#3c85ee] animate text-white"
)}
@@ -137,7 +157,9 @@ const FileItem = React.memo((props) => {
<svg
className={classNames(
"w-4 h-4",
elementSelected ? "text-white" : "text-[#919eab]"
elementSelected || elementMultiSelected
? "text-white"
: "text-[#919eab]"
)}
aria-hidden="true"
focusable="false"
@@ -162,8 +184,10 @@ const FileItem = React.memo((props) => {
return (
<div
className={classNames(
"border rounded-md o transition-all duration-400 ease-in-out cursor-pointer flex items-center justify-center flex-col h-[125px] sm:h-[150px] animiate hover:border-[#3c85ee] overflow-hidden",
elementSelected ? "border-[#3c85ee]" : "border-[#ebe9f9]"
"border rounded-md o transition-all duration-400 ease-in-out cursor-pointer flex items-center justify-center flex-col h-[125px] sm:h-[150px] animiate hover:border-[#3c85ee] overflow-hidden bg-white",
elementSelected || elementMultiSelected
? "border-[#3c85ee]"
: "border-[#ebe9f9]"
)}
onClick={fileClick}
onContextMenu={onContextMenu}
@@ -175,7 +199,7 @@ const FileItem = React.memo((props) => {
<div onClick={clickStopPropagation}>
<ContextMenu
gridMode={true}
quickItemMode={true}
quickItemMode={false}
contextSelected={contextMenuState}
closeContext={closeContextMenu}
file={file}
@@ -221,7 +245,7 @@ const FileItem = React.memo((props) => {
<div
className={classNames(
"p-3 overflow-hidden text-ellipsis block w-full animate",
elementSelected
elementSelected || elementMultiSelected
? "bg-[#3c85ee] text-white"
: "bg-white text-[#637381]"
)}
@@ -229,7 +253,9 @@ const FileItem = React.memo((props) => {
<p
className={classNames(
"m-0 text-[14px] leading-[16px] font-normal max-w-full overflow-hidden text-ellipsis whitespace-nowrap animate",
elementSelected ? "text-white" : "text-[#212b36]"
elementSelected || elementMultiSelected
? "text-white"
: "text-[#212b36]"
)}
>
{formattedFilename}
@@ -237,7 +263,9 @@ const FileItem = React.memo((props) => {
<span
className={classNames(
"m-0 text-[#637381] font-normal max-w-full whitespace-nowrap text-xs animate hidden sm:block mt-1",
elementSelected ? "text-white" : "text-[#637381]"
elementSelected || elementMultiSelected
? "text-white"
: "text-[#637381]"
)}
>
Created {formattedCreatedDate}
+32 -7
View File
@@ -8,7 +8,7 @@ import { startSetSelectedItem } from "../../actions/selectedItem";
import mobilecheck from "../../utils/mobileCheck";
import moment from "moment";
import { useAppDispatch, useAppSelector } from "../../hooks/store";
import { setMainSelect } from "../../reducers/selected";
import { setMainSelect, setMultiSelectMode } from "../../reducers/selected";
const FolderItem = React.memo((props) => {
const { folder } = props;
@@ -16,6 +16,13 @@ const FolderItem = React.memo((props) => {
if (state.selected.mainSection.type !== "folder") return false;
return state.selected.mainSection.id === folder._id;
});
const elementMultiSelected = useAppSelector((state) => {
if (!state.selected.multiSelectMode) return false;
return state.selected.multiSelectMap[folder._id];
});
const multiSelectMode = useAppSelector(
(state) => state.selected.multiSelectMode
);
const lastSelected = useRef(0);
const navigate = useNavigate();
const dispatch = useAppDispatch();
@@ -30,6 +37,17 @@ const FolderItem = React.memo((props) => {
} = useContextMenu();
const folderClick = useCallback(() => {
if (multiSelectMode) {
dispatch(
setMultiSelectMode({
type: "folder",
id: folder._id,
file: null,
folder: folder,
})
);
return;
}
const currentDate = Date.now();
if (!elementSelected) {
@@ -58,14 +76,15 @@ const FolderItem = React.memo((props) => {
navigate,
folder._id,
elementSelected,
multiSelectMode,
]);
return (
<div
className={classNames(
"p-[12px] border border-[#ebe9f9] rounded-[4px] overflow-hidden cursor-pointer animate ",
"p-[12px] border border-[#ebe9f9] rounded-[4px] overflow-hidden cursor-pointer animate hover:border-[#3c85ee]",
{
"bg-[#3c85ee]": elementSelected,
"bg-[#3c85ee]": elementSelected || elementMultiSelected,
}
)}
onClick={folderClick}
@@ -91,7 +110,9 @@ const FolderItem = React.memo((props) => {
<svg
className={classNames(
"w-[40px] h-[40px]",
elementSelected ? "text-white" : "text-[#3c85ee]"
elementSelected || elementMultiSelected
? "text-white"
: "text-[#3c85ee]"
)}
aria-hidden="true"
focusable="false"
@@ -111,7 +132,7 @@ const FolderItem = React.memo((props) => {
<div
className={classNames(
"overflow-hidden text-ellipsis block w-full animate mt-2",
elementSelected
elementSelected || elementMultiSelected
? "bg-[#3c85ee] text-white"
: "bg-white text-[#637381]"
)}
@@ -119,7 +140,9 @@ const FolderItem = React.memo((props) => {
<p
className={classNames(
"m-0 text-[14px] leading-[16px] font-normal max-w-full overflow-hidden text-ellipsis whitespace-nowrap animate",
elementSelected ? "text-white" : "text-black"
elementSelected || elementMultiSelected
? "text-white"
: "text-black"
)}
>
{folder.name}
@@ -127,7 +150,9 @@ const FolderItem = React.memo((props) => {
<span
className={classNames(
"m-0 font-normal max-w-full whitespace-nowrap text-xs animate hidden sm:block mt-1",
elementSelected ? "text-white" : "text-[#637381]"
elementSelected || elementMultiSelected
? "text-white"
: "text-[#637381]"
)}
>
Created {moment(folder.createdAt).format("MM/DD/YY hh:mma")}
+120
View File
@@ -0,0 +1,120 @@
import { useMemo } from "react";
import { useAppDispatch, useAppSelector } from "../../hooks/store";
import { resetMultiSelect } from "../../reducers/selected";
import Swal from "sweetalert2";
import { trashMultiAPI } from "../../api/filesAPI";
import { useFilesClient, useQuickFilesClient } from "../../hooks/files";
import { useFoldersClient } from "../../hooks/folders";
const MultiSelectBar = () => {
const dispatch = useAppDispatch();
const multiSelectMode = useAppSelector(
(state) => state.selected.multiSelectMode
);
const multiSelectMap = useAppSelector(
(state) => state.selected.multiSelectMap
);
const multiSelectCount = useAppSelector(
(state) => state.selected.multiSelectCount
);
const { invalidateFilesCache } = useFilesClient();
const { invalidateFoldersCache } = useFoldersClient();
const { invalidateQuickFilesCache } = useQuickFilesClient();
const closeMultiSelect = () => {
dispatch(resetMultiSelect());
};
const deleteItems = async () => {
const result = await Swal.fire({
title: "Move to trash?",
text: "Items in the trash will eventually be deleted.",
icon: "warning",
showCancelButton: true,
confirmButtonColor: "#3085d6",
cancelButtonColor: "#d33",
confirmButtonText: "Yes",
});
if (result.value) {
const itemsToTrash = Object.values(multiSelectMap);
await trashMultiAPI(itemsToTrash);
invalidateFilesCache();
invalidateFoldersCache();
invalidateQuickFilesCache();
closeMultiSelect();
}
};
if (!multiSelectMode) return <div></div>;
return (
<div className="border border-[#ebe9f9] bg-[#ebe9f9] rounded-full p-2 px-5 text-black text-sm mb-4">
<div className="flex flex-row items-center justify-between">
<div className="flex flex-row items-center">
<img
className="w-[22px] h-[22px] cursor-pointer"
src="/images/close_icon.png"
onClick={closeMultiSelect}
/>
<p className="ml-4">{multiSelectCount} selected</p>
</div>
<div className="flex flex-row items-center">
<svg
width="17"
height="18"
viewBox="0 0 17 18"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="ml-4 cursor-pointer"
onClick={deleteItems}
>
<g id="trash">
<path
id="Shape"
fill-rule="evenodd"
clip-rule="evenodd"
d="M16.0694 2.57072H11.5707V1.92803C11.5707 0.863209 10.7075 0 9.64265 0H7.07192C6.0071 0 5.14389 0.863209 5.14389 1.92803V2.57072H0.645132C0.290178 2.57072 0.00244141 2.85846 0.00244141 3.21341C0.00244141 3.56837 0.290215 3.85607 0.645132 3.85607H1.34371L2.57317 17.4108C2.60348 17.7427 2.88255 17.9963 3.21586 17.995H13.4987C13.832 17.9964 14.1111 17.7427 14.1414 17.4108L15.3708 3.85607H16.0694C16.4244 3.85607 16.7121 3.56833 16.7121 3.21338C16.7121 2.85842 16.4244 2.57072 16.0694 2.57072ZM6.42923 1.92803C6.42923 1.57308 6.71697 1.28534 7.07192 1.28534H9.64265C9.9976 1.28534 10.2853 1.57308 10.2853 1.92803V2.57072H6.42927V1.92803H6.42923ZM3.80263 16.7096H12.9119L14.0803 3.85607H5.78658H2.63745L3.80263 16.7096Z"
fill="currentColor"
/>
<path
id="Path"
d="M6.42938 14.7385C6.4293 14.7376 6.42926 14.7367 6.42919 14.7358L5.7865 5.73834C5.76131 5.38339 5.45312 5.1161 5.09821 5.14129C4.74325 5.16649 4.47596 5.47467 4.50116 5.82959L5.14385 14.8271C5.16783 15.1641 5.44868 15.425 5.78654 15.4241H5.83282C6.1869 15.3995 6.45401 15.0925 6.42938 14.7385Z"
fill="currentColor"
/>
<path
id="Path_2"
d="M8.35729 5.1416C8.00234 5.1416 7.7146 5.42934 7.7146 5.78429V14.7818C7.7146 15.1367 8.00234 15.4245 8.35729 15.4245C8.71224 15.4245 8.99998 15.1367 8.99998 14.7818V5.78429C8.99998 5.42934 8.71224 5.1416 8.35729 5.1416Z"
fill="currentColor"
/>
<path
id="Path_3"
d="M11.6164 5.14129C11.2615 5.1161 10.9533 5.38339 10.9281 5.73834L10.2854 14.7358C10.2594 15.0898 10.5253 15.3979 10.8793 15.4239C10.8804 15.424 10.8814 15.424 10.8825 15.4241H10.9281C11.266 15.425 11.5468 15.1641 11.5708 14.8271L12.2135 5.82959C12.2387 5.47467 11.9714 5.16652 11.6164 5.14129Z"
fill="currentColor"
/>
</g>
</svg>
<svg
width="19"
height="16"
viewBox="0 0 19 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="ml-4 cursor-pointer"
>
<path
id="Combined Shape"
fill-rule="evenodd"
clip-rule="evenodd"
d="M7.63107 0C7.83994 0 8.03661 0.0983374 8.16193 0.265429L9.95357 2.65429H17.9164C18.2829 2.65429 18.58 2.95138 18.58 3.31786V15.2621C18.58 15.6286 18.2829 15.9257 17.9164 15.9257H0.663571C0.297091 15.9257 0 15.6286 0 15.2621V0.663571C0 0.297091 0.297091 0 0.663571 0H7.63107ZM7.212 1.5H1.5V14.425H17.08V4.154L9.20357 4.15429L7.212 1.5ZM9.96369 9.51348C10.0439 9.43969 10.0892 9.33783 10.0892 9.23078C10.0892 9.12373 10.0439 9.02188 9.96369 8.9486L7.2712 6.4802C7.15381 6.37263 6.98149 6.34301 6.8334 6.40433C6.68532 6.46565 6.58893 6.60648 6.58893 6.76238V7.93162H4.30032C3.92929 7.93162 3.62719 8.22315 3.62719 8.5812V9.88036C3.62719 10.2384 3.92929 10.5299 4.30032 10.5299H6.58893V11.6992C6.58893 11.8551 6.68478 11.9964 6.8334 12.0577C6.98203 12.1191 7.15435 12.0889 7.2712 11.9819L9.96369 9.51348Z"
fill="currentColor"
/>
</svg>
</div>
</div>
</div>
);
};
export default MultiSelectBar;
+33 -8
View File
@@ -12,7 +12,7 @@ import { startSetSelectedItem } from "../../actions/selectedItem";
import { setPopupFile } from "../../actions/popupFile";
import { FileInterface } from "../../types/file";
import { useAppDispatch, useAppSelector } from "../../hooks/store";
import { setMainSelect } from "../../reducers/selected";
import { setMainSelect, setMultiSelectMode } from "../../reducers/selected";
interface QuickAccessItemProps {
file: FileInterface;
@@ -24,10 +24,18 @@ const QuickAccessItem = memo((props: QuickAccessItemProps) => {
if (state.selected.mainSection.type !== "quick-item") return false;
return state.selected.mainSection.id === file._id;
});
console.log("ele selected 2", elementSelected);
const elementMultiSelected = useAppSelector((state) => {
if (!state.selected.multiSelectMode) return false;
const selected = state.selected.multiSelectMap[file._id];
return selected && selected.type === "quick-item";
});
const multiSelectMode = useAppSelector(
(state) => state.selected.multiSelectMode
);
const { image, hasThumbnail, imageOnError } = useThumbnail(
file.metadata.hasThumbnail,
file.metadata.thumbnailID
file.metadata.thumbnailID,
true
);
const dispatch = useAppDispatch();
const lastSelected = useRef(0);
@@ -54,6 +62,17 @@ const QuickAccessItem = memo((props: QuickAccessItemProps) => {
// TODO: See if we can memoize this
const quickItemClick = () => {
if (multiSelectMode) {
dispatch(
setMultiSelectMode({
type: "quick-item",
id: file._id,
file: file,
folder: null,
})
);
return;
}
const currentDate = Date.now();
if (!elementSelected) {
@@ -77,8 +96,10 @@ const QuickAccessItem = memo((props: QuickAccessItemProps) => {
return (
<div
className={classNames(
"border rounded-md o transition-all duration-400 ease-in-out cursor-pointer flex items-center justify-center flex-col h-[125px] sm:h-[150px] animiate hover:border-[#3c85ee] overflow-hidden",
elementSelected ? "border-[#3c85ee]" : "border-[#ebe9f9]"
"border rounded-md o transition-all duration-400 ease-in-out cursor-pointer flex items-center justify-center flex-col h-[125px] sm:h-[150px] animiate hover:border-[#3c85ee] overflow-hidden bg-white",
elementSelected || elementMultiSelected
? "border-[#3c85ee]"
: "border-[#ebe9f9]"
)}
onClick={quickItemClick}
onContextMenu={onContextMenu}
@@ -136,7 +157,7 @@ const QuickAccessItem = memo((props: QuickAccessItemProps) => {
<div
className={classNames(
"p-3 overflow-hidden text-ellipsis block w-full animate",
elementSelected
elementSelected || elementMultiSelected
? "bg-[#3c85ee] text-white"
: "bg-white text-[#637381]"
)}
@@ -144,7 +165,9 @@ const QuickAccessItem = memo((props: QuickAccessItemProps) => {
<p
className={classNames(
"m-0 text-[14px] leading-[16px] font-normal max-w-full overflow-hidden text-ellipsis whitespace-nowrap animate",
elementSelected ? "text-white" : "text-[#212b36]"
elementSelected || elementMultiSelected
? "text-white"
: "text-[#212b36]"
)}
>
{capitalize(file.filename)}
@@ -152,7 +175,9 @@ const QuickAccessItem = memo((props: QuickAccessItemProps) => {
<span
className={classNames(
"text-[#637381] font-normal max-w-full whitespace-nowrap text-xs animate hidden sm:block mt-1",
elementSelected ? "text-white" : "text-[#637381]"
elementSelected || elementMultiSelected
? "text-white"
: "text-[#637381]"
)}
>
Created {moment(file.uploadDate).format("MM/DD/YY hh:mma")}
+3 -3
View File
@@ -26,7 +26,7 @@ const SearchBarItem = (props: SearchBarItemProps) => {
if (type === "folder" && folder) {
return (
<div
className="flex flex-row items-center py-2 px-4 overflow-hidden text-ellipsis hover:bg-[#f6f5fd] cursor-pointer"
className="flex flex-row items-center py-2 px-4 overflow-hidden text-ellipsis hover:bg-[#f6f5fd] cursor-pointer border-y mx-4"
key={folder._id}
onClick={() => folderClick(folder)}
>
@@ -48,7 +48,7 @@ const SearchBarItem = (props: SearchBarItemProps) => {
></path>
</svg>
</div>
<span className="text-sm ml-4 text-ellipsis overflow-hidden whitespace-nowrap">
<span className="text-sm ml-4 text-ellipsis overflow-hidden whitespace-nowrap max-w-[50%]">
{folder.name}
</span>
</div>
@@ -56,7 +56,7 @@ const SearchBarItem = (props: SearchBarItemProps) => {
} else if (type === "file" && file) {
return (
<div
className="flex flex-row items-center py-2 px-4 overflow-hidden text-ellipsis hover:bg-[#f6f5fd] cursor-pointer"
className="flex flex-row items-center py-2 px-4 overflow-hidden text-ellipsis hover:bg-[#f6f5fd] cursor-pointer border-y mx-4"
key={file._id}
onClick={() => fileClick(file)}
>