Skip to content

Commit

Permalink
Added Template
Browse files Browse the repository at this point in the history
  • Loading branch information
anoopkarnik committed Nov 23, 2024
1 parent 1ff7935 commit 2424796
Show file tree
Hide file tree
Showing 12 changed files with 390 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ const PublicWorkflows = () => {
useEffect(()=>{
async function fetchWorkflows(){
const flows = await getPublicWorkflowsAction();
console.log(flows)
setWorkflows(flows);
}
fetchWorkflows()
},[])

return (
<div className='grid grid-cols-1 lg:grid-cols-2 2xl:grid-cols-3 w-full py-10 overflow-y-auto gap-4'>
{workflows?.map((workflow:any) => (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
'use client'

import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@repo/ui/molecules/shadcn/Card'
import { ArrowRightIcon, CopyIcon } from 'lucide-react'
import DynamicIcon from '../../../../components/DynamicIcon'
import { useRouter } from 'next/navigation'
import { useSession } from 'next-auth/react'
import { useToast } from '../../../../hooks/useToast'
import { duplicateWorkflow, editFlow, makeFlowPublic } from '../../../actions/workflows/workflow'
import { Label } from '@repo/ui/atoms/shadcn/Label'
import { Switch } from '@repo/ui/molecules/shadcn/Switch'
import { useState } from 'react'
import { Input } from '@repo/ui/atoms/shadcn/Input'
import { Textarea } from '@repo/ui/atoms/shadcn/Textarea'


const Template = ({workflow}:any) => {
const router = useRouter();
const session = useSession();
const userId = session.data?.user?.id;
const [toggle,setToggle] = useState(workflow.shared || false)
const [name, setName] = useState(workflow.name);
const [description, setDescription] = useState(workflow.description);
const [showNameEdit,setShowNameEdit] = useState(false);
const [showDescriptionEdit,setShowDescriptionEdit] = useState(false);

const onToggle = async () =>{
setToggle(!toggle)
await makeFlowPublic(workflow.id,!toggle)
}

const handleEditName = async () =>{
if (showNameEdit) {
setName(name)
await editFlow(workflow.id,name,description);
}
setShowNameEdit(!showNameEdit);
// router.refresh();
}

const handleEditDescription = async () =>{
if (showDescriptionEdit){
setDescription(description)
await editFlow(workflow.id,name,description);
}
setShowDescriptionEdit(!showDescriptionEdit);
}

return (
<Card className=''>
<CardHeader className=''>
<CardTitle className='flex items-center justify-between leading-3 '>
<div className='flex items-center gap-2 w-full justify-between leading-normal'>
{showNameEdit ? (
<Input
className='w-[80%] break-words whitespace-normal bg-background dark:bg-background dark:text-foreground'
placeholder={name}
onChange={(e: any) => setName(e.target.value)}
onBlur={handleEditName} // Exit edit mode when clicking outside the input
autoFocus // Automatically focus the input when entering edit mode
/>
) : (
// Add onDoubleClick to enable editing on double click
<div className='w-[80%] break-words whitespace-normal text-wrap text-button' onDoubleClick={handleEditName}>
{name}
</div>
)}
</div>
<div className='flex items-center gap-2 text-right '>
<Label htmlFor='airplane-mode'>
{toggle? 'Private': 'Public'}
</Label>
<Switch id='airplane-mode' onClick={onToggle} defaultChecked={toggle} />
</div>

</CardTitle>
<CardDescription className='text-description text-xs leading-snug '>
<div className='flex items-start justify-start gap-2 text-sm text-description w-full '>
{showDescriptionEdit ? (
<Textarea
placeholder={description}
onChange={(e: any) => setDescription(e.target.value)}
onBlur={handleEditDescription} // Exit edit mode when clicking outside the input
autoFocus // Automatically focus the input when entering edit mode
className='w-full mt-2'
/>
) : (
// Add onDoubleClick to enable editing on double click
<div className='text-description' onDoubleClick={handleEditDescription}>
{description || 'Add Description Here'}
</div>
)}
</div>
</CardDescription>

</CardHeader>
<CardContent className=''>
<CardDescription>

<div className='flex items-center justify-start gap-2 flex-wrap mt-2'>
{workflow.trigger && <>
<DynamicIcon icon={workflow.trigger.type.triggerType.icon}/>
<ArrowRightIcon className='w-2 h-2'/>
</>
}
{workflow.actions.map((action:any) => (
<><DynamicIcon key={action.id} icon={action.type.actionType.icon}/>
</>
))}
</div>
</CardDescription>
</CardContent>
</Card>
)
}

export default Template
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"use client"
/* eslint-disable */

import React, { useEffect, useState } from 'react'
import { getTemplatesAction } from '../../../actions/workflows/workflow'
import PublicWorkflow from './PublicWorkflow'
import { useSession } from 'next-auth/react'
import Template from './Template'

const Templates = () => {
const [workflows,setWorkflows] = useState<any>([])
const session = useSession();
const userId = session.data?.user?.id;

useEffect(()=>{
async function fetchWorkflows(){
const flows = await getTemplatesAction(userId || '');
setWorkflows(flows);
}
fetchWorkflows()
},[userId])

return (
<div className='grid grid-cols-1 lg:grid-cols-2 2xl:grid-cols-3 w-full py-10 overflow-y-auto gap-4'>
{workflows?.map((workflow:any) => (
<Template key={workflow.id} workflow={workflow}/>
))}
</div>
)
}

export default Templates
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { CopyIcon, Edit2Icon, TrashIcon } from 'lucide-react'
import { useRouter } from 'next/navigation'
import React, { useState } from 'react'
import { useToast } from '../../../../hooks/useToast'
import { deleteFlow, duplicateWorkflow, makeFlowPublic, publishFlow } from '../../../actions/workflows/workflow'
import { createTemplate, deleteFlow, duplicateWorkflow, makeFlowPublic, publishFlow } from '../../../actions/workflows/workflow'
import { Checkbox } from '@repo/ui/atoms/shadcn/Checkbox'
import { useSession } from 'next-auth/react'

Expand Down Expand Up @@ -49,6 +49,17 @@ const WorkflowDropdown = ({workflow}:any) => {
toast({title: "Error", description: res?.error, variant: 'destructive'})
}
}

const onTemplateCreation = async () => {
const res = await createTemplate(workflow.id,userId)
if (res.success){
toast({title: "Success", description: res?.success, variant: 'default'})
router.refresh()
}
else if (res.error){
toast({title: "Error", description: res?.error, variant: 'destructive'})
}
}
return (
<DropdownMenuContent>
<DropdownMenuItem className='cursor-pointer' onClick={()=>router.push(`/automations/editor/${workflow.id}`)}>
Expand All @@ -63,16 +74,22 @@ const WorkflowDropdown = ({workflow}:any) => {
<div>Duplicate</div>
</div>
</DropdownMenuItem>
<DropdownMenuItem className='cursor-pointer' onClick={onTemplateCreation}>
<div className='flex items-center gap-2'>
<CopyIcon className=' w-4 h-4'/>
<div>Create Template</div>
</div>
</DropdownMenuItem>
<DropdownMenuItem onClick={onPublish} className='cursor-pointer flex gap-2 items-center'>
<Checkbox checked={publish}/>
{!publish && <div >Publish</div>}
{publish && <div >Unpublish</div>}
</DropdownMenuItem>
<DropdownMenuItem onClick={onPublic} className='cursor-pointer flex gap-2 items-center'>
{/* <DropdownMenuItem onClick={onPublic} className='cursor-pointer flex gap-2 items-center'>
<Checkbox checked={publicWorkflow}/>
{!publicWorkflow && <div>Make Public</div>}
{publicWorkflow && <div>Make Private</div>}
</DropdownMenuItem>
</DropdownMenuItem> */}
<DropdownMenuItem>
<div className='flex items-center gap-2 cursor-pointer' onClick={()=>handleDelete(workflow.id)}>
<TrashIcon className='cursor-pointer w-4 h-4'/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,17 @@ export const PythonCode = ({funcType,nodeType,type,subType,node}: any) => {
setCodeBlocks(updatedCodeBlocks);
}

const modifyVariable = (blockId: number,index: number,key: string,value: string) => {
const updatedCodeBlocks = codeBlocks.map((block:any) => {
if (block.id === blockId) {
block.variables[index] = { key, value };
}
return block;
});
setCodeBlocks(updatedCodeBlocks);

}



return (
Expand All @@ -222,7 +233,8 @@ export const PythonCode = ({funcType,nodeType,type,subType,node}: any) => {
{codeBlocks.map((block: any,index: number) => (
<PythonCodeBlock block={block} modifyTitle={modifyTitle} removeVariable={removeVariable}
addVariable={addVariable} modifyCode={modifyCode} addCodeBlock={addCodeBlock}
removeCodeBlock={removeCodeBlock} runTillCurrentCode={runTillCurrentCode} index={index}/>
removeCodeBlock={removeCodeBlock} runTillCurrentCode={runTillCurrentCode}
modifyVariable={modifyVariable} index={index}/>
))}

{output && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@repo/
import { Input } from '@repo/ui/atoms/shadcn/Input';
import { Label } from '@repo/ui/atoms/shadcn/Label';
import { Alert, AlertDescription } from '@repo/ui/atoms/shadcn/Alert';
import PythonCodeBlockVariables from './PythonCodeBlockVariables';

interface VariablesProps {
key: string;
Expand All @@ -29,7 +30,7 @@ interface CodeBlockProps {
}

const PythonCodeBlock = ({block,modifyTitle,removeVariable,addVariable,modifyCode,addCodeBlock,removeCodeBlock,
runTillCurrentCode,index}:any) => {
runTillCurrentCode,modifyVariable,index}:any) => {

const [output, setOutput] = useState<any>('');
const [error, setError] = useState<any>('');
Expand All @@ -46,6 +47,9 @@ const PythonCodeBlock = ({block,modifyTitle,removeVariable,addVariable,modifyCod
setValue('')
}




const runCode = async (block:any) => {
setError('');
setOutput('');
Expand Down Expand Up @@ -120,22 +124,8 @@ const PythonCodeBlock = ({block,modifyTitle,removeVariable,addVariable,modifyCod
<Label className='text-description ml-[1px]'>Variables</Label>
<div className='flex flex-col gap-2'>
{block.variables?.map((variable: any,index:any) => (
<div className='flex gap-2 items-center'>
<div className='w-[30%] border-[1px] rounded-md p-2 break-words whitespace-normal text-wrap text-paragraph'>
{variable.key}
</div>
<div className='w-[50%] border-[1px] rounded-md p-2 break-words whitespace-normal text-wrap text-paragraph'>
{variable.value}
</div>

<ConfirmDialog
alertActionFunction={() => removeVariable(block.id, index)}
alertTitle='Delete Property'
alertDescription='Are you sure you want to delete this property?'
buttonDiv={<Trash2Icon className='w-5 h-5 cursor-pointer col-span-1 text-foreground/50' />}
alertActionText='Delete'
/>
</div>
<PythonCodeBlockVariables variable={variable} removeVariable={removeVariable} block={block}
index={index} modifyVariable={modifyVariable} key={index}/>
))}
<div className='flex gap-2 items-center'>
<Input
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { Input } from '@repo/ui/atoms/shadcn/Input';
import ConfirmDialog from '@repo/ui/molecules/custom/ConfirmDialog'
import { set } from 'date-fns';
import { Trash2Icon } from 'lucide-react'
import React, { useState } from 'react'

const PythonCodeBlockVariables = ({variable,removeVariable,block,index,modifyVariable}:any) => {
const [key, setKey] = useState(variable.key);
const [value, setValue] = useState(variable.value);
const [showKeyEdit, setShowKeyEdit] = useState(false);
const [showValueEdit, setShowValueEdit] = useState(false);

const modifyKey = async () =>{
if (showKeyEdit){
setKey(key)
await modifyVariable(block.id,index,key,value)
}
setShowKeyEdit(!showKeyEdit)
}

const modifyValue = async () =>{
if (showValueEdit){
setValue(value)
await modifyVariable(block.id,index,key,value)
}
setShowValueEdit(!showValueEdit)
}

return (
<div className='flex gap-2 items-center'>
{showKeyEdit ? (
<Input
className='w-[30%] break-words whitespace-normal bg-background dark:bg-background dark:text-foreground'
placeholder={key}
onChange={(e: any) => setKey(e.target.value)}
onBlur={modifyKey} // Exit edit mode when clicking outside the input
autoFocus // Automatically focus the input when entering edit mode
/>):(
<div onDoubleClick={modifyKey} className='w-[30%] border-[1px] rounded-md p-2 break-words whitespace-normal text-wrap text-paragraph'>
{key}
</div>
)}
{showValueEdit ? (
<Input
className='w-[30%] break-words whitespace-normal bg-background dark:bg-background dark:text-foreground'
placeholder={value}
onChange={(e: any) => setValue(e.target.value)}
onBlur={modifyValue} // Exit edit mode when clicking outside the input
autoFocus // Automatically focus the input when entering edit mode
/>):(
<div onDoubleClick={modifyValue} className='w-[30%] border-[1px] rounded-md p-2 break-words whitespace-normal text-wrap text-paragraph'>
{value}
</div>
)}

<ConfirmDialog
alertActionFunction={() => removeVariable(block.id, index)}
alertTitle='Delete Property'
alertDescription='Are you sure you want to delete this property?'
buttonDiv={<Trash2Icon className='w-5 h-5 cursor-pointer col-span-1 text-foreground/50' />}
alertActionText='Delete'
/>
</div>
)
}

export default PythonCodeBlockVariables
Loading

0 comments on commit 2424796

Please sign in to comment.