From b93f0aa2608028f3e373f4e3c47e2f1665b14c0d Mon Sep 17 00:00:00 2001 From: Nick Savage Date: Thu, 19 Dec 2024 21:11:50 -0500 Subject: [PATCH] frontend: improve taglist styling, add filter and sorting --- .../src/components/tags/TagList.tsx | 82 ++++++++++++++----- .../src/components/tags/TagListItem.tsx | 63 ++++++++------ 2 files changed, 99 insertions(+), 46 deletions(-) diff --git a/zettelkasten-front/src/components/tags/TagList.tsx b/zettelkasten-front/src/components/tags/TagList.tsx index dffff925..c9453868 100644 --- a/zettelkasten-front/src/components/tags/TagList.tsx +++ b/zettelkasten-front/src/components/tags/TagList.tsx @@ -1,31 +1,75 @@ -import React from "react"; +import React, { useState } from "react"; import { useTagContext } from "../../contexts/TagContext"; import { TagListItem } from "./TagListItem"; interface TagListInterface {} +type SortOption = "name" | "name-desc" | "tasks-asc" | "tasks-desc" | "cards-asc" | "cards-desc"; + export function TagList({}: TagListInterface) { const { tags } = useTagContext(); + const [sortOption, setSortOption] = useState("name"); + const [filterText, setFilterText] = useState(""); + + const filteredTags = (tags || []).filter(tag => + tag.name.toLowerCase().includes(filterText.toLowerCase()) + ); + + const sortedTags = [...filteredTags].sort((a, b) => { + switch (sortOption) { + case "name": + return a.name.localeCompare(b.name); + case "name-desc": + return b.name.localeCompare(a.name); + case "tasks-asc": + return a.task_count - b.task_count; + case "tasks-desc": + return b.task_count - a.task_count; + case "cards-asc": + return a.card_count - b.card_count; + case "cards-desc": + return b.card_count - a.card_count; + default: + return 0; + } + }); return ( -
- Tags -
-
    -
  • -
    -
    Name
    -
    -
    Tasks
    -
    Cards
    -
    -
    -
  • - {tags && - tags.map((tag) => { - return ; - })} -
+
+

Tags

+
+
+ + setFilterText(e.target.value)} + className="border border-gray-300 rounded px-2 py-1 w-full md:w-auto" + placeholder="Filter by name" + /> +
+
+ + +
+
+
+ {sortedTags.length > 0 ? ( + sortedTags.map((tag) => ) + ) : ( +
No tags available
+ )}
); diff --git a/zettelkasten-front/src/components/tags/TagListItem.tsx b/zettelkasten-front/src/components/tags/TagListItem.tsx index 491b0502..07ab11a4 100644 --- a/zettelkasten-front/src/components/tags/TagListItem.tsx +++ b/zettelkasten-front/src/components/tags/TagListItem.tsx @@ -2,7 +2,6 @@ import React, { useState } from "react"; import { useNavigate } from "react-router-dom"; import { Tag } from "../../models/Tags"; import { deleteTag } from "../../api/tags"; - import { useTagContext } from "../../contexts/TagContext"; interface TagListItemInterface { @@ -12,20 +11,22 @@ interface TagListItemInterface { export function TagListItem({ tag }: TagListItemInterface) { const [showMenu, setShowMenu] = useState(false); const { setRefreshTags } = useTagContext(); - const navigate = useNavigate(); function toggleMenu() { setShowMenu(!showMenu); } + function handleViewCards() { - let searchTerm = "#" + tag.name - navigate(`/app/search?term=${encodeURIComponent(searchTerm)}`) + let searchTerm = "#" + tag.name; + navigate(`/app/search?term=${encodeURIComponent(searchTerm)}`); } + function handleViewTasks() { - let searchTerm = "#" + tag.name - navigate(`/app/tasks?term=${encodeURIComponent(searchTerm)}`) + let searchTerm = "#" + tag.name; + navigate(`/app/tasks?term=${encodeURIComponent(searchTerm)}`); } + async function handleDelete() { let _ = await deleteTag(tag.id) .then((data) => { @@ -33,33 +34,41 @@ export function TagListItem({ tag }: TagListItemInterface) { }) .catch((error) => alert( - "Unable to delete tag, make sure no cards or tasks are using it first.", - ), + "Unable to delete tag, make sure no cards or tasks are using it first." + ) ); setShowMenu(false); } return ( -
  • -
    -
    {tag.name}
    -
    -
    {tag.task_count}
    -
    {tag.card_count}
    -
    -
    - +
    +
    + + Tasks: {tag.task_count} + + + Cards: {tag.card_count} + +
    + {showMenu && ( +
    + + + - {showMenu && ( -
    - - - -
    - )}
    -
    -
  • + )} +
    ); }