From 3afe1e21df6dcc0483e74e0db02d9d82af32ecea Mon Sep 17 00:00:00 2001 From: xuatz Date: Mon, 2 Jun 2025 04:01:26 +0900 Subject: feat: add user customisable default archive display behaviour (#1505) * fix typo * implementation * bug fix and refactoring * Use nuqs for searchParam management * remove the todo about the tests * fix tests --------- Co-authored-by: Mohamed Bassem --- .../web/components/dashboard/lists/ListOptions.tsx | 20 ++++++++- apps/web/components/dashboard/tags/TagOptions.tsx | 14 +++++- apps/web/components/settings/UserOptions.tsx | 52 ++++++++++++++++++++-- apps/web/components/utils/useShowArchived.tsx | 24 ++++++++++ 4 files changed, 104 insertions(+), 6 deletions(-) create mode 100644 apps/web/components/utils/useShowArchived.tsx (limited to 'apps/web/components') diff --git a/apps/web/components/dashboard/lists/ListOptions.tsx b/apps/web/components/dashboard/lists/ListOptions.tsx index d0dedfd5..7e020374 100644 --- a/apps/web/components/dashboard/lists/ListOptions.tsx +++ b/apps/web/components/dashboard/lists/ListOptions.tsx @@ -5,8 +5,17 @@ import { DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; +import { useShowArchived } from "@/components/utils/useShowArchived"; import { useTranslation } from "@/lib/i18n/client"; -import { FolderInput, Pencil, Plus, Share, Trash2 } from "lucide-react"; +import { + FolderInput, + Pencil, + Plus, + Share, + Square, + SquareCheck, + Trash2, +} from "lucide-react"; import { ZBookmarkList } from "@karakeep/shared/types/lists"; @@ -27,6 +36,7 @@ export function ListOptions({ children?: React.ReactNode; }) { const { t } = useTranslation(); + const { showArchived, onClickShowArchived } = useShowArchived(); const [deleteListDialogOpen, setDeleteListDialogOpen] = useState(false); const [newNestedListModalOpen, setNewNestedListModalOpen] = useState(false); @@ -93,6 +103,14 @@ export function ListOptions({ {t("lists.merge_list")} + + {showArchived ? ( + + ) : ( + + )} + {t("actions.toggle_show_archived")} + setDeleteListDialogOpen(true)} diff --git a/apps/web/components/dashboard/tags/TagOptions.tsx b/apps/web/components/dashboard/tags/TagOptions.tsx index 8d8cc9db..1419e6c3 100644 --- a/apps/web/components/dashboard/tags/TagOptions.tsx +++ b/apps/web/components/dashboard/tags/TagOptions.tsx @@ -7,8 +7,9 @@ import { DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; +import { useShowArchived } from "@/components/utils/useShowArchived"; import { useTranslation } from "@/lib/i18n/client"; -import { Combine, Trash2 } from "lucide-react"; +import { Combine, Square, SquareCheck, Trash2 } from "lucide-react"; import DeleteTagConfirmationDialog from "./DeleteTagConfirmationDialog"; import { MergeTagModal } from "./MergeTagModal"; @@ -21,6 +22,8 @@ export function TagOptions({ children?: React.ReactNode; }) { const { t } = useTranslation(); + const { showArchived, onClickShowArchived } = useShowArchived(); + const [deleteTagDialogOpen, setDeleteTagDialogOpen] = useState(false); const [mergeTagDialogOpen, setMergeTagDialogOpen] = useState(false); @@ -45,7 +48,14 @@ export function TagOptions({ {t("actions.merge")} - + + {showArchived ? ( + + ) : ( + + )} + {t("actions.toggle_show_archived")} + setDeleteTagDialogOpen(true)} diff --git a/apps/web/components/settings/UserOptions.tsx b/apps/web/components/settings/UserOptions.tsx index c8aa5e86..3918ceed 100644 --- a/apps/web/components/settings/UserOptions.tsx +++ b/apps/web/components/settings/UserOptions.tsx @@ -73,12 +73,22 @@ export default function UserSettings() { ZUserSettings["bookmarkClickAction"], string > = { - open_original_link: t("settings.info.user_settings.open_external_url"), + open_original_link: t( + "settings.info.user_settings.bookmark_click_action.open_external_url", + ), expand_bookmark_preview: t( - "settings.info.user_settings.open_bookmark_details", + "settings.info.user_settings.bookmark_click_action.open_bookmark_details", ), }; + const archiveDisplayBehaviourTranslation: Record< + ZUserSettings["archiveDisplayBehaviour"], + string + > = { + show: t("settings.info.user_settings.archive_display_behaviour.show"), + hide: t("settings.info.user_settings.archive_display_behaviour.hide"), + }; + const form = useForm>({ resolver: zodResolver(zUserSettingsSchema), defaultValues: data, @@ -97,7 +107,7 @@ export default function UserSettings() { render={({ field }) => (
{ + mutate({ + archiveDisplayBehaviour: + value as ZUserSettings["archiveDisplayBehaviour"], + }); + }} + > + + + {archiveDisplayBehaviourTranslation[field.value]} + + + + {Object.entries(archiveDisplayBehaviourTranslation).map( + ([value, label]) => ( + + {label} + + ), + )} + + +
+ )} + /> ); } diff --git a/apps/web/components/utils/useShowArchived.tsx b/apps/web/components/utils/useShowArchived.tsx new file mode 100644 index 00000000..3fc66e91 --- /dev/null +++ b/apps/web/components/utils/useShowArchived.tsx @@ -0,0 +1,24 @@ +import { useCallback } from "react"; +import { useUserSettings } from "@/lib/userSettings"; +import { parseAsBoolean, useQueryState } from "nuqs"; + +export function useShowArchived() { + const userSettings = useUserSettings(); + const [showArchived, setShowArchived] = useQueryState( + "includeArchived", + parseAsBoolean + .withOptions({ + shallow: false, + }) + .withDefault(userSettings.archiveDisplayBehaviour === "show"), + ); + + const onClickShowArchived = useCallback(() => { + setShowArchived((prev) => !prev); + }, [setShowArchived]); + + return { + showArchived, + onClickShowArchived, + }; +} -- cgit v1.2.3-70-g09d2