Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { Button } from '@/components/ui/button'
import { Card, CardContent } from '@/components/ui/card'
import { CopyButton } from '@/components/ui/copy-button'
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'
import { env } from '@/lib/env'
import { getEnv } from '@/lib/env'
import { createLogger } from '@/lib/logs/console-logger'
import { cn } from '@/lib/utils'
import { ChatDeploy } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/chat-deploy/chat-deploy'
Expand Down Expand Up @@ -225,7 +225,7 @@ export function DeployModal({
}

const data = await response.json()
const endpoint = `${env.NEXT_PUBLIC_APP_URL}/api/workflows/${workflowId}/execute`
const endpoint = `${getEnv('NEXT_PUBLIC_APP_URL')}/api/workflows/${workflowId}/execute`
const inputFormatExample = getInputFormatExample()

setDeploymentInfo({
Expand Down Expand Up @@ -288,7 +288,7 @@ export function DeployModal({
}

// Update the local deployment info
const endpoint = `${env.NEXT_PUBLIC_APP_URL}/api/workflows/${workflowId}/execute`
const endpoint = `${getEnv('NEXT_PUBLIC_APP_URL')}/api/workflows/${workflowId}/execute`
const inputFormatExample = getInputFormatExample()

const newDeploymentInfo = {
Expand Down Expand Up @@ -597,7 +597,7 @@ export function DeployModal({
<DeployForm
apiKeys={apiKeys}
keysLoaded={keysLoaded}
endpointUrl={`${env.NEXT_PUBLIC_APP_URL}/api/workflows/${workflowId}/execute`}
endpointUrl={`${getEnv('NEXT_PUBLIC_APP_URL')}/api/workflows/${workflowId}/execute`}
workflowId={workflowId || ''}
onSubmit={onDeploy}
getInputFormatExample={getInputFormatExample}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
CommandList,
} from '@/components/ui/command'
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
import { env } from '@/lib/env'
import { getEnv } from '@/lib/env'
import { createLogger } from '@/lib/logs/console-logger'
import {
type Credential,
Expand Down Expand Up @@ -301,7 +301,7 @@ export function GoogleDrivePicker({
showUploadFolders: true,
supportDrives: true,
multiselect: false,
appId: env.NEXT_PUBLIC_GOOGLE_PROJECT_NUMBER,
appId: getEnv('NEXT_PUBLIC_GOOGLE_PROJECT_NUMBER'),
// Enable folder selection when mimeType is folder
setSelectFolderEnabled: !!mimeTypeFilter?.includes('folder'),
callbackFunction: (data) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { useEffect, useState } from 'react'
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
import { env } from '@/lib/env'
import { getEnv } from '@/lib/env'
import type { SubBlockConfig } from '@/blocks/types'
import { useCollaborativeWorkflow } from '@/hooks/use-collaborative-workflow'
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
Expand Down Expand Up @@ -169,8 +169,8 @@ export function FileSelectorInput({
}

// For Google Drive
const clientId = env.NEXT_PUBLIC_GOOGLE_CLIENT_ID || ''
const apiKey = env.NEXT_PUBLIC_GOOGLE_API_KEY || ''
const clientId = getEnv('NEXT_PUBLIC_GOOGLE_CLIENT_ID') || ''
const apiKey = getEnv('NEXT_PUBLIC_GOOGLE_API_KEY') || ''

// Render Google Calendar selector
if (isGoogleCalendar) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ import { logger } from '@sentry/nextjs'
import { File, Folder, Plus, Upload } from 'lucide-react'
import { useParams, useRouter } from 'next/navigation'
import { Button } from '@/components/ui/button'
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
import { generateFolderName } from '@/lib/naming'
import { cn } from '@/lib/utils'
import { useUserPermissionsContext } from '@/app/workspace/[workspaceId]/w/components/providers/workspace-permissions-provider'
import { useFolderStore } from '@/stores/folders/store'
Expand All @@ -25,8 +23,6 @@ export function CreateMenu({
isCollapsed,
isCreatingWorkflow = false,
}: CreateMenuProps) {
const [showFolderDialog, setShowFolderDialog] = useState(false)
const [folderName, setFolderName] = useState('')
const [isCreating, setIsCreating] = useState(false)
const [isOpen, setIsOpen] = useState(false)
const [pressTimer, setPressTimer] = useState<NodeJS.Timeout | null>(null)
Expand Down Expand Up @@ -61,10 +57,37 @@ export function CreateMenu({
}
}, [onCreateWorkflow, isCreatingWorkflow, router, workspaceId])

const handleCreateFolder = useCallback(() => {
const handleCreateFolder = useCallback(async () => {
setIsOpen(false)
setShowFolderDialog(true)
}, [])

if (isCreating) {
logger.info('Folder creation already in progress, ignoring request')
return
}

if (!workspaceId) {
logger.error('No workspaceId available for folder creation')
return
}

try {
setIsCreating(true)

// Generate folder name using fresh data from API
const folderName = await generateFolderName(workspaceId)

await createFolder({
name: folderName,
workspaceId: workspaceId,
})

logger.info(`Created folder: ${folderName}`)
} catch (error) {
logger.error('Failed to create folder:', { error })
} finally {
setIsCreating(false)
}
}, [createFolder, workspaceId])

const handleImportWorkflow = useCallback(() => {
setIsOpen(false)
Expand Down Expand Up @@ -146,30 +169,6 @@ export function CreateMenu({
}
}, [pressTimer])

const handleFolderSubmit = async (e: React.FormEvent) => {
e.preventDefault()
if (!folderName.trim() || !workspaceId) return

setIsCreating(true)
try {
await createFolder({
name: folderName.trim(),
workspaceId: workspaceId,
})
setFolderName('')
setShowFolderDialog(false)
} catch (error) {
logger.error('Failed to create folder:', { error })
} finally {
setIsCreating(false)
}
}

const handleCancel = () => {
setFolderName('')
setShowFolderDialog(false)
}

return (
<>
<Popover open={isOpen} onOpenChange={setIsOpen}>
Expand Down Expand Up @@ -221,11 +220,15 @@ export function CreateMenu({
</button>

<button
className='flex w-full cursor-pointer items-center gap-2 rounded-md px-3 py-2 font-[380] text-card-foreground text-sm outline-none hover:bg-secondary/50 focus:bg-secondary/50'
className={cn(
'flex w-full cursor-pointer items-center gap-2 rounded-md px-3 py-2 font-[380] text-card-foreground text-sm outline-none hover:bg-secondary/50 focus:bg-secondary/50',
isCreating && 'cursor-not-allowed opacity-50'
)}
onClick={handleCreateFolder}
disabled={isCreating}
>
<Folder className='h-4 w-4' />
New folder
{isCreating ? 'Creating...' : 'New folder'}
</button>

{userPermissions.canEdit && (
Expand All @@ -246,36 +249,6 @@ export function CreateMenu({
disabled={!userPermissions.canEdit}
onClose={() => setIsOpen(false)}
/>

{/* Folder creation dialog */}
<Dialog open={showFolderDialog} onOpenChange={setShowFolderDialog}>
<DialogContent className='sm:max-w-[425px]'>
<DialogHeader>
<DialogTitle>Create New Folder</DialogTitle>
</DialogHeader>
<form onSubmit={handleFolderSubmit} className='space-y-4'>
<div className='space-y-2'>
<Label htmlFor='folder-name'>Folder Name</Label>
<Input
id='folder-name'
value={folderName}
onChange={(e) => setFolderName(e.target.value)}
placeholder='Enter folder name...'
autoFocus
required
/>
</div>
<div className='flex justify-end space-x-2'>
<Button type='button' variant='outline' onClick={handleCancel}>
Cancel
</Button>
<Button type='submit' disabled={!folderName.trim() || isCreating}>
{isCreating ? 'Creating...' : 'Create Folder'}
</Button>
</div>
</form>
</DialogContent>
</Dialog>
</>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,15 @@ import { useState } from 'react'
import { File, Folder, MoreHorizontal, Pencil, Trash2 } from 'lucide-react'
import { useParams } from 'next/navigation'
import { Button } from '@/components/ui/button'
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
import { createLogger } from '@/lib/logs/console-logger'
import { generateSubfolderName } from '@/lib/naming'
import { useUserPermissionsContext } from '@/app/workspace/[workspaceId]/w/components/providers/workspace-permissions-provider'
import { useFolderStore } from '@/stores/folders/store'

Expand All @@ -37,23 +35,53 @@ export function FolderContextMenu({
onStartEdit,
level,
}: FolderContextMenuProps) {
const [showSubfolderDialog, setShowSubfolderDialog] = useState(false)
const [subfolderName, setSubfolderName] = useState('')
const [isCreating, setIsCreating] = useState(false)
const params = useParams()
const workspaceId = params.workspaceId as string

// Get user permissions for the workspace
const userPermissions = useUserPermissionsContext()

const { createFolder, deleteFolder } = useFolderStore()
const { createFolder, deleteFolder, setExpanded } = useFolderStore()

const handleCreateWorkflow = () => {
// Ensure folder is expanded so user can see the new workflow
setExpanded(folderId, true)
onCreateWorkflow(folderId)
}

const handleCreateSubfolder = () => {
setShowSubfolderDialog(true)
const handleCreateSubfolder = async () => {
if (isCreating) {
logger.info('Subfolder creation already in progress, ignoring request')
return
}

if (!workspaceId) {
logger.error('No workspaceId available for subfolder creation')
return
}

try {
setIsCreating(true)

// Ensure parent folder is expanded so user can see the new subfolder
setExpanded(folderId, true)

// Generate subfolder name using fresh data from API
const subfolderName = await generateSubfolderName(workspaceId, folderId)

await createFolder({
name: subfolderName,
workspaceId: workspaceId,
parentId: folderId,
})

logger.info(`Created subfolder: ${subfolderName}`)
} catch (error) {
logger.error('Failed to create subfolder:', { error })
} finally {
setIsCreating(false)
}
}

const handleRename = () => {
Expand All @@ -76,31 +104,6 @@ export function FolderContextMenu({
}
}

const handleSubfolderSubmit = async (e: React.FormEvent) => {
e.preventDefault()
if (!subfolderName.trim() || !workspaceId) return

setIsCreating(true)
try {
await createFolder({
name: subfolderName.trim(),
workspaceId: workspaceId,
parentId: folderId,
})
setSubfolderName('')
setShowSubfolderDialog(false)
} catch (error) {
logger.error('Failed to create subfolder:', { error })
} finally {
setIsCreating(false)
}
}

const handleCancel = () => {
setSubfolderName('')
setShowSubfolderDialog(false)
}

return (
<>
<DropdownMenu>
Expand Down Expand Up @@ -175,37 +178,6 @@ export function FolderContextMenu({
)}
</DropdownMenuContent>
</DropdownMenu>

{/* Subfolder creation dialog */}
<Dialog open={showSubfolderDialog} onOpenChange={setShowSubfolderDialog}>
<DialogContent className='sm:max-w-[425px]' onClick={(e) => e.stopPropagation()}>
<DialogHeader>
<DialogTitle>Create New Subfolder</DialogTitle>
</DialogHeader>
<form onSubmit={handleSubfolderSubmit} className='space-y-4'>
<div className='space-y-2'>
<Label htmlFor='subfolder-name'>Folder Name</Label>
<Input
id='subfolder-name'
value={subfolderName}
onChange={(e) => setSubfolderName(e.target.value)}
placeholder='Enter folder name...'
maxLength={50}
autoFocus
required
/>
</div>
<div className='flex justify-end space-x-2'>
<Button type='button' variant='outline' onClick={handleCancel}>
Cancel
</Button>
<Button type='submit' disabled={!subfolderName.trim() || isCreating}>
{isCreating ? 'Creating...' : 'Create Folder'}
</Button>
</div>
</form>
</DialogContent>
</Dialog>
</>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ export function FolderItem({
onChange={(e) => setEditValue(e.target.value)}
onKeyDown={handleKeyDown}
onBlur={handleInputBlur}
className='flex-1 border-0 bg-transparent p-0 text-muted-foreground text-sm outline-none focus:outline-none focus:ring-0 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0'
className='min-w-0 flex-1 border-0 bg-transparent p-0 text-muted-foreground text-sm outline-none focus:outline-none focus:ring-0 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0'
maxLength={50}
disabled={isRenaming}
onClick={(e) => e.stopPropagation()} // Prevent folder toggle when clicking input
Expand All @@ -314,7 +314,9 @@ export function FolderItem({
spellCheck='false'
/>
) : (
<span className='flex-1 select-none truncate text-muted-foreground'>{folder.name}</span>
<span className='min-w-0 flex-1 select-none truncate text-muted-foreground'>
{folder.name}
</span>
)}

{!isEditing && (
Expand Down
Loading