aboutsummaryrefslogtreecommitdiff
path: root/apps/web/src/components/Sidebar/AddMemoryDialog.tsx
diff options
context:
space:
mode:
authoryxshv <[email protected]>2024-04-15 00:02:37 +0530
committeryxshv <[email protected]>2024-04-15 00:02:37 +0530
commit496849c9cf6b4436695cc3a173e68c7378715160 (patch)
tree6b9992638d65f975be627434b79dd902dfa57e4f /apps/web/src/components/Sidebar/AddMemoryDialog.tsx
parentfix route (diff)
downloadarchived-supermemory-496849c9cf6b4436695cc3a173e68c7378715160.tar.xz
archived-supermemory-496849c9cf6b4436695cc3a173e68c7378715160.zip
space expand layout
Diffstat (limited to 'apps/web/src/components/Sidebar/AddMemoryDialog.tsx')
-rw-r--r--apps/web/src/components/Sidebar/AddMemoryDialog.tsx139
1 files changed, 118 insertions, 21 deletions
diff --git a/apps/web/src/components/Sidebar/AddMemoryDialog.tsx b/apps/web/src/components/Sidebar/AddMemoryDialog.tsx
index f6a7224f..1406925c 100644
--- a/apps/web/src/components/Sidebar/AddMemoryDialog.tsx
+++ b/apps/web/src/components/Sidebar/AddMemoryDialog.tsx
@@ -13,25 +13,24 @@ import { useEffect, useRef, useState } from "react";
import { FilterMemories, FilterSpaces } from "./FilterCombobox";
import { useMemory } from "@/contexts/MemoryContext";
import { Loader, Plus, X } from "lucide-react";
-import { StoredContent } from "@/server/db/schema";
+import { StoredContent, StoredSpace } from "@/server/db/schema";
import { cleanUrl } from "@/lib/utils";
import { motion } from "framer-motion";
import { getMetaData } from "@/server/helpers";
-export function AddMemoryPage({ closeDialog }: { closeDialog: () => void }) {
+export function AddMemoryPage({ closeDialog, defaultSpaces, onAdd }: { closeDialog: () => void, defaultSpaces?: number[], onAdd?: (addedData: StoredContent) => void }) {
const { addMemory } = useMemory();
const [loading, setLoading] = useState(false);
const [url, setUrl] = useState("");
- const [selectedSpacesId, setSelectedSpacesId] = useState<number[]>([]);
+ const [selectedSpacesId, setSelectedSpacesId] = useState<number[]>(defaultSpaces ?? []);
return (
<div className="md:w-[40vw]">
<DialogHeader>
<DialogTitle>Add a web page to memory</DialogTitle>
<DialogDescription>
- This will take you the web page you are trying to add to memory, where
- the extension will save the page to memory
+ This will fetch the content of the web page and add it to the memory
</DialogDescription>
</DialogHeader>
<Label className="mt-5 block">URL</Label>
@@ -58,7 +57,7 @@ export function AddMemoryPage({ closeDialog }: { closeDialog: () => void }) {
onClick={async () => {
setLoading(true);
const metadata = await getMetaData(url);
- await addMemory(
+ const data = await addMemory(
{
title: metadata.title,
description: metadata.description,
@@ -70,6 +69,7 @@ export function AddMemoryPage({ closeDialog }: { closeDialog: () => void }) {
},
selectedSpacesId,
);
+ if (data) onAdd?.(data.memory)
closeDialog();
}}
className="bg-rgray-4 hover:bg-rgray-5 focus-visible:bg-rgray-5 focus-visible:ring-rgray-7 relative rounded-md px-4 py-2 ring-transparent transition focus-visible:outline-none focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-70"
@@ -99,10 +99,10 @@ export function AddMemoryPage({ closeDialog }: { closeDialog: () => void }) {
);
}
-export function NoteAddPage({ closeDialog }: { closeDialog: () => void }) {
+export function NoteAddPage({ closeDialog, defaultSpaces, onAdd }: { closeDialog: () => void, defaultSpaces?: number[], onAdd?: (addedData: StoredContent) => void }) {
const { addMemory } = useMemory();
- const [selectedSpacesId, setSelectedSpacesId] = useState<number[]>([]);
+ const [selectedSpacesId, setSelectedSpacesId] = useState<number[]>(defaultSpaces ?? []);
const inputRef = useRef<HTMLInputElement>(null);
const [name, setName] = useState("");
@@ -175,7 +175,10 @@ export function NoteAddPage({ closeDialog }: { closeDialog: () => void }) {
savedAt: new Date(),
},
selectedSpacesId,
- ).then(closeDialog);
+ ).then((data) => {
+ if (data?.memory) onAdd?.(data.memory)
+ closeDialog()
+ });
}
}}
disabled={loading}
@@ -207,7 +210,7 @@ export function NoteAddPage({ closeDialog }: { closeDialog: () => void }) {
);
}
-export function SpaceAddPage({ closeDialog }: { closeDialog: () => void }) {
+export function SpaceAddPage({ closeDialog, onAdd }: { closeDialog: () => void, onAdd?: (addedData: StoredSpace) => void }) {
const { addSpace } = useMemory();
const inputRef = useRef<HTMLInputElement>(null);
@@ -289,7 +292,10 @@ export function SpaceAddPage({ closeDialog }: { closeDialog: () => void }) {
addSpace(
name,
selected.map((s) => s.id),
- ).then(() => closeDialog());
+ ).then((data) => {
+ if (data) onAdd?.(data.space)
+ closeDialog()
+ });
}
}}
disabled={loading}
@@ -329,19 +335,18 @@ export function MemorySelectedItem({
onRemove,
}: StoredContent & { onRemove: () => void }) {
return (
- <div className="hover:bg-rgray-4 focus-within-bg-rgray-4 flex w-full items-center justify-start gap-2 rounded-md p-1 px-2 text-sm [&:hover>[data-icon]]:block [&:hover>img]:hidden">
- <img
- src={
- type === "note" ? "/note.svg" : image ?? "/icons/logo_without_bg.png"
- }
- className="h-5 w-5"
- />
+ <div className="hover:bg-rgray-4 focus-within-bg-rgray-4 flex w-full items-center justify-start gap-2 rounded-md p-2 px-3 text-sm [&:hover_[data-icon]]:block [&:hover_img]:hidden">
<button
onClick={onRemove}
- data-icon
- className="m-0 hidden h-5 w-5 p-0 focus-visible:outline-none"
+ className="m-0 h-5 w-5 p-0 [&:focus-visible>[data-icon]]:block [&:focus-visible>img]:hidden focus-visible:outline-none focus-visible:ring-2 ring-rgray-7 rounded-sm ring-offset-2 ring-offset-rgray-3"
>
- <X className="h-5 w-5 scale-90" />
+ <img
+ src={
+ type === "note" ? "/note.svg" : image ?? "/icons/logo_without_bg.png"
+ }
+ className="h-5 w-5"
+ />
+ <X data-icon className="h-5 w-5 hidden scale-90" />
</button>
<span>{title}</span>
<span className="ml-auto block opacity-50">
@@ -350,3 +355,95 @@ export function MemorySelectedItem({
</div>
);
}
+
+export function AddExistingMemoryToSpace({
+ space,
+ closeDialog,
+ fromSpaces,
+ notInSpaces,
+ onAdd
+}: {
+ space: { title: string, id: number },
+ closeDialog: () => void,
+ fromSpaces?: number[],
+ notInSpaces?: number[],
+ onAdd?: () => void;
+}) {
+ const { addMemoriesToSpace } = useMemory();
+
+ const [loading, setLoading] = useState(false);
+
+ const [selected, setSelected] = useState<StoredContent[]>([]);
+
+ return (
+ <div className="md:w-[40vw]">
+ <DialogHeader>
+ <DialogTitle>Add an existing memory to {space.title}</DialogTitle>
+ <DialogDescription>
+ Pick the memories you want to add to this space
+ </DialogDescription>
+ </DialogHeader>
+ {selected.length > 0 && (
+ <>
+ <Label className="mt-5 block">Add Memories</Label>
+ <div className="flex min-h-5 flex-col items-center justify-center py-2">
+ {selected.map((i) => (
+ <MemorySelectedItem
+ key={i.id}
+ onRemove={() =>
+ setSelected((prev) => prev.filter((p) => p.id !== i.id))
+ }
+ {...i}
+ />
+ ))}
+ </div>
+ </>
+ )}
+ <DialogFooter>
+ <FilterMemories
+ selected={selected}
+ setSelected={setSelected}
+ disabled={loading}
+ fromSpaces={fromSpaces}
+ notInSpaces={notInSpaces}
+ className="hover:bg-rgray-4 focus-visible:bg-rgray-4 mr-auto bg-white/5 disabled:cursor-not-allowed disabled:opacity-70"
+ >
+ <Plus className="h-5 w-5" />
+ Memory
+ </FilterMemories>
+ <button
+ type={undefined}
+ onClick={() => {
+ setLoading(true);
+ addMemoriesToSpace(space.id, selected.map(i => i.id)).then(() => {
+ onAdd?.()
+ closeDialog();
+ });
+ }}
+ disabled={loading}
+ className="bg-rgray-4 hover:bg-rgray-5 focus-visible:bg-rgray-5 focus-visible:ring-rgray-7 relative rounded-md px-4 py-2 ring-transparent transition focus-visible:outline-none focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-70"
+ >
+ <motion.div
+ initial={{ x: "-50%", y: "-100%" }}
+ animate={loading && { y: "-50%", x: "-50%", opacity: 1 }}
+ className="absolute left-1/2 top-1/2 -translate-x-1/2 translate-y-[-100%] opacity-0"
+ >
+ <Loader className="text-rgray-11 h-5 w-5 animate-spin" />
+ </motion.div>
+ <motion.div
+ initial={{ y: "0%" }}
+ animate={loading && { opacity: 0, y: "30%" }}
+ >
+ Add
+ </motion.div>
+ </button>
+ <DialogClose
+ disabled={loading}
+ className="hover:bg-rgray-4 focus-visible:bg-rgray-4 focus-visible:ring-rgray-7 rounded-md px-3 py-2 ring-transparent transition focus-visible:outline-none focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-70"
+ >
+ Cancel
+ </DialogClose>
+ </DialogFooter>
+ </div>
+ );
+}