Skip to content

Commit

Permalink
feat: download canvas as image #128
Browse files Browse the repository at this point in the history
  • Loading branch information
hughlv committed Jan 10, 2025
1 parent 3da36ea commit ae4ead7
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 13 deletions.
2 changes: 1 addition & 1 deletion api/agentok_api/templates/assistant.j2
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# agents.j2
{%- macro generate_assistants(assistant_nodes) %}
# Assistant Agents
{%- for node in assistant_nodes %}
{%- set name = node.data.name %}

node_{{ node.id }} = {{ node.data.class_type }}(
name="{{ name }}",
{%- if node.data.system_message %}
Expand Down
4 changes: 2 additions & 2 deletions api/agentok_api/templates/conversable_agent.j2
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# conversable_agents.j2
{% macro generate_conversable_agents(conversable_nodes) %}
{%- macro generate_conversable_agents(conversable_nodes) -%}

import tempfile
temp_dir = tempfile.gettempdir()
Expand Down Expand Up @@ -34,4 +34,4 @@ node_{{ node.id }} = {{ node.data.class_type }}(
{%- endif %}
)
{% endfor %}
{% endmacro %}
{%- endmacro -%}
2 changes: 1 addition & 1 deletion api/agentok_api/templates/tool.j2
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Tools
{%- if tool_dict and tool_dict | length > 0 %}
{% if tool_dict and tool_dict | length > 0 %}
{%- for tool in tool_dict.values() %}
{%- if tool.code %}

Expand Down
1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"date-fns": "^4.1.0",
"html-to-image": "^1.11.11",
"immer": "^10.1.1",
"katex": "^0.16.11",
"lodash-es": "^4.17.21",
Expand Down
20 changes: 14 additions & 6 deletions frontend/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions frontend/src/components/navbar/auth-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const AuthButton = () => {
<DropdownMenuTrigger>
<UserAvatar
user={user}
className="w-10 h-10 bg-muted-foreground/50 text-muted"
className="w-10 h-10 bg-muted-foreground/20 text-primary"
/>
</DropdownMenuTrigger>
<DropdownMenuContent
Expand All @@ -74,7 +74,7 @@ export const AuthButton = () => {
<div className="flex items-center p-2 gap-2">
<UserAvatar
user={user}
className="w-10 h-10 bg-muted-foreground/50 text-muted"
className="w-10 h-10 bg-muted-foreground/20 text-primary"
/>
<div className="flex flex-col gap-1">
<span className="font-bold">
Expand Down
58 changes: 57 additions & 1 deletion frontend/src/components/project/project-config.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,60 @@
import { useProject } from '@/hooks';
import { ScrollArea } from '@radix-ui/react-scroll-area';
import { ScrollArea } from '../ui/scroll-area';
import { GenericOption } from '../flow/option/option';
import { Button } from '../ui/button';
import { Icons } from '../icons';
import { useReactFlow } from '@xyflow/react';
import { toast } from '@/hooks/use-toast';
import { toPng } from 'html-to-image';

export const ProjectConfig = ({ projectId }: { projectId: number }) => {
const { project, updateProject } = useProject(projectId);
const instance = useReactFlow();

const handleChange = (name: string, value: any) => {
updateProject({ [name]: value }).catch(console.error);
};

const handleDownloadImage = () => {
// Get the ReactFlow container element
const flowElement = document.querySelector('.react-flow') as HTMLElement;
if (!flowElement) {
toast({
title: 'Error',
description: 'Could not find the flow canvas',
variant: 'destructive',
});
return;
}

toPng(flowElement, {
backgroundColor: '#ffffff00', // transparent background
quality: 1,
pixelRatio: 2,
})
.then((dataUrl: string) => {
const link = document.createElement('a');
link.href = dataUrl;
link.download = `${project?.name || 'flow'}-canvas.png`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);

toast({
title: 'Success',
description: 'Canvas image downloaded successfully',
});
})
.catch((error: Error) => {
console.error('Failed to download canvas:', error);
toast({
title: 'Error',
description: 'Failed to download canvas image',
variant: 'destructive',
});
});
};

return (
<ScrollArea className="h-full p-2">
<div className="flex flex-col gap-4">
Expand All @@ -27,6 +75,14 @@ export const ProjectConfig = ({ projectId }: { projectId: number }) => {
data={{ description: project?.description }}
onValueChange={handleChange}
/>
<Button
onClick={handleDownloadImage}
className="w-full flex items-center gap-2"
variant="outline"
>
<Icons.download className="w-4 h-4" />
Download Canvas
</Button>
</div>
</ScrollArea>
);
Expand Down

0 comments on commit ae4ead7

Please sign in to comment.