From 38b736c5ee4daeb1602e337cabb121c8af126ee9 Mon Sep 17 00:00:00 2001 From: Varun Raj Date: Sun, 18 Aug 2024 00:16:19 +0530 Subject: [PATCH] fix: merge face using dropdown Signed-off-by: Varun Raj --- bun.lockb | Bin 174542 -> 185493 bytes package.json | 2 + src/components/people/PeopleList.tsx | 18 +++ src/components/people/PersonItem.tsx | 2 + src/components/people/PersonMergeDropdown.tsx | 136 ++++++++++++++++ src/components/ui/calendar.tsx | 2 - src/components/ui/command.tsx | 153 ++++++++++++++++++ src/components/ui/dialog.tsx | 120 ++++++++++++++ src/config/routes.ts | 4 +- src/handlers/api/people.handler.ts | 10 +- 10 files changed, 443 insertions(+), 4 deletions(-) create mode 100644 src/components/people/PersonMergeDropdown.tsx create mode 100644 src/components/ui/command.tsx create mode 100644 src/components/ui/dialog.tsx diff --git a/bun.lockb b/bun.lockb index cf736c2a15a1e1a63283ec2a64e2ba24385d0980..9045f2d3c388e7336a87dfdadbfa8cb8c6241328 100755 GIT binary patch delta 37874 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�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 delta 31981 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 diff --git a/package.json b/package.json index 5be8d3b..e2ee7ae 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "@radix-ui/react-avatar": "^1.1.0", + "@radix-ui/react-dialog": "^1.1.1", "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-popover": "^1.1.1", "@radix-ui/react-slot": "^1.1.0", @@ -18,6 +19,7 @@ "axios": "^1.7.4", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", + "cmdk": "1.0.0", "date-fns": "^3.6.0", "lucide-react": "^0.428.0", "next": "14.2.5", diff --git a/src/components/people/PeopleList.tsx b/src/components/people/PeopleList.tsx index 372708d..6a3c48e 100644 --- a/src/components/people/PeopleList.tsx +++ b/src/components/people/PeopleList.tsx @@ -7,6 +7,8 @@ import PersonItem from "./PersonItem"; import { ColumnDef } from "@tanstack/react-table"; import { Table } from "../ui/table"; import PersonBirthdayCell from "./PersonBirthdayCell"; +import Link from "next/link"; +import { ENV } from "@/config/environment"; const columns: ColumnDef[] = [ { @@ -19,6 +21,22 @@ const columns: ColumnDef[] = [ accessorKey: "birthDate", cell: ({ row }) => , }, + { + header: "Hidden", + accessorKey: "isHidden", + cell: ({ row }) => ( + {row.original.isHidden ? "Yes" : "No"} + ), + }, + { + header: "Link", + accessorKey: "id", + cell: ({ row }) => ( + + View + + ) + }, { header: "Updated At", accessorKey: "updatedAt", diff --git a/src/components/people/PersonItem.tsx b/src/components/people/PersonItem.tsx index 5e9d714..29ddc86 100644 --- a/src/components/people/PersonItem.tsx +++ b/src/components/people/PersonItem.tsx @@ -2,6 +2,7 @@ import { IPerson } from "@/types/person"; import React, { useState } from "react"; import { Avatar } from "../ui/avatar"; import { updatePerson } from "@/handlers/api/people.handler"; +import { PersonMergeDropdown } from "./PersonMergeDropdown"; interface IProps { person: IPerson; @@ -54,6 +55,7 @@ export default function PersonItem({ person }: IProps) { onBlur={handleEdit} /> )} + ); } diff --git a/src/components/people/PersonMergeDropdown.tsx b/src/components/people/PersonMergeDropdown.tsx new file mode 100644 index 0000000..dfec675 --- /dev/null +++ b/src/components/people/PersonMergeDropdown.tsx @@ -0,0 +1,136 @@ +"use client"; + +import * as React from "react"; + +import { Button } from "@/components/ui/button"; +import { + Command, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, +} from "@/components/ui/command"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; +import { Merge } from "lucide-react"; +import { mergePerson, searchPeople } from "@/handlers/api/people.handler"; +import { IPerson } from "@/types/person"; +import { set } from "date-fns"; +import { CommandLoading } from "cmdk"; +import { Avatar } from "../ui/avatar"; + +type Status = { + value: string; + label: string; +}; + +const statuses: Status[] = [ + { + value: "backlog", + label: "Backlog", + }, + { + value: "todo", + label: "Todo", + }, + { + value: "in progress", + label: "In Progress", + }, + { + value: "done", + label: "Done", + }, + { + value: "canceled", + label: "Canceled", + }, +]; + +interface PersonMergeDropdownProps { + person: IPerson; +} +export function PersonMergeDropdown( + { person }: PersonMergeDropdownProps +) { + const [searchedPeople, setSearchedPeople] = React.useState([]); + const [open, setOpen] = React.useState(false); + const [loading, setLoading] = React.useState(false); + const searchTimer = React.useRef(); + + const handleSearch = (value: string) => { + if (searchTimer.current) { + clearTimeout(searchTimer.current); + } + + searchTimer.current = setTimeout(() => { + setLoading(true); + if (!value) { + setSearchedPeople([]); + setLoading(false); + return; + } + + return searchPeople(value) + .then(setSearchedPeople) + .finally(() => { + setLoading(false); + }); + }, 500); + }; + + const handleSelect = (value: IPerson) => { + return mergePerson(person.id, value.id) + .then(() => { + setOpen(false); + }) + }; + + console.log(searchedPeople); + return ( +
+ + + + + + + + + {loading && } + + {searchedPeople.map((person) => ( + { + handleSelect(person); + }} + className="flex items-center gap-2" + > + + {person.name} + + ))} + + + + + +
+ ); +} diff --git a/src/components/ui/calendar.tsx b/src/components/ui/calendar.tsx index 6c36f3f..1e75f33 100644 --- a/src/components/ui/calendar.tsx +++ b/src/components/ui/calendar.tsx @@ -1,10 +1,8 @@ import * as React from "react" -import { ChevronLeftIcon, ChevronRightIcon } from "@radix-ui/react-icons" import { DayPicker } from "react-day-picker" import "react-day-picker/dist/style.css"; import { cn } from "@/lib/utils" -import { buttonVariants } from "@/components/ui/button" export type CalendarProps = React.ComponentProps diff --git a/src/components/ui/command.tsx b/src/components/ui/command.tsx new file mode 100644 index 0000000..a0225c4 --- /dev/null +++ b/src/components/ui/command.tsx @@ -0,0 +1,153 @@ +import * as React from "react" +import { type DialogProps } from "@radix-ui/react-dialog" +import { MagnifyingGlassIcon } from "@radix-ui/react-icons" +import { Command as CommandPrimitive } from "cmdk" + +import { cn } from "@/lib/utils" +import { Dialog, DialogContent } from "@/components/ui/dialog" + +const Command = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +Command.displayName = CommandPrimitive.displayName + +interface CommandDialogProps extends DialogProps {} + +const CommandDialog = ({ children, ...props }: CommandDialogProps) => { + return ( + + + + {children} + + + + ) +} + +const CommandInput = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( +
+ + +
+)) + +CommandInput.displayName = CommandPrimitive.Input.displayName + +const CommandList = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) + +CommandList.displayName = CommandPrimitive.List.displayName + +const CommandEmpty = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>((props, ref) => ( + +)) + +CommandEmpty.displayName = CommandPrimitive.Empty.displayName + +const CommandGroup = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) + +CommandGroup.displayName = CommandPrimitive.Group.displayName + +const CommandSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +CommandSeparator.displayName = CommandPrimitive.Separator.displayName + +const CommandItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) + +CommandItem.displayName = CommandPrimitive.Item.displayName + +const CommandShortcut = ({ + className, + ...props +}: React.HTMLAttributes) => { + return ( + + ) +} +CommandShortcut.displayName = "CommandShortcut" + +export { + Command, + CommandDialog, + CommandInput, + CommandList, + CommandEmpty, + CommandGroup, + CommandItem, + CommandShortcut, + CommandSeparator, +} diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx new file mode 100644 index 0000000..5d16351 --- /dev/null +++ b/src/components/ui/dialog.tsx @@ -0,0 +1,120 @@ +import * as React from "react" +import * as DialogPrimitive from "@radix-ui/react-dialog" +import { Cross2Icon } from "@radix-ui/react-icons" + +import { cn } from "@/lib/utils" + +const Dialog = DialogPrimitive.Root + +const DialogTrigger = DialogPrimitive.Trigger + +const DialogPortal = DialogPrimitive.Portal + +const DialogClose = DialogPrimitive.Close + +const DialogOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DialogOverlay.displayName = DialogPrimitive.Overlay.displayName + +const DialogContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + {children} + + + Close + + + +)) +DialogContent.displayName = DialogPrimitive.Content.displayName + +const DialogHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +DialogHeader.displayName = "DialogHeader" + +const DialogFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +DialogFooter.displayName = "DialogFooter" + +const DialogTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DialogTitle.displayName = DialogPrimitive.Title.displayName + +const DialogDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DialogDescription.displayName = DialogPrimitive.Description.displayName + +export { + Dialog, + DialogPortal, + DialogOverlay, + DialogTrigger, + DialogClose, + DialogContent, + DialogHeader, + DialogFooter, + DialogTitle, + DialogDescription, +} diff --git a/src/config/routes.ts b/src/config/routes.ts index e6d18c0..d611ac5 100644 --- a/src/config/routes.ts +++ b/src/config/routes.ts @@ -1,5 +1,7 @@ export const BASE_ENDPOINT = '/api/immich-proxy'; export const LIST_PEOPLE_PATH = BASE_ENDPOINT + "/people"; +export const SEARCH_PEOPLE_PATH = BASE_ENDPOINT + "/search/person"; export const PERSON_THUBNAIL_PATH = (id: string) => BASE_ENDPOINT + "/thumbnail/" + id; -export const UPDATE_PERSON_PATH = (id: string) => BASE_ENDPOINT + "/people/" + id; \ No newline at end of file +export const UPDATE_PERSON_PATH = (id: string) => BASE_ENDPOINT + "/people/" + id; +export const MERGE_PERSON_PATH = (id: string) => BASE_ENDPOINT + "/people/" + id + "/merge"; \ No newline at end of file diff --git a/src/handlers/api/people.handler.ts b/src/handlers/api/people.handler.ts index 77744d6..1263292 100644 --- a/src/handlers/api/people.handler.ts +++ b/src/handlers/api/people.handler.ts @@ -1,4 +1,4 @@ -import { LIST_PEOPLE_PATH, UPDATE_PERSON_PATH } from "@/config/routes" +import { LIST_PEOPLE_PATH, MERGE_PERSON_PATH, SEARCH_PEOPLE_PATH, UPDATE_PERSON_PATH } from "@/config/routes" import { cleanUpPerson } from "@/helpers/person.helper"; import API from "@/lib/api" import { IPeopleListResponse, IPerson } from "@/types/person" @@ -18,4 +18,12 @@ export const updatePerson = (id: string, data: Partial<{ isHidden: boolean; }>) => { return API.put(UPDATE_PERSON_PATH(id), data) +} + +export const searchPeople = (name: string) => { + return API.get(SEARCH_PEOPLE_PATH, { name }).then((response) => response.map(cleanUpPerson)); +} + +export const mergePerson = (id: string, targetId: string) => { + return API.post(MERGE_PERSON_PATH(id), { ids: [ targetId ] }) } \ No newline at end of file