-
Notifications
You must be signed in to change notification settings - Fork 297
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Create notebook copies #2227
Changes from 2 commits
19e5df7
fcbb8af
910c297
99fd552
13a8de3
ae1c7e6
0330f87
5a33dbe
281285a
2df9c99
fa12271
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ import { | |
getRunningNotebooks, | ||
shutdownSession, | ||
openTutorial, | ||
sendCopy, | ||
} from "@/core/network/requests"; | ||
import { combineAsyncData, useAsyncData } from "@/hooks/useAsyncData"; | ||
import type React from "react"; | ||
|
@@ -19,6 +20,7 @@ import { | |
ChevronRightIcon, | ||
ChevronsDownUpIcon, | ||
ClockIcon, | ||
Copy, | ||
DatabaseIcon, | ||
ExternalLinkIcon, | ||
FileIcon, | ||
|
@@ -73,7 +75,7 @@ import { | |
} from "../home/state"; | ||
import { Maps } from "@/utils/maps"; | ||
import { Input } from "../ui/input"; | ||
import { Paths } from "@/utils/paths"; | ||
import { PathBuilder, Paths } from "@/utils/paths"; | ||
import { | ||
DropdownMenu, | ||
DropdownMenuTrigger, | ||
|
@@ -441,9 +443,8 @@ const MarimoFileComponent = ({ | |
</div> | ||
<div className="flex flex-col gap-1 items-end"> | ||
<div className="flex gap-3 items-center"> | ||
<div> | ||
<SessionShutdownButton filePath={file.path} /> | ||
</div> | ||
<CopyNotebookButton filePath={file.path} /> | ||
<SessionShutdownButton filePath={file.path} /> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we need this on the homepage - at least for now. This is also probably why you were getting mismatch sessions. Since the homepage doesn't have an active session |
||
{openNewTab && ( | ||
<ExternalLinkIcon | ||
size={20} | ||
|
@@ -516,6 +517,46 @@ const SessionShutdownButton: React.FC<{ filePath: string }> = ({ | |
); | ||
}; | ||
|
||
const CopyNotebookButton: React.FC<{ filePath: string }> = ({ filePath }) => { | ||
const { openPrompt, closeModal } = useImperativeModal(); | ||
return ( | ||
<Tooltip content="Copy"> | ||
<Button | ||
size={"icon"} | ||
variant="outline" | ||
className="opacity-0 group-hover:opacity-100 hover:bg-accent text-primary border-primary hover:border-primary hover:text-primary bg-background hover:bg-[var(--blue-1)]" | ||
onClick={(e) => { | ||
e.stopPropagation(); | ||
e.preventDefault(); | ||
const pathBuilder = new PathBuilder("/"); | ||
openPrompt({ | ||
title: "Copy notebook", | ||
description: "Enter a new filename for the notebook copy.", | ||
defaultValue: `_${Paths.basename(filePath)}`, | ||
confirmText: "Copy notebook", | ||
spellCheck: false, | ||
onConfirm: (destination: string) => { | ||
sendCopy({ | ||
source: filePath, | ||
destination: pathBuilder.join( | ||
Paths.dirname(filePath), | ||
destination, | ||
), | ||
}); | ||
closeModal(); | ||
toast({ | ||
description: "Notebook has been copied.", | ||
}); | ||
}, | ||
}); | ||
}} | ||
> | ||
<Copy size={14} /> | ||
</Button> | ||
</Tooltip> | ||
); | ||
}; | ||
|
||
const CreateNewNotebook: React.FC = () => { | ||
const sessionId = generateSessionId(); | ||
const initializationId = `__new__${sessionId}`; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,6 +31,7 @@ export const { | |
sendRestart, | ||
syncCellIds, | ||
sendSave, | ||
sendCopy, | ||
sendStdin, | ||
sendFormat, | ||
sendInterrupt, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -187,6 +187,11 @@ export class PyodideBridge implements RunRequests, EditRequests { | |
return null; | ||
}; | ||
|
||
sendCopy: EditRequests["sendCopy"] = async () => { | ||
// TODO: Implement copy with pyodide! | ||
return null; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can throw not implemented. And I think we can hide this action in the notebook dropdown when isWasm is true |
||
}; | ||
|
||
sendStdin: EditRequests["sendStdin"] = async (request) => { | ||
await this.rpc.proxy.request.bridge({ | ||
functionName: "put_input", | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can put this in notebook actions - so it automatically appears in the notebook dropdown and in the command palette. It doesn't need to be its own button.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good! I was just going off the issue author's suggestions, thought it'd be a simple add
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yea I didn't see the second part of the issue mentioning that. I don't know how common it'll be and does complicate the routes. I think we hold off homepage and consider later