Unified bookmark search
This commit is contained in:
3976
package-lock.json
generated
3976
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
16
package.json
16
package.json
@@ -13,11 +13,11 @@
|
|||||||
"@hello-pangea/dnd": "^18.0.1",
|
"@hello-pangea/dnd": "^18.0.1",
|
||||||
"@mantine/core": "^7.17.4",
|
"@mantine/core": "^7.17.4",
|
||||||
"@mantine/hooks": "^7.17.4",
|
"@mantine/hooks": "^7.17.4",
|
||||||
"@tanstack/react-query": "^5.72.2",
|
"@tanstack/react-query": "^5.74.3",
|
||||||
"@tanstack/react-query-devtools": "^5.72.2",
|
"@tanstack/react-query-devtools": "^5.74.3",
|
||||||
"@tanstack/react-query-persist-client": "^5.73.1",
|
"@tanstack/react-query-persist-client": "^5.74.3",
|
||||||
"idb-keyval": "^6.2.1",
|
"idb-keyval": "^6.2.1",
|
||||||
"jotai": "^2.12.2",
|
"jotai": "^2.12.3",
|
||||||
"react": "^19.1.0",
|
"react": "^19.1.0",
|
||||||
"react-dom": "^19.1.0",
|
"react-dom": "^19.1.0",
|
||||||
"react-icons": "^5.5.0",
|
"react-icons": "^5.5.0",
|
||||||
@@ -27,11 +27,11 @@
|
|||||||
"recharts": "^2.15.2"
|
"recharts": "^2.15.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^22.14.0",
|
"@types/node": "^22.14.1",
|
||||||
"@types/react": "^19.1.0",
|
"@types/react": "^19.1.1",
|
||||||
"@types/react-dom": "^19.1.2",
|
"@types/react-dom": "^19.1.2",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.29.1",
|
"@typescript-eslint/eslint-plugin": "^8.30.0",
|
||||||
"@typescript-eslint/parser": "^8.29.1",
|
"@typescript-eslint/parser": "^8.30.0",
|
||||||
"@vitejs/plugin-react": "^4.3.4",
|
"@vitejs/plugin-react": "^4.3.4",
|
||||||
"@vitest/coverage-v8": "^3.1.1",
|
"@vitest/coverage-v8": "^3.1.1",
|
||||||
"@vitest/ui": "^3.1.1",
|
"@vitest/ui": "^3.1.1",
|
||||||
|
|||||||
@@ -74,15 +74,32 @@ const BookmarkSettings = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (groupData && groupsIsFetched) {
|
if (groupData && groupsIsFetched) {
|
||||||
setGroups(
|
const foundBookmarkGroups = [
|
||||||
groupData
|
...new Set(
|
||||||
.filter((a: BookmarkGroup) =>
|
bookmarks
|
||||||
a.categoryName.toLowerCase().includes(debouncedGroupSearch.toLowerCase()),
|
.filter(
|
||||||
|
(a: Bookmark) =>
|
||||||
|
a.name.toLowerCase().includes(debouncedGroupSearch.toLowerCase()) ||
|
||||||
|
a.url.toLowerCase().includes(debouncedGroupSearch.toLowerCase()),
|
||||||
)
|
)
|
||||||
.sort((a: BookmarkGroup, b: BookmarkGroup) =>
|
.map(
|
||||||
a.categoryIndex > b.categoryIndex ? 1 : -1,
|
(a: Bookmark) =>
|
||||||
|
groupData.filter(
|
||||||
|
(b: BookmarkGroup) =>
|
||||||
|
b.categoryName.toLowerCase() === a.category.toLowerCase(),
|
||||||
|
)[0],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
const foundGroups = groupData.filter((a: BookmarkGroup) =>
|
||||||
|
a.categoryName.toLowerCase().includes(debouncedGroupSearch.toLowerCase()),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const groupList = [...new Set([...foundBookmarkGroups, ...foundGroups])].sort(
|
||||||
|
(a: BookmarkGroup, b: BookmarkGroup) =>
|
||||||
|
a.categoryIndex > b.categoryIndex ? 1 : -1,
|
||||||
|
);
|
||||||
|
setGroups(groupList);
|
||||||
}
|
}
|
||||||
}, [groupData, groupsIsFetched, debouncedGroupSearch]);
|
}, [groupData, groupsIsFetched, debouncedGroupSearch]);
|
||||||
|
|
||||||
@@ -278,6 +295,7 @@ const BookmarkSettings = () => {
|
|||||||
bookmarks={bookmarks
|
bookmarks={bookmarks
|
||||||
.filter((a: Bookmark) => a.category === group.categoryName)
|
.filter((a: Bookmark) => a.category === group.categoryName)
|
||||||
.sort((a: Bookmark, b: Bookmark) => (a.index > b.index ? 1 : -1))}
|
.sort((a: Bookmark, b: Bookmark) => (a.index > b.index ? 1 : -1))}
|
||||||
|
searchTerm={searchValue}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</Group>
|
</Group>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
import { useDebouncedValue, useDisclosure } from '@mantine/hooks';
|
import { useDebouncedValue, useDisclosure } from '@mantine/hooks';
|
||||||
import { useCommonHooks, useMutationAPI } from 'hooks';
|
import { useCommonHooks, useMutationAPI } from 'hooks';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
import { FaChevronLeft } from 'react-icons/fa';
|
||||||
import { FiPlus, FiTrash } from 'react-icons/fi';
|
import { FiPlus, FiTrash } from 'react-icons/fi';
|
||||||
import { buttonClasses, cardClasses, popoverClasses, textInputClasses } from 'styles';
|
import { buttonClasses, cardClasses, popoverClasses, textInputClasses } from 'styles';
|
||||||
import type { Bookmark, BookmarkGroup } from 'types';
|
import type { Bookmark, BookmarkGroup } from 'types';
|
||||||
@@ -24,7 +25,8 @@ import DebouncedBookmarkItem from './DebouncedBookmarkItem';
|
|||||||
function DebouncedGroupSettingsItem({
|
function DebouncedGroupSettingsItem({
|
||||||
bookmarkGroup,
|
bookmarkGroup,
|
||||||
bookmarks,
|
bookmarks,
|
||||||
}: { bookmarkGroup: BookmarkGroup; bookmarks: Bookmark[] }) {
|
searchTerm,
|
||||||
|
}: { bookmarkGroup: BookmarkGroup; bookmarks: Bookmark[]; searchTerm: string }) {
|
||||||
const { theme, isMobile, handleDelete } = useCommonHooks();
|
const { theme, isMobile, handleDelete } = useCommonHooks();
|
||||||
const [modalOpened, { open: openModal, close: closeModal }] = useDisclosure(false);
|
const [modalOpened, { open: openModal, close: closeModal }] = useDisclosure(false);
|
||||||
const [popoverOpened, setPopoverOpened] = useState(false);
|
const [popoverOpened, setPopoverOpened] = useState(false);
|
||||||
@@ -48,7 +50,6 @@ function DebouncedGroupSettingsItem({
|
|||||||
result.splice(endIndex, 0, removed);
|
result.splice(endIndex, 0, removed);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
function onDragEnd(result: any) {
|
function onDragEnd(result: any) {
|
||||||
if (!result.destination) {
|
if (!result.destination) {
|
||||||
return;
|
return;
|
||||||
@@ -238,7 +239,25 @@ function DebouncedGroupSettingsItem({
|
|||||||
classNames={popoverClasses}
|
classNames={popoverClasses}
|
||||||
>
|
>
|
||||||
<Popover.Target>
|
<Popover.Target>
|
||||||
<Box>
|
<Box pos={'relative'}>
|
||||||
|
{(bookmark.name.toLowerCase().includes(searchTerm) ||
|
||||||
|
bookmark.url.toLowerCase().includes(searchTerm)) &&
|
||||||
|
searchTerm && (
|
||||||
|
<ActionIcon
|
||||||
|
variant='subtle'
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: 6,
|
||||||
|
left: -12,
|
||||||
|
color: 'red',
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FaChevronLeft
|
||||||
|
style={{ transform: 'rotate(180deg)' }}
|
||||||
|
/>
|
||||||
|
</ActionIcon>
|
||||||
|
)}
|
||||||
<BookmarkSettingsItem bookmark={bookmark} />
|
<BookmarkSettingsItem bookmark={bookmark} />
|
||||||
</Box>
|
</Box>
|
||||||
</Popover.Target>
|
</Popover.Target>
|
||||||
|
|||||||
Reference in New Issue
Block a user