Skip to content

Commit

Permalink
feat: updated tags list UI
Browse files Browse the repository at this point in the history
  • Loading branch information
MehadND committed May 7, 2024
1 parent a9caecf commit d185805
Showing 1 changed file with 57 additions and 74 deletions.
131 changes: 57 additions & 74 deletions web/src/components/HomeSidebar/TagsSection.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Dropdown, Menu, MenuButton, MenuItem } from "@mui/joy";
import { Autocomplete, AutocompleteOption, Dropdown, Menu, MenuButton, MenuItem } from "@mui/joy";
import { useState } from "react";
import useDebounce from "react-use/lib/useDebounce";
import { useFilterStore } from "@/store/module";
import { useMemoList, useTagStore } from "@/store/v1";
Expand All @@ -13,7 +14,6 @@ const TagsSection = () => {
const filterStore = useFilterStore();
const tagStore = useTagStore();
const memoList = useMemoList();
const filter = filterStore.state;
const tags = tagStore.tags;

useDebounce(
Expand All @@ -24,6 +24,22 @@ const TagsSection = () => {
[memoList.size()],
);

const [search, setSearch] = useState<string | null>();

const handleDeleteTag = async (tagValue: string) => {
showCommonDialog({
title: t("tag.delete-tag"),
content: t("tag.delete-confirm"),
style: "danger",
dialogName: "delete-tag-dialog",
onConfirm: async () => {
await tagStore.deleteTag(tagValue);
tagStore.fetchTags({ skipCache: true });
setSearch("");
},
});
};

return (
<div className="flex flex-col justify-start items-start w-full mt-3 px-1 h-auto shrink-0 flex-nowrap hide-scrollbar">
<div className="flex flex-row justify-start items-center w-full">
Expand All @@ -32,10 +48,45 @@ const TagsSection = () => {
</span>
</div>
{tags.size > 0 ? (
<div className="flex flex-col justify-start items-start relative w-full h-auto flex-nowrap gap-2 mt-1">
{Array.from(tags).map((tag) => (
<TagItemContainer key={tag} tag={tag} tagQuery={filter.tag} />
))}
<div className="w-full flex items-center justify-between">
<Autocomplete
key={search}
options={Array.from(tags)}
autoHighlight
renderOption={(props, option) => (
<AutocompleteOption {...props}>
<div className="relative flex flex-row justify-between items-center w-full leading-6 py-0 mt-px rounded-lg text-sm select-none shrink-0">
<div className="flex flex-row justify-start items-center truncate shrink leading-5 mr-1 text-gray-600 dark:text-gray-400">
<Icon.Hash className="group-hover:hidden w-4 h-auto shrink-0 opacity-60 mr-1" />
<span className="truncate cursor-pointer hover:opacity-80">{option}</span>
</div>
</div>
</AutocompleteOption>
)}
className="w-full"
value={search || null}
onChange={(event, searchValue) => {
setSearch(searchValue);
filterStore.setTagFilter(searchValue || "");
}}
/>
{search && (
<Dropdown>
<MenuButton variant="plain">
<Icon.MoreVertical />
</MenuButton>
<Menu size="sm" placement="bottom">
<MenuItem onClick={() => showRenameTagDialog({ tag: search })}>
<Icon.Edit3 className="w-4 h-auto" />
{t("common.rename")}
</MenuItem>
<MenuItem color="danger" onClick={() => handleDeleteTag(search)}>
<Icon.Trash className="w-4 h-auto" />
{t("common.delete")}
</MenuItem>
</Menu>
</Dropdown>
)}
</div>
) : (
<div className="p-2 border rounded-md flex flex-row justify-start items-start gap-1 text-gray-400 dark:text-gray-500">
Expand All @@ -47,72 +98,4 @@ const TagsSection = () => {
);
};

interface TagItemContainerProps {
tag: string;
tagQuery?: string;
}

const TagItemContainer: React.FC<TagItemContainerProps> = (props: TagItemContainerProps) => {
const t = useTranslate();
const filterStore = useFilterStore();
const tagStore = useTagStore();
const { tag, tagQuery } = props;
const isActive = tagQuery === tag;

const handleTagClick = () => {
if (isActive) {
filterStore.setTagFilter(undefined);
} else {
filterStore.setTagFilter(tag);
}
};

const handleDeleteTag = async () => {
showCommonDialog({
title: t("tag.delete-tag"),
content: t("tag.delete-confirm"),
style: "danger",
dialogName: "delete-tag-dialog",
onConfirm: async () => {
await tagStore.deleteTag(tag);
tagStore.fetchTags({ skipCache: true });
},
});
};

return (
<>
<div className="relative flex flex-row justify-between items-center w-full leading-6 py-0 mt-px rounded-lg text-sm select-none shrink-0">
<div
className={`flex flex-row justify-start items-center truncate shrink leading-5 mr-1 text-gray-600 dark:text-gray-400 ${
isActive && "!text-blue-600"
}`}
>
<Dropdown>
<MenuButton slots={{ root: "div" }}>
<div className="shrink-0 group">
<Icon.Hash className="group-hover:hidden w-4 h-auto shrink-0 opacity-60 mr-1" />
<Icon.MoreVertical className="hidden group-hover:block w-4 h-auto shrink-0 opacity-60 mr-1" />
</div>
</MenuButton>
<Menu size="sm" placement="bottom">
<MenuItem onClick={() => showRenameTagDialog({ tag: tag })}>
<Icon.Edit3 className="w-4 h-auto" />
{t("common.rename")}
</MenuItem>
<MenuItem color="danger" onClick={handleDeleteTag}>
<Icon.Trash className="w-4 h-auto" />
{t("common.delete")}
</MenuItem>
</Menu>
</Dropdown>
<span className="truncate cursor-pointer hover:opacity-80" onClick={handleTagClick}>
{tag}
</span>
</div>
</div>
</>
);
};

export default TagsSection;

0 comments on commit d185805

Please sign in to comment.