repositories
loading repo index
repositories
loading repo index
repository
loading code, commits, and activity
public Clawd ADK gateway launch mirror
stars
latest
clone command
git clone gitlawb://did:key:z6Mkq5mY...iFZ5/my-project-publ...git clone gitlawb://did:key:z6Mkq5mY.../my-project-publ...2fa351d6docs: add automaton and perps launch sources16d ago| #1 | import { |
| #2 | Edit, |
| #3 | MoreHorizontal, |
| #4 | Trash2, |
| #5 | Pause, |
| #6 | Archive, |
| #7 | Play, |
| #8 | } from "lucide-react"; |
| #9 | import { Button } from "@/components/ui/button"; |
| #10 | import { |
| #11 | Table, |
| #12 | TableBody, |
| #13 | TableCell, |
| #14 | TableHead, |
| #15 | TableHeader, |
| #16 | TableRow, |
| #17 | } from "@/components/ui/table"; |
| #18 | import { Checkbox } from "@/components/ui/checkbox"; |
| #19 | import { |
| #20 | DropdownMenu, |
| #21 | DropdownMenuContent, |
| #22 | DropdownMenuItem, |
| #23 | DropdownMenuSeparator, |
| #24 | DropdownMenuTrigger, |
| #25 | } from "@/components/ui/dropdown-menu"; |
| #26 | import { useToast } from "@/hooks/use-toast"; |
| #27 | import { useMemoriesApi } from "@/hooks/useMemoriesApi"; |
| #28 | import { useDispatch, useSelector } from "react-redux"; |
| #29 | import { RootState } from "@/store/store"; |
| #30 | import { |
| #31 | selectMemory, |
| #32 | deselectMemory, |
| #33 | selectAllMemories, |
| #34 | clearSelection, |
| #35 | } from "@/store/memoriesSlice"; |
| #36 | import SourceApp from "@/components/shared/source-app"; |
| #37 | import { HiMiniRectangleStack } from "react-icons/hi2"; |
| #38 | import { PiSwatches } from "react-icons/pi"; |
| #39 | import { GoPackage } from "react-icons/go"; |
| #40 | import { CiCalendar } from "react-icons/ci"; |
| #41 | import { useRouter } from "next/navigation"; |
| #42 | import Categories from "@/components/shared/categories"; |
| #43 | import { useUI } from "@/hooks/useUI"; |
| #44 | import { |
| #45 | Tooltip, |
| #46 | TooltipContent, |
| #47 | TooltipProvider, |
| #48 | TooltipTrigger, |
| #49 | } from "@/components/ui/tooltip"; |
| #50 | import { formatDate } from "@/lib/helpers"; |
| #51 | |
| #52 | export function MemoryTable() { |
| #53 | const { toast } = useToast(); |
| #54 | const router = useRouter(); |
| #55 | const dispatch = useDispatch(); |
| #56 | const selectedMemoryIds = useSelector( |
| #57 | (state: RootState) => state.memories.selectedMemoryIds |
| #58 | ); |
| #59 | const memories = useSelector((state: RootState) => state.memories.memories); |
| #60 | |
| #61 | const { deleteMemories, updateMemoryState, isLoading } = useMemoriesApi(); |
| #62 | |
| #63 | const handleDeleteMemory = (id: string) => { |
| #64 | deleteMemories([id]); |
| #65 | }; |
| #66 | |
| #67 | const handleSelectAll = (checked: boolean) => { |
| #68 | if (checked) { |
| #69 | dispatch(selectAllMemories()); |
| #70 | } else { |
| #71 | dispatch(clearSelection()); |
| #72 | } |
| #73 | }; |
| #74 | |
| #75 | const handleSelectMemory = (id: string, checked: boolean) => { |
| #76 | if (checked) { |
| #77 | dispatch(selectMemory(id)); |
| #78 | } else { |
| #79 | dispatch(deselectMemory(id)); |
| #80 | } |
| #81 | }; |
| #82 | const { handleOpenUpdateMemoryDialog } = useUI(); |
| #83 | |
| #84 | const handleEditMemory = (memory_id: string, memory_content: string) => { |
| #85 | handleOpenUpdateMemoryDialog(memory_id, memory_content); |
| #86 | }; |
| #87 | |
| #88 | const handleUpdateMemoryState = async (id: string, newState: string) => { |
| #89 | try { |
| #90 | await updateMemoryState([id], newState); |
| #91 | } catch (error) { |
| #92 | toast({ |
| #93 | title: "Error", |
| #94 | description: "Failed to update memory state", |
| #95 | variant: "destructive", |
| #96 | }); |
| #97 | } |
| #98 | }; |
| #99 | |
| #100 | const isAllSelected = |
| #101 | memories.length > 0 && selectedMemoryIds.length === memories.length; |
| #102 | const isPartiallySelected = |
| #103 | selectedMemoryIds.length > 0 && selectedMemoryIds.length < memories.length; |
| #104 | |
| #105 | const handleMemoryClick = (id: string) => { |
| #106 | router.push(`/memory/${id}`); |
| #107 | }; |
| #108 | |
| #109 | return ( |
| #110 | <div className="rounded-md border"> |
| #111 | <Table className=""> |
| #112 | <TableHeader> |
| #113 | <TableRow className="bg-zinc-800 hover:bg-zinc-800"> |
| #114 | <TableHead className="w-[50px] pl-4"> |
| #115 | <Checkbox |
| #116 | className="data-[state=checked]:border-primary border-zinc-500/50" |
| #117 | checked={isAllSelected} |
| #118 | data-state={ |
| #119 | isPartiallySelected |
| #120 | ? "indeterminate" |
| #121 | : isAllSelected |
| #122 | ? "checked" |
| #123 | : "unchecked" |
| #124 | } |
| #125 | onCheckedChange={handleSelectAll} |
| #126 | /> |
| #127 | </TableHead> |
| #128 | <TableHead className="border-zinc-700"> |
| #129 | <div className="flex items-center min-w-[600px]"> |
| #130 | <HiMiniRectangleStack className="mr-1" /> |
| #131 | Memory |
| #132 | </div> |
| #133 | </TableHead> |
| #134 | <TableHead className="border-zinc-700"> |
| #135 | <div className="flex items-center"> |
| #136 | <PiSwatches className="mr-1" size={15} /> |
| #137 | Categories |
| #138 | </div> |
| #139 | </TableHead> |
| #140 | <TableHead className="w-[140px] border-zinc-700"> |
| #141 | <div className="flex items-center"> |
| #142 | <GoPackage className="mr-1" /> |
| #143 | Source App |
| #144 | </div> |
| #145 | </TableHead> |
| #146 | <TableHead className="w-[140px] border-zinc-700"> |
| #147 | <div className="flex items-center w-full justify-center"> |
| #148 | <CiCalendar className="mr-1" size={16} /> |
| #149 | Created On |
| #150 | </div> |
| #151 | </TableHead> |
| #152 | <TableHead className="text-right border-zinc-700 flex justify-center"> |
| #153 | <div className="flex items-center justify-end"> |
| #154 | <MoreHorizontal className="h-4 w-4 mr-2" /> |
| #155 | </div> |
| #156 | </TableHead> |
| #157 | </TableRow> |
| #158 | </TableHeader> |
| #159 | <TableBody> |
| #160 | {memories.map((memory) => ( |
| #161 | <TableRow |
| #162 | key={memory.id} |
| #163 | className={`hover:bg-zinc-900/50 ${ |
| #164 | memory.state === "paused" || memory.state === "archived" |
| #165 | ? "text-zinc-400" |
| #166 | : "" |
| #167 | } ${isLoading ? "animate-pulse opacity-50" : ""}`} |
| #168 | > |
| #169 | <TableCell className="pl-4"> |
| #170 | <Checkbox |
| #171 | className="data-[state=checked]:border-primary border-zinc-500/50" |
| #172 | checked={selectedMemoryIds.includes(memory.id)} |
| #173 | onCheckedChange={(checked) => |
| #174 | handleSelectMemory(memory.id, checked as boolean) |
| #175 | } |
| #176 | /> |
| #177 | </TableCell> |
| #178 | <TableCell className=""> |
| #179 | {memory.state === "paused" || memory.state === "archived" ? ( |
| #180 | <TooltipProvider> |
| #181 | <Tooltip delayDuration={0}> |
| #182 | <TooltipTrigger asChild> |
| #183 | <div |
| #184 | onClick={() => handleMemoryClick(memory.id)} |
| #185 | className={`font-medium ${ |
| #186 | memory.state === "paused" || |
| #187 | memory.state === "archived" |
| #188 | ? "text-zinc-400" |
| #189 | : "text-white" |
| #190 | } cursor-pointer`} |
| #191 | > |
| #192 | {memory.memory} |
| #193 | </div> |
| #194 | </TooltipTrigger> |
| #195 | <TooltipContent> |
| #196 | <p> |
| #197 | This memory is{" "} |
| #198 | <span className="font-bold"> |
| #199 | {memory.state === "paused" ? "paused" : "archived"} |
| #200 | </span>{" "} |
| #201 | and <span className="font-bold">disabled</span>. |
| #202 | </p> |
| #203 | </TooltipContent> |
| #204 | </Tooltip> |
| #205 | </TooltipProvider> |
| #206 | ) : ( |
| #207 | <div |
| #208 | onClick={() => handleMemoryClick(memory.id)} |
| #209 | className={`font-medium text-white cursor-pointer`} |
| #210 | > |
| #211 | {memory.memory} |
| #212 | </div> |
| #213 | )} |
| #214 | </TableCell> |
| #215 | <TableCell className=""> |
| #216 | <div className="flex flex-wrap gap-1"> |
| #217 | <Categories |
| #218 | categories={memory.categories} |
| #219 | isPaused={ |
| #220 | memory.state === "paused" || memory.state === "archived" |
| #221 | } |
| #222 | concat={true} |
| #223 | /> |
| #224 | </div> |
| #225 | </TableCell> |
| #226 | <TableCell className="w-[140px] text-center"> |
| #227 | <SourceApp source={memory.app_name} /> |
| #228 | </TableCell> |
| #229 | <TableCell className="w-[140px] text-center"> |
| #230 | {formatDate(memory.created_at)} |
| #231 | </TableCell> |
| #232 | <TableCell className="text-right flex justify-center"> |
| #233 | <DropdownMenu> |
| #234 | <DropdownMenuTrigger asChild> |
| #235 | <Button variant="ghost" size="icon" className="h-8 w-8"> |
| #236 | <MoreHorizontal className="h-4 w-4" /> |
| #237 | </Button> |
| #238 | </DropdownMenuTrigger> |
| #239 | <DropdownMenuContent |
| #240 | align="end" |
| #241 | className="bg-zinc-900 border-zinc-800" |
| #242 | > |
| #243 | <DropdownMenuItem |
| #244 | className="cursor-pointer" |
| #245 | onClick={() => { |
| #246 | const newState = |
| #247 | memory.state === "active" ? "paused" : "active"; |
| #248 | handleUpdateMemoryState(memory.id, newState); |
| #249 | }} |
| #250 | > |
| #251 | {memory?.state === "active" ? ( |
| #252 | <> |
| #253 | <Pause className="mr-2 h-4 w-4" /> |
| #254 | Pause |
| #255 | </> |
| #256 | ) : ( |
| #257 | <> |
| #258 | <Play className="mr-2 h-4 w-4" /> |
| #259 | Resume |
| #260 | </> |
| #261 | )} |
| #262 | </DropdownMenuItem> |
| #263 | <DropdownMenuItem |
| #264 | className="cursor-pointer" |
| #265 | onClick={() => { |
| #266 | const newState = |
| #267 | memory.state === "active" ? "archived" : "active"; |
| #268 | handleUpdateMemoryState(memory.id, newState); |
| #269 | }} |
| #270 | > |
| #271 | <Archive className="mr-2 h-4 w-4" /> |
| #272 | {memory?.state !== "archived" ? ( |
| #273 | <>Archive</> |
| #274 | ) : ( |
| #275 | <>Unarchive</> |
| #276 | )} |
| #277 | </DropdownMenuItem> |
| #278 | <DropdownMenuItem |
| #279 | className="cursor-pointer" |
| #280 | onClick={() => handleEditMemory(memory.id, memory.memory)} |
| #281 | > |
| #282 | <Edit className="mr-2 h-4 w-4" /> |
| #283 | Edit |
| #284 | </DropdownMenuItem> |
| #285 | <DropdownMenuSeparator /> |
| #286 | <DropdownMenuItem |
| #287 | className="cursor-pointer text-red-500 focus:text-red-500" |
| #288 | onClick={() => handleDeleteMemory(memory.id)} |
| #289 | > |
| #290 | <Trash2 className="mr-2 h-4 w-4" /> |
| #291 | Delete |
| #292 | </DropdownMenuItem> |
| #293 | </DropdownMenuContent> |
| #294 | </DropdownMenu> |
| #295 | </TableCell> |
| #296 | </TableRow> |
| #297 | ))} |
| #298 | </TableBody> |
| #299 | </Table> |
| #300 | </div> |
| #301 | ); |
| #302 | } |
| #303 |