diff --git a/apps/sim/.env.example b/apps/sim/.env.example
new file mode 100644
index 00000000000..738e9760366
--- /dev/null
+++ b/apps/sim/.env.example
@@ -0,0 +1,19 @@
+# Database (Required)
+DATABASE_URL="postgresql://postgres:password@localhost:5432/postgres"
+
+# Authentication (Required)
+BETTER_AUTH_SECRET=your_secret_key # Use `openssl rand -hex 32` to generate, or visit https://www.better-auth.com/docs/installation
+BETTER_AUTH_URL=http://localhost:3000
+
+# NextJS (Required)
+NEXT_PUBLIC_APP_URL=http://localhost:3000
+
+# Security (Required)
+ENCRYPTION_KEY=your_encryption_key # Use `openssl rand -hex 32` to generate
+
+# Email Provider (Optional)
+# RESEND_API_KEY= # Uncomment and add your key from https://resend.com to send actual emails
+ # If left commented out, emails will be logged to console instead
+
+# Freestyle API Key (Required for sandboxed code execution for functions/custom-tools)
+# FREESTYLE_API_KEY= # Uncomment and add your key from https://docs.freestyle.sh/Getting-Started/run
diff --git a/apps/sim/app/(auth)/components/social-login-buttons.tsx b/apps/sim/app/(auth)/components/social-login-buttons.tsx
index 29fb289076f..09157d7de1e 100644
--- a/apps/sim/app/(auth)/components/social-login-buttons.tsx
+++ b/apps/sim/app/(auth)/components/social-login-buttons.tsx
@@ -17,7 +17,7 @@ interface SocialLoginButtonsProps {
export function SocialLoginButtons({
githubAvailable,
googleAvailable,
- callbackURL = '/w',
+ callbackURL = '/workspace',
isProduction,
}: SocialLoginButtonsProps) {
const [isGithubLoading, setIsGithubLoading] = useState(false)
diff --git a/apps/sim/app/(auth)/layout.tsx b/apps/sim/app/(auth)/layout.tsx
index 6a81c5ba228..d448a4eae24 100644
--- a/apps/sim/app/(auth)/layout.tsx
+++ b/apps/sim/app/(auth)/layout.tsx
@@ -3,7 +3,7 @@
import Image from 'next/image'
import Link from 'next/link'
import { GridPattern } from '../(landing)/components/grid-pattern'
-import { NotificationList } from '../w/[id]/components/notifications/notifications'
+import { NotificationList } from '../workspace/[workspaceId]/w/[workflowId]/components/notifications/notifications'
export default function AuthLayout({ children }: { children: React.ReactNode }) {
return (
diff --git a/apps/sim/app/(auth)/login/login-form.test.tsx b/apps/sim/app/(auth)/login/login-form.test.tsx
index 00bf49df227..a40edfd88fc 100644
--- a/apps/sim/app/(auth)/login/login-form.test.tsx
+++ b/apps/sim/app/(auth)/login/login-form.test.tsx
@@ -149,7 +149,7 @@ describe('LoginPage', () => {
{
email: 'test@example.com',
password: 'password123',
- callbackURL: '/w',
+ callbackURL: '/workspace',
},
expect.objectContaining({
onError: expect.any(Function),
diff --git a/apps/sim/app/(auth)/login/login-form.tsx b/apps/sim/app/(auth)/login/login-form.tsx
index 566aa18cd01..88b9e5af624 100644
--- a/apps/sim/app/(auth)/login/login-form.tsx
+++ b/apps/sim/app/(auth)/login/login-form.tsx
@@ -125,7 +125,7 @@ export default function LoginPage({
const [showValidationError, setShowValidationError] = useState(false)
// Initialize state for URL parameters
- const [callbackUrl, setCallbackUrl] = useState('/w')
+ const [callbackUrl, setCallbackUrl] = useState('/workspace')
const [isInviteFlow, setIsInviteFlow] = useState(false)
// Forgot password states
@@ -155,7 +155,7 @@ export default function LoginPage({
setCallbackUrl(callback)
} else {
logger.warn('Invalid callback URL detected and blocked:', { url: callback })
- // Keep the default safe value ('/w')
+ // Keep the default safe value ('/workspace')
}
}
@@ -222,7 +222,7 @@ export default function LoginPage({
try {
// Final validation before submission
- const safeCallbackUrl = validateCallbackUrl(callbackUrl) ? callbackUrl : '/w'
+ const safeCallbackUrl = validateCallbackUrl(callbackUrl) ? callbackUrl : '/workspace'
const result = await client.signIn.email(
{
diff --git a/apps/sim/app/(auth)/signup/signup-form.tsx b/apps/sim/app/(auth)/signup/signup-form.tsx
index c061c6ba030..8b5e88dc813 100644
--- a/apps/sim/app/(auth)/signup/signup-form.tsx
+++ b/apps/sim/app/(auth)/signup/signup-form.tsx
@@ -410,7 +410,7 @@ function SignupFormContent({
diff --git a/apps/sim/app/(auth)/verify/use-verification.ts b/apps/sim/app/(auth)/verify/use-verification.ts
index 933352d4907..b800cbd5782 100644
--- a/apps/sim/app/(auth)/verify/use-verification.ts
+++ b/apps/sim/app/(auth)/verify/use-verification.ts
@@ -148,7 +148,7 @@ export function useVerification({
router.push(redirectUrl)
} else {
// Default redirect to dashboard
- router.push('/w')
+ router.push('/workspace')
}
}, 2000)
} else {
@@ -233,7 +233,7 @@ export function useVerification({
if (isDevOrDocker || !hasResendKey) {
setIsVerified(true)
const timeoutId = setTimeout(() => {
- router.push('/w')
+ router.push('/workspace')
}, 1000)
return () => clearTimeout(timeoutId)
diff --git a/apps/sim/app/(landing)/components/sections/footer.tsx b/apps/sim/app/(landing)/components/sections/footer.tsx
index d0fdbf8c1b4..0a957c6011f 100644
--- a/apps/sim/app/(landing)/components/sections/footer.tsx
+++ b/apps/sim/app/(landing)/components/sections/footer.tsx
@@ -21,7 +21,7 @@ function Footer() {
if (typeof window !== 'undefined') {
// Check if user has an active session
if (isAuthenticated) {
- router.push('/w')
+ router.push('/workspace')
} else {
// Check if user has logged in before
const hasLoggedInBefore =
diff --git a/apps/sim/app/(landing)/components/sections/hero.tsx b/apps/sim/app/(landing)/components/sections/hero.tsx
index a3823a7cc0c..e822888b7c2 100644
--- a/apps/sim/app/(landing)/components/sections/hero.tsx
+++ b/apps/sim/app/(landing)/components/sections/hero.tsx
@@ -18,7 +18,7 @@ function Hero() {
if (typeof window !== 'undefined') {
// Check if user has an active session
if (isAuthenticated) {
- router.push('/w')
+ router.push('/workspace')
} else {
// Check if user has logged in before
const hasLoggedInBefore =
diff --git a/apps/sim/app/api/marketplace/workflows/route.ts b/apps/sim/app/api/marketplace/workflows/route.ts
index 40bc4fe1975..fdf7a3cdb81 100644
--- a/apps/sim/app/api/marketplace/workflows/route.ts
+++ b/apps/sim/app/api/marketplace/workflows/route.ts
@@ -2,7 +2,7 @@ import { desc, eq, sql } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { createLogger } from '@/lib/logs/console-logger'
import { createErrorResponse, createSuccessResponse } from '@/app/api/workflows/utils'
-import { CATEGORIES } from '@/app/w/marketplace/constants/categories'
+import { CATEGORIES } from '@/app/workspace/[workspaceId]/marketplace/constants/categories'
import { db } from '@/db'
import * as schema from '@/db/schema'
diff --git a/apps/sim/app/api/workspaces/invitations/accept/route.ts b/apps/sim/app/api/workspaces/invitations/accept/route.ts
index 2b30618005a..560b36f68e7 100644
--- a/apps/sim/app/api/workspaces/invitations/accept/route.ts
+++ b/apps/sim/app/api/workspaces/invitations/accept/route.ts
@@ -149,7 +149,10 @@ export async function GET(req: NextRequest) {
.where(eq(workspaceInvitation.id, invitation.id))
return NextResponse.redirect(
- new URL(`/w/${invitation.workspaceId}`, env.NEXT_PUBLIC_APP_URL || 'https://simstudio.ai')
+ new URL(
+ `/workspace/${invitation.workspaceId}/w`,
+ env.NEXT_PUBLIC_APP_URL || 'https://simstudio.ai'
+ )
)
}
@@ -194,7 +197,10 @@ export async function GET(req: NextRequest) {
// Redirect to the workspace
return NextResponse.redirect(
- new URL(`/w/${invitation.workspaceId}`, env.NEXT_PUBLIC_APP_URL || 'https://simstudio.ai')
+ new URL(
+ `/workspace/${invitation.workspaceId}/w`,
+ env.NEXT_PUBLIC_APP_URL || 'https://simstudio.ai'
+ )
)
} catch (error) {
console.error('Error accepting invitation:', error)
diff --git a/apps/sim/app/invite/[id]/invite.tsx b/apps/sim/app/invite/[id]/invite.tsx
index 3cac00e554f..86b748b6866 100644
--- a/apps/sim/app/invite/[id]/invite.tsx
+++ b/apps/sim/app/invite/[id]/invite.tsx
@@ -131,7 +131,7 @@ export default function Invite() {
// Redirect to workspace after a brief delay
setTimeout(() => {
- router.push('/w')
+ router.push('/workspace')
}, 2000)
} else {
// For organization invites, use the client API
@@ -153,7 +153,7 @@ export default function Invite() {
// Redirect to workspace after a brief delay
setTimeout(() => {
- router.push('/w')
+ router.push('/workspace')
}, 2000)
}
} catch (err: any) {
diff --git a/apps/sim/app/invite/invite-error/invite-error.tsx b/apps/sim/app/invite/invite-error/invite-error.tsx
index 480a59d2ae8..064a70b9332 100644
--- a/apps/sim/app/invite/invite-error/invite-error.tsx
+++ b/apps/sim/app/invite/invite-error/invite-error.tsx
@@ -54,7 +54,7 @@ export default function InviteError() {
{displayMessage}
-
+
Go to Dashboard
diff --git a/apps/sim/app/w/error.tsx b/apps/sim/app/w/error.tsx
deleted file mode 100644
index adac0456b81..00000000000
--- a/apps/sim/app/w/error.tsx
+++ /dev/null
@@ -1,5 +0,0 @@
-'use client'
-
-import { NextError } from './[id]/components/error'
-
-export default NextError
diff --git a/apps/sim/app/w/global-error.tsx b/apps/sim/app/w/global-error.tsx
deleted file mode 100644
index 9c7bd975759..00000000000
--- a/apps/sim/app/w/global-error.tsx
+++ /dev/null
@@ -1,5 +0,0 @@
-'use client'
-
-import { NextGlobalError } from './[id]/components/error'
-
-export default NextGlobalError
diff --git a/apps/sim/app/workspace/[workspaceId]/error.tsx b/apps/sim/app/workspace/[workspaceId]/error.tsx
new file mode 100644
index 00000000000..c5e6e668b88
--- /dev/null
+++ b/apps/sim/app/workspace/[workspaceId]/error.tsx
@@ -0,0 +1,5 @@
+'use client'
+
+import { NextError } from './w/[workflowId]/components/error'
+
+export default NextError
diff --git a/apps/sim/app/workspace/[workspaceId]/global-error.tsx b/apps/sim/app/workspace/[workspaceId]/global-error.tsx
new file mode 100644
index 00000000000..d92a73ce254
--- /dev/null
+++ b/apps/sim/app/workspace/[workspaceId]/global-error.tsx
@@ -0,0 +1,5 @@
+'use client'
+
+import { NextGlobalError } from './w/[workflowId]/components/error'
+
+export default NextGlobalError
diff --git a/apps/sim/app/w/knowledge/[id]/[documentId]/components/create-chunk-modal/create-chunk-modal.tsx b/apps/sim/app/workspace/[workspaceId]/knowledge/[id]/[documentId]/components/create-chunk-modal/create-chunk-modal.tsx
similarity index 100%
rename from apps/sim/app/w/knowledge/[id]/[documentId]/components/create-chunk-modal/create-chunk-modal.tsx
rename to apps/sim/app/workspace/[workspaceId]/knowledge/[id]/[documentId]/components/create-chunk-modal/create-chunk-modal.tsx
diff --git a/apps/sim/app/w/knowledge/[id]/[documentId]/components/delete-chunk-modal/delete-chunk-modal.tsx b/apps/sim/app/workspace/[workspaceId]/knowledge/[id]/[documentId]/components/delete-chunk-modal/delete-chunk-modal.tsx
similarity index 100%
rename from apps/sim/app/w/knowledge/[id]/[documentId]/components/delete-chunk-modal/delete-chunk-modal.tsx
rename to apps/sim/app/workspace/[workspaceId]/knowledge/[id]/[documentId]/components/delete-chunk-modal/delete-chunk-modal.tsx
diff --git a/apps/sim/app/w/knowledge/[id]/[documentId]/components/document-loading.tsx b/apps/sim/app/workspace/[workspaceId]/knowledge/[id]/[documentId]/components/document-loading.tsx
similarity index 97%
rename from apps/sim/app/w/knowledge/[id]/[documentId]/components/document-loading.tsx
rename to apps/sim/app/workspace/[workspaceId]/knowledge/[id]/[documentId]/components/document-loading.tsx
index 2b9d811d733..aad70d0ed4f 100644
--- a/apps/sim/app/w/knowledge/[id]/[documentId]/components/document-loading.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/knowledge/[id]/[documentId]/components/document-loading.tsx
@@ -25,12 +25,12 @@ export function DocumentLoading({
{
id: 'knowledge-root',
label: 'Knowledge',
- href: '/w/knowledge',
+ href: '/knowledge',
},
{
id: `knowledge-base-${knowledgeBaseId}`,
label: knowledgeBaseName,
- href: `/w/knowledge/${knowledgeBaseId}`,
+ href: `/knowledge/${knowledgeBaseId}`,
},
{
id: `document-${knowledgeBaseId}-${documentName}`,
diff --git a/apps/sim/app/w/knowledge/[id]/[documentId]/components/edit-chunk-modal/edit-chunk-modal.tsx b/apps/sim/app/workspace/[workspaceId]/knowledge/[id]/[documentId]/components/edit-chunk-modal/edit-chunk-modal.tsx
similarity index 100%
rename from apps/sim/app/w/knowledge/[id]/[documentId]/components/edit-chunk-modal/edit-chunk-modal.tsx
rename to apps/sim/app/workspace/[workspaceId]/knowledge/[id]/[documentId]/components/edit-chunk-modal/edit-chunk-modal.tsx
diff --git a/apps/sim/app/w/knowledge/[id]/[documentId]/document.tsx b/apps/sim/app/workspace/[workspaceId]/knowledge/[id]/[documentId]/document.tsx
similarity index 99%
rename from apps/sim/app/w/knowledge/[id]/[documentId]/document.tsx
rename to apps/sim/app/workspace/[workspaceId]/knowledge/[id]/[documentId]/document.tsx
index 9758f46fa8e..fc25327f6db 100644
--- a/apps/sim/app/w/knowledge/[id]/[documentId]/document.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/knowledge/[id]/[documentId]/document.tsx
@@ -16,7 +16,7 @@ import { Button } from '@/components/ui/button'
import { Checkbox } from '@/components/ui/checkbox'
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
import { createLogger } from '@/lib/logs/console-logger'
-import { ActionBar } from '@/app/w/knowledge/[id]/components/action-bar/action-bar'
+import { ActionBar } from '@/app/workspace/[workspaceId]/knowledge/[id]/components/action-bar/action-bar'
import { useDocumentChunks } from '@/hooks/use-knowledge'
import { type ChunkData, type DocumentData, useKnowledgeStore } from '@/stores/knowledge/store'
import { useSidebarStore } from '@/stores/sidebar/store'
@@ -170,10 +170,10 @@ export function Document({
const effectiveDocumentName = document?.filename || documentName || 'Document'
const breadcrumbs = [
- { label: 'Knowledge', href: '/w/knowledge' },
+ { label: 'Knowledge', href: '/knowledge' },
{
label: effectiveKnowledgeBaseName,
- href: `/w/knowledge/${knowledgeBaseId}`,
+ href: `/knowledge/${knowledgeBaseId}`,
},
{ label: effectiveDocumentName },
]
@@ -360,10 +360,10 @@ export function Document({
if (combinedError && !isLoadingChunks) {
const errorBreadcrumbs = [
- { label: 'Knowledge', href: '/w/knowledge' },
+ { label: 'Knowledge', href: '/knowledge' },
{
label: effectiveKnowledgeBaseName,
- href: `/w/knowledge/${knowledgeBaseId}`,
+ href: `/knowledge/${knowledgeBaseId}`,
},
{ label: 'Error' },
]
diff --git a/apps/sim/app/w/knowledge/[id]/[documentId]/page.tsx b/apps/sim/app/workspace/[workspaceId]/knowledge/[id]/[documentId]/page.tsx
similarity index 100%
rename from apps/sim/app/w/knowledge/[id]/[documentId]/page.tsx
rename to apps/sim/app/workspace/[workspaceId]/knowledge/[id]/[documentId]/page.tsx
diff --git a/apps/sim/app/w/knowledge/[id]/base.tsx b/apps/sim/app/workspace/[workspaceId]/knowledge/[id]/base.tsx
similarity index 98%
rename from apps/sim/app/w/knowledge/[id]/base.tsx
rename to apps/sim/app/workspace/[workspaceId]/knowledge/[id]/base.tsx
index 2b7ab83d394..eeffdb79e7d 100644
--- a/apps/sim/app/w/knowledge/[id]/base.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/knowledge/[id]/base.tsx
@@ -13,7 +13,7 @@ import {
Trash2,
X,
} from 'lucide-react'
-import { useRouter } from 'next/navigation'
+import { useParams, useRouter } from 'next/navigation'
import {
AlertDialog,
AlertDialogAction,
@@ -28,10 +28,10 @@ import { Button } from '@/components/ui/button'
import { Checkbox } from '@/components/ui/checkbox'
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
import { createLogger } from '@/lib/logs/console-logger'
-import { ActionBar } from '@/app/w/knowledge/[id]/components/action-bar/action-bar'
-import { getDocumentIcon } from '@/app/w/knowledge/components/icons/document-icons'
-import { PrimaryButton } from '@/app/w/knowledge/components/primary-button/primary-button'
-import { SearchInput } from '@/app/w/knowledge/components/search-input/search-input'
+import { ActionBar } from '@/app/workspace/[workspaceId]/knowledge/[id]/components/action-bar/action-bar'
+import { getDocumentIcon } from '@/app/workspace/[workspaceId]/knowledge/components/icons/document-icons'
+import { PrimaryButton } from '@/app/workspace/[workspaceId]/knowledge/components/primary-button/primary-button'
+import { SearchInput } from '@/app/workspace/[workspaceId]/knowledge/components/search-input/search-input'
import { useKnowledgeBase, useKnowledgeBaseDocuments } from '@/hooks/use-knowledge'
import { type DocumentData, useKnowledgeStore } from '@/stores/knowledge/store'
import { useSidebarStore } from '@/stores/sidebar/store'
@@ -122,6 +122,8 @@ export function KnowledgeBase({
}: KnowledgeBaseProps) {
const { mode, isExpanded } = useSidebarStore()
const { removeKnowledgeBase } = useKnowledgeStore()
+ const params = useParams()
+ const workspaceId = params.workspaceId as string
const {
knowledgeBase,
isLoading: isLoadingKnowledgeBase,
@@ -402,11 +404,11 @@ export function KnowledgeBase({
const handleDocumentClick = (docId: string) => {
// Find the document to get its filename
const document = documents.find((doc) => doc.id === docId)
- const params = new URLSearchParams({
+ const urlParams = new URLSearchParams({
kbName: knowledgeBaseName, // Use the instantly available name
docName: document?.filename || 'Document',
})
- router.push(`/w/knowledge/${id}/${docId}?${params.toString()}`)
+ router.push(`/workspace/${workspaceId}/knowledge/${id}/${docId}?${urlParams.toString()}`)
}
const handleDeleteKnowledgeBase = async () => {
@@ -428,7 +430,7 @@ export function KnowledgeBase({
if (result.success) {
// Remove from store and redirect to knowledge bases list
removeKnowledgeBase(id)
- router.push('/w/knowledge')
+ router.push(`/workspace/${workspaceId}/knowledge`)
} else {
throw new Error(result.error || 'Failed to delete knowledge base')
}
@@ -741,7 +743,7 @@ export function KnowledgeBase({
{
id: 'knowledge-root',
label: 'Knowledge',
- href: '/w/knowledge',
+ href: '/knowledge',
},
{
id: `knowledge-base-${id}`,
@@ -760,7 +762,7 @@ export function KnowledgeBase({
{
id: 'knowledge-root',
label: 'Knowledge',
- href: '/w/knowledge',
+ href: '/knowledge',
},
{
id: 'error',
diff --git a/apps/sim/app/w/knowledge/[id]/components/action-bar/action-bar.tsx b/apps/sim/app/workspace/[workspaceId]/knowledge/[id]/components/action-bar/action-bar.tsx
similarity index 100%
rename from apps/sim/app/w/knowledge/[id]/components/action-bar/action-bar.tsx
rename to apps/sim/app/workspace/[workspaceId]/knowledge/[id]/components/action-bar/action-bar.tsx
diff --git a/apps/sim/app/w/knowledge/[id]/components/knowledge-base-loading/knowledge-base-loading.tsx b/apps/sim/app/workspace/[workspaceId]/knowledge/[id]/components/knowledge-base-loading/knowledge-base-loading.tsx
similarity index 99%
rename from apps/sim/app/w/knowledge/[id]/components/knowledge-base-loading/knowledge-base-loading.tsx
rename to apps/sim/app/workspace/[workspaceId]/knowledge/[id]/components/knowledge-base-loading/knowledge-base-loading.tsx
index f969e7ae7f2..150979ddb66 100644
--- a/apps/sim/app/w/knowledge/[id]/components/knowledge-base-loading/knowledge-base-loading.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/knowledge/[id]/components/knowledge-base-loading/knowledge-base-loading.tsx
@@ -19,7 +19,7 @@ export function KnowledgeBaseLoading({ knowledgeBaseName }: KnowledgeBaseLoading
{
id: 'knowledge-root',
label: 'Knowledge',
- href: '/w/knowledge',
+ href: '/knowledge',
},
{
id: 'knowledge-base-loading',
diff --git a/apps/sim/app/w/knowledge/[id]/page.tsx b/apps/sim/app/workspace/[workspaceId]/knowledge/[id]/page.tsx
similarity index 100%
rename from apps/sim/app/w/knowledge/[id]/page.tsx
rename to apps/sim/app/workspace/[workspaceId]/knowledge/[id]/page.tsx
diff --git a/apps/sim/app/w/knowledge/components/base-overview/base-overview.tsx b/apps/sim/app/workspace/[workspaceId]/knowledge/components/base-overview/base-overview.tsx
similarity index 95%
rename from apps/sim/app/w/knowledge/components/base-overview/base-overview.tsx
rename to apps/sim/app/workspace/[workspaceId]/knowledge/components/base-overview/base-overview.tsx
index 4da5fdd9ab7..223c9e9c90f 100644
--- a/apps/sim/app/w/knowledge/components/base-overview/base-overview.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/knowledge/components/base-overview/base-overview.tsx
@@ -18,7 +18,7 @@ export function BaseOverview({ id, title, docCount, description }: BaseOverviewP
const params = new URLSearchParams({
kbName: title,
})
- const href = `/w/knowledge/${id || title.toLowerCase().replace(/\s+/g, '-')}?${params.toString()}`
+ const href = `/knowledge/${id || title.toLowerCase().replace(/\s+/g, '-')}?${params.toString()}`
const handleCopy = async (e: React.MouseEvent) => {
e.preventDefault()
diff --git a/apps/sim/app/w/knowledge/components/create-modal/create-modal.tsx b/apps/sim/app/workspace/[workspaceId]/knowledge/components/create-modal/create-modal.tsx
similarity index 99%
rename from apps/sim/app/w/knowledge/components/create-modal/create-modal.tsx
rename to apps/sim/app/workspace/[workspaceId]/knowledge/components/create-modal/create-modal.tsx
index 5fbfd6effa2..77bf98e8fb8 100644
--- a/apps/sim/app/w/knowledge/components/create-modal/create-modal.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/knowledge/components/create-modal/create-modal.tsx
@@ -12,7 +12,7 @@ import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Textarea } from '@/components/ui/textarea'
import { createLogger } from '@/lib/logs/console-logger'
-import { getDocumentIcon } from '@/app/w/knowledge/components/icons/document-icons'
+import { getDocumentIcon } from '@/app/workspace/[workspaceId]/knowledge/components/icons/document-icons'
import type { DocumentData, KnowledgeBaseData } from '@/stores/knowledge/store'
import { useKnowledgeStore } from '@/stores/knowledge/store'
diff --git a/apps/sim/app/w/knowledge/components/empty-state-card/empty-state-card.tsx b/apps/sim/app/workspace/[workspaceId]/knowledge/components/empty-state-card/empty-state-card.tsx
similarity index 100%
rename from apps/sim/app/w/knowledge/components/empty-state-card/empty-state-card.tsx
rename to apps/sim/app/workspace/[workspaceId]/knowledge/components/empty-state-card/empty-state-card.tsx
diff --git a/apps/sim/app/w/knowledge/components/icons/document-icons.tsx b/apps/sim/app/workspace/[workspaceId]/knowledge/components/icons/document-icons.tsx
similarity index 100%
rename from apps/sim/app/w/knowledge/components/icons/document-icons.tsx
rename to apps/sim/app/workspace/[workspaceId]/knowledge/components/icons/document-icons.tsx
diff --git a/apps/sim/app/w/knowledge/components/knowledge-header/knowledge-header.tsx b/apps/sim/app/workspace/[workspaceId]/knowledge/components/knowledge-header/knowledge-header.tsx
similarity index 100%
rename from apps/sim/app/w/knowledge/components/knowledge-header/knowledge-header.tsx
rename to apps/sim/app/workspace/[workspaceId]/knowledge/components/knowledge-header/knowledge-header.tsx
diff --git a/apps/sim/app/w/knowledge/components/primary-button/primary-button.tsx b/apps/sim/app/workspace/[workspaceId]/knowledge/components/primary-button/primary-button.tsx
similarity index 100%
rename from apps/sim/app/w/knowledge/components/primary-button/primary-button.tsx
rename to apps/sim/app/workspace/[workspaceId]/knowledge/components/primary-button/primary-button.tsx
diff --git a/apps/sim/app/w/knowledge/components/search-input/search-input.tsx b/apps/sim/app/workspace/[workspaceId]/knowledge/components/search-input/search-input.tsx
similarity index 100%
rename from apps/sim/app/w/knowledge/components/search-input/search-input.tsx
rename to apps/sim/app/workspace/[workspaceId]/knowledge/components/search-input/search-input.tsx
diff --git a/apps/sim/app/w/knowledge/components/skeletons/knowledge-base-card-skeleton.tsx b/apps/sim/app/workspace/[workspaceId]/knowledge/components/skeletons/knowledge-base-card-skeleton.tsx
similarity index 100%
rename from apps/sim/app/w/knowledge/components/skeletons/knowledge-base-card-skeleton.tsx
rename to apps/sim/app/workspace/[workspaceId]/knowledge/components/skeletons/knowledge-base-card-skeleton.tsx
diff --git a/apps/sim/app/w/knowledge/components/skeletons/table-skeleton.tsx b/apps/sim/app/workspace/[workspaceId]/knowledge/components/skeletons/table-skeleton.tsx
similarity index 100%
rename from apps/sim/app/w/knowledge/components/skeletons/table-skeleton.tsx
rename to apps/sim/app/workspace/[workspaceId]/knowledge/components/skeletons/table-skeleton.tsx
diff --git a/apps/sim/app/w/knowledge/knowledge.tsx b/apps/sim/app/workspace/[workspaceId]/knowledge/knowledge.tsx
similarity index 100%
rename from apps/sim/app/w/knowledge/knowledge.tsx
rename to apps/sim/app/workspace/[workspaceId]/knowledge/knowledge.tsx
diff --git a/apps/sim/app/w/knowledge/loading.tsx b/apps/sim/app/workspace/[workspaceId]/knowledge/loading.tsx
similarity index 100%
rename from apps/sim/app/w/knowledge/loading.tsx
rename to apps/sim/app/workspace/[workspaceId]/knowledge/loading.tsx
diff --git a/apps/sim/app/w/knowledge/page.tsx b/apps/sim/app/workspace/[workspaceId]/knowledge/page.tsx
similarity index 100%
rename from apps/sim/app/w/knowledge/page.tsx
rename to apps/sim/app/workspace/[workspaceId]/knowledge/page.tsx
diff --git a/apps/sim/app/w/layout.tsx b/apps/sim/app/workspace/[workspaceId]/layout.tsx
similarity index 79%
rename from apps/sim/app/w/layout.tsx
rename to apps/sim/app/workspace/[workspaceId]/layout.tsx
index 42ac184a820..261b5d42224 100644
--- a/apps/sim/app/w/layout.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/layout.tsx
@@ -1,6 +1,6 @@
import { WorkspaceProvider } from '@/providers/workspace-provider'
-import Providers from './components/providers/providers'
-import { Sidebar } from './components/sidebar/sidebar'
+import Providers from './w/components/providers/providers'
+import { Sidebar } from './w/components/sidebar/sidebar'
export default function WorkspaceLayout({ children }: { children: React.ReactNode }) {
return (
diff --git a/apps/sim/app/w/logs/components/control-bar/control-bar.tsx b/apps/sim/app/workspace/[workspaceId]/logs/components/control-bar/control-bar.tsx
similarity index 100%
rename from apps/sim/app/w/logs/components/control-bar/control-bar.tsx
rename to apps/sim/app/workspace/[workspaceId]/logs/components/control-bar/control-bar.tsx
diff --git a/apps/sim/app/w/logs/components/filters/components/filter-section.tsx b/apps/sim/app/workspace/[workspaceId]/logs/components/filters/components/filter-section.tsx
similarity index 100%
rename from apps/sim/app/w/logs/components/filters/components/filter-section.tsx
rename to apps/sim/app/workspace/[workspaceId]/logs/components/filters/components/filter-section.tsx
diff --git a/apps/sim/app/w/logs/components/filters/components/folder.tsx b/apps/sim/app/workspace/[workspaceId]/logs/components/filters/components/folder.tsx
similarity index 93%
rename from apps/sim/app/w/logs/components/filters/components/folder.tsx
rename to apps/sim/app/workspace/[workspaceId]/logs/components/filters/components/folder.tsx
index 025e20a7193..bc7432758f7 100644
--- a/apps/sim/app/w/logs/components/filters/components/folder.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/logs/components/filters/components/folder.tsx
@@ -1,5 +1,6 @@
import { useEffect, useState } from 'react'
import { Check, ChevronDown, Folder } from 'lucide-react'
+import { useParams } from 'next/navigation'
import { Button } from '@/components/ui/button'
import {
DropdownMenu,
@@ -8,9 +9,8 @@ import {
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
-import { useFilterStore } from '@/app/w/logs/stores/store'
+import { useFilterStore } from '@/app/workspace/[workspaceId]/logs/stores/store'
import { useFolderStore } from '@/stores/folders/store'
-import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
interface FolderOption {
id: string
@@ -22,7 +22,8 @@ interface FolderOption {
export default function FolderFilter() {
const { folderIds, toggleFolderId, setFolderIds } = useFilterStore()
const { getFolderTree, getFolderPath, fetchFolders } = useFolderStore()
- const { activeWorkspaceId } = useWorkflowRegistry()
+ const params = useParams()
+ const workspaceId = params.workspaceId as string
const [folders, setFolders] = useState
([])
const [loading, setLoading] = useState(true)
@@ -31,9 +32,9 @@ export default function FolderFilter() {
const fetchFoldersData = async () => {
try {
setLoading(true)
- if (activeWorkspaceId) {
- await fetchFolders(activeWorkspaceId)
- const folderTree = getFolderTree(activeWorkspaceId)
+ if (workspaceId) {
+ await fetchFolders(workspaceId)
+ const folderTree = getFolderTree(workspaceId)
// Flatten the folder tree and create options with full paths
const flattenFolders = (nodes: any[], parentPath = ''): FolderOption[] => {
@@ -68,7 +69,7 @@ export default function FolderFilter() {
}
fetchFoldersData()
- }, [activeWorkspaceId, fetchFolders, getFolderTree])
+ }, [workspaceId, fetchFolders, getFolderTree])
// Get display text for the dropdown button
const getSelectedFoldersText = () => {
diff --git a/apps/sim/app/w/logs/components/filters/components/level.tsx b/apps/sim/app/workspace/[workspaceId]/logs/components/filters/components/level.tsx
similarity index 91%
rename from apps/sim/app/w/logs/components/filters/components/level.tsx
rename to apps/sim/app/workspace/[workspaceId]/logs/components/filters/components/level.tsx
index 78550907e93..c83706a5b40 100644
--- a/apps/sim/app/w/logs/components/filters/components/level.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/logs/components/filters/components/level.tsx
@@ -6,8 +6,8 @@ import {
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
-import { useFilterStore } from '@/app/w/logs/stores/store'
-import type { LogLevel } from '@/app/w/logs/stores/types'
+import { useFilterStore } from '@/app/workspace/[workspaceId]/logs/stores/store'
+import type { LogLevel } from '@/app/workspace/[workspaceId]/logs/stores/types'
export default function Level() {
const { level, setLevel } = useFilterStore()
diff --git a/apps/sim/app/w/logs/components/filters/components/timeline.tsx b/apps/sim/app/workspace/[workspaceId]/logs/components/filters/components/timeline.tsx
similarity index 88%
rename from apps/sim/app/w/logs/components/filters/components/timeline.tsx
rename to apps/sim/app/workspace/[workspaceId]/logs/components/filters/components/timeline.tsx
index 39ae02fb0d1..0a475b6f1dc 100644
--- a/apps/sim/app/w/logs/components/filters/components/timeline.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/logs/components/filters/components/timeline.tsx
@@ -6,8 +6,8 @@ import {
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
-import { useFilterStore } from '@/app/w/logs/stores/store'
-import type { TimeRange } from '@/app/w/logs/stores/types'
+import { useFilterStore } from '@/app/workspace/[workspaceId]/logs/stores/store'
+import type { TimeRange } from '@/app/workspace/[workspaceId]/logs/stores/types'
export default function Timeline() {
const { timeRange, setTimeRange } = useFilterStore()
diff --git a/apps/sim/app/w/logs/components/filters/components/trigger.tsx b/apps/sim/app/workspace/[workspaceId]/logs/components/filters/components/trigger.tsx
similarity index 97%
rename from apps/sim/app/w/logs/components/filters/components/trigger.tsx
rename to apps/sim/app/workspace/[workspaceId]/logs/components/filters/components/trigger.tsx
index 760649d35be..1cabe0583c9 100644
--- a/apps/sim/app/w/logs/components/filters/components/trigger.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/logs/components/filters/components/trigger.tsx
@@ -7,7 +7,7 @@ import {
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
-import { useFilterStore } from '@/app/w/logs/stores/store'
+import { useFilterStore } from '@/app/workspace/[workspaceId]/logs/stores/store'
import type { TriggerType } from '../../../stores/types'
export default function Trigger() {
diff --git a/apps/sim/app/w/logs/components/filters/components/workflow.tsx b/apps/sim/app/workspace/[workspaceId]/logs/components/filters/components/workflow.tsx
similarity index 97%
rename from apps/sim/app/w/logs/components/filters/components/workflow.tsx
rename to apps/sim/app/workspace/[workspaceId]/logs/components/filters/components/workflow.tsx
index d5f94b6de74..47081d31674 100644
--- a/apps/sim/app/w/logs/components/filters/components/workflow.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/logs/components/filters/components/workflow.tsx
@@ -8,7 +8,7 @@ import {
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
-import { useFilterStore } from '@/app/w/logs/stores/store'
+import { useFilterStore } from '@/app/workspace/[workspaceId]/logs/stores/store'
interface WorkflowOption {
id: string
diff --git a/apps/sim/app/w/logs/components/filters/filters.tsx b/apps/sim/app/workspace/[workspaceId]/logs/components/filters/filters.tsx
similarity index 100%
rename from apps/sim/app/w/logs/components/filters/filters.tsx
rename to apps/sim/app/workspace/[workspaceId]/logs/components/filters/filters.tsx
diff --git a/apps/sim/app/w/logs/components/sidebar/components/markdown-renderer.tsx b/apps/sim/app/workspace/[workspaceId]/logs/components/sidebar/components/markdown-renderer.tsx
similarity index 100%
rename from apps/sim/app/w/logs/components/sidebar/components/markdown-renderer.tsx
rename to apps/sim/app/workspace/[workspaceId]/logs/components/sidebar/components/markdown-renderer.tsx
diff --git a/apps/sim/app/w/logs/components/sidebar/sidebar.tsx b/apps/sim/app/workspace/[workspaceId]/logs/components/sidebar/sidebar.tsx
similarity index 99%
rename from apps/sim/app/w/logs/components/sidebar/sidebar.tsx
rename to apps/sim/app/workspace/[workspaceId]/logs/components/sidebar/sidebar.tsx
index a47131e42d5..65d070356b8 100644
--- a/apps/sim/app/w/logs/components/sidebar/sidebar.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/logs/components/sidebar/sidebar.tsx
@@ -7,8 +7,8 @@ import { CopyButton } from '@/components/ui/copy-button'
import { ScrollArea } from '@/components/ui/scroll-area'
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
import { redactApiKeys } from '@/lib/utils'
-import type { WorkflowLog } from '@/app/w/logs/stores/types'
-import { formatDate } from '@/app/w/logs/utils/format-date'
+import type { WorkflowLog } from '@/app/workspace/[workspaceId]/logs/stores/types'
+import { formatDate } from '@/app/workspace/[workspaceId]/logs/utils/format-date'
import { formatCost } from '@/providers/utils'
import { ToolCallsDisplay } from '../tool-calls/tool-calls-display'
import { TraceSpansDisplay } from '../trace-spans/trace-spans-display'
diff --git a/apps/sim/app/w/logs/components/tool-calls/tool-calls-display.tsx b/apps/sim/app/workspace/[workspaceId]/logs/components/tool-calls/tool-calls-display.tsx
similarity index 100%
rename from apps/sim/app/w/logs/components/tool-calls/tool-calls-display.tsx
rename to apps/sim/app/workspace/[workspaceId]/logs/components/tool-calls/tool-calls-display.tsx
diff --git a/apps/sim/app/w/logs/components/trace-spans/trace-spans-display.tsx b/apps/sim/app/workspace/[workspaceId]/logs/components/trace-spans/trace-spans-display.tsx
similarity index 100%
rename from apps/sim/app/w/logs/components/trace-spans/trace-spans-display.tsx
rename to apps/sim/app/workspace/[workspaceId]/logs/components/trace-spans/trace-spans-display.tsx
diff --git a/apps/sim/app/w/logs/logs.tsx b/apps/sim/app/workspace/[workspaceId]/logs/logs.tsx
similarity index 100%
rename from apps/sim/app/w/logs/logs.tsx
rename to apps/sim/app/workspace/[workspaceId]/logs/logs.tsx
diff --git a/apps/sim/app/w/logs/page.tsx b/apps/sim/app/workspace/[workspaceId]/logs/page.tsx
similarity index 100%
rename from apps/sim/app/w/logs/page.tsx
rename to apps/sim/app/workspace/[workspaceId]/logs/page.tsx
diff --git a/apps/sim/app/w/logs/stores/store.ts b/apps/sim/app/workspace/[workspaceId]/logs/stores/store.ts
similarity index 100%
rename from apps/sim/app/w/logs/stores/store.ts
rename to apps/sim/app/workspace/[workspaceId]/logs/stores/store.ts
diff --git a/apps/sim/app/w/logs/stores/types.ts b/apps/sim/app/workspace/[workspaceId]/logs/stores/types.ts
similarity index 100%
rename from apps/sim/app/w/logs/stores/types.ts
rename to apps/sim/app/workspace/[workspaceId]/logs/stores/types.ts
diff --git a/apps/sim/app/w/logs/utils/format-date.ts b/apps/sim/app/workspace/[workspaceId]/logs/utils/format-date.ts
similarity index 100%
rename from apps/sim/app/w/logs/utils/format-date.ts
rename to apps/sim/app/workspace/[workspaceId]/logs/utils/format-date.ts
diff --git a/apps/sim/app/w/marketplace/components/control-bar/control-bar.tsx b/apps/sim/app/workspace/[workspaceId]/marketplace/components/control-bar/control-bar.tsx
similarity index 100%
rename from apps/sim/app/w/marketplace/components/control-bar/control-bar.tsx
rename to apps/sim/app/workspace/[workspaceId]/marketplace/components/control-bar/control-bar.tsx
diff --git a/apps/sim/app/w/marketplace/components/error-message.tsx b/apps/sim/app/workspace/[workspaceId]/marketplace/components/error-message.tsx
similarity index 100%
rename from apps/sim/app/w/marketplace/components/error-message.tsx
rename to apps/sim/app/workspace/[workspaceId]/marketplace/components/error-message.tsx
diff --git a/apps/sim/app/w/marketplace/components/section.tsx b/apps/sim/app/workspace/[workspaceId]/marketplace/components/section.tsx
similarity index 100%
rename from apps/sim/app/w/marketplace/components/section.tsx
rename to apps/sim/app/workspace/[workspaceId]/marketplace/components/section.tsx
diff --git a/apps/sim/app/w/marketplace/components/toolbar/toolbar.tsx b/apps/sim/app/workspace/[workspaceId]/marketplace/components/toolbar/toolbar.tsx
similarity index 100%
rename from apps/sim/app/w/marketplace/components/toolbar/toolbar.tsx
rename to apps/sim/app/workspace/[workspaceId]/marketplace/components/toolbar/toolbar.tsx
diff --git a/apps/sim/app/w/marketplace/components/workflow-card-skeleton.tsx b/apps/sim/app/workspace/[workspaceId]/marketplace/components/workflow-card-skeleton.tsx
similarity index 100%
rename from apps/sim/app/w/marketplace/components/workflow-card-skeleton.tsx
rename to apps/sim/app/workspace/[workspaceId]/marketplace/components/workflow-card-skeleton.tsx
diff --git a/apps/sim/app/w/marketplace/components/workflow-card.tsx b/apps/sim/app/workspace/[workspaceId]/marketplace/components/workflow-card.tsx
similarity index 94%
rename from apps/sim/app/w/marketplace/components/workflow-card.tsx
rename to apps/sim/app/workspace/[workspaceId]/marketplace/components/workflow-card.tsx
index 82db83df0b7..76667b1d724 100644
--- a/apps/sim/app/w/marketplace/components/workflow-card.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/marketplace/components/workflow-card.tsx
@@ -2,9 +2,9 @@
import { useEffect, useState } from 'react'
import { Eye } from 'lucide-react'
-import { useRouter } from 'next/navigation'
+import { useParams, useRouter } from 'next/navigation'
import { Card, CardContent, CardFooter, CardHeader } from '@/components/ui/card'
-import { WorkflowPreview } from '@/app/w/components/workflow-preview/workflow-preview'
+import { WorkflowPreview } from '@/app/workspace/[workspaceId]/w/components/workflow-preview/workflow-preview'
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
import type { Workflow } from '../marketplace'
@@ -28,6 +28,8 @@ interface WorkflowCardProps {
export function WorkflowCard({ workflow, onHover }: WorkflowCardProps) {
const [isPreviewReady, setIsPreviewReady] = useState(!!workflow.workflowState)
const router = useRouter()
+ const params = useParams()
+ const workspaceId = params.workspaceId as string
const { createWorkflow } = useWorkflowRegistry()
// When workflow state becomes available, update preview ready state
@@ -71,7 +73,7 @@ export function WorkflowCard({ workflow, onHover }: WorkflowCardProps) {
})
// Navigate to the new workflow
- router.push(`/w/${newWorkflowId}`)
+ router.push(`/workspace/${workspaceId}/w/${newWorkflowId}`)
} else {
console.error('Cannot import workflow: state is not available')
}
diff --git a/apps/sim/app/w/marketplace/constants/categories.tsx b/apps/sim/app/workspace/[workspaceId]/marketplace/constants/categories.tsx
similarity index 100%
rename from apps/sim/app/w/marketplace/constants/categories.tsx
rename to apps/sim/app/workspace/[workspaceId]/marketplace/constants/categories.tsx
diff --git a/apps/sim/app/w/marketplace/marketplace.tsx b/apps/sim/app/workspace/[workspaceId]/marketplace/marketplace.tsx
similarity index 100%
rename from apps/sim/app/w/marketplace/marketplace.tsx
rename to apps/sim/app/workspace/[workspaceId]/marketplace/marketplace.tsx
diff --git a/apps/sim/app/w/marketplace/page.tsx b/apps/sim/app/workspace/[workspaceId]/marketplace/page.tsx
similarity index 100%
rename from apps/sim/app/w/marketplace/page.tsx
rename to apps/sim/app/workspace/[workspaceId]/marketplace/page.tsx
diff --git a/apps/sim/app/workspace/[workspaceId]/page.tsx b/apps/sim/app/workspace/[workspaceId]/page.tsx
new file mode 100644
index 00000000000..bd93acadf88
--- /dev/null
+++ b/apps/sim/app/workspace/[workspaceId]/page.tsx
@@ -0,0 +1,10 @@
+import { redirect } from 'next/navigation'
+
+export default async function WorkspacePage({
+ params,
+}: {
+ params: Promise<{ workspaceId: string }>
+}) {
+ const { workspaceId } = await params
+ redirect(`/workspace/${workspaceId}/w`)
+}
diff --git a/apps/sim/app/w/[id]/components/code-prompt-bar/code-prompt-bar.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/code-prompt-bar/code-prompt-bar.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/code-prompt-bar/code-prompt-bar.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/code-prompt-bar/code-prompt-bar.tsx
diff --git a/apps/sim/app/w/[id]/components/control-bar/components/deploy-modal/components/chat-deploy/chat-deploy.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/chat-deploy/chat-deploy.tsx
similarity index 99%
rename from apps/sim/app/w/[id]/components/control-bar/components/deploy-modal/components/chat-deploy/chat-deploy.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/chat-deploy/chat-deploy.tsx
index ef4b60ed270..f680c2ffa99 100644
--- a/apps/sim/app/w/[id]/components/control-bar/components/deploy-modal/components/chat-deploy/chat-deploy.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/chat-deploy/chat-deploy.tsx
@@ -33,7 +33,7 @@ import { Textarea } from '@/components/ui/textarea'
import { createLogger } from '@/lib/logs/console-logger'
import { getBaseDomain } from '@/lib/urls/utils'
import { cn } from '@/lib/utils'
-import { OutputSelect } from '@/app/w/[id]/components/panel/components/chat/components/output-select/output-select'
+import { OutputSelect } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/chat/components/output-select/output-select'
import { useNotificationStore } from '@/stores/notifications/store'
import type { OutputConfig } from '@/stores/panel/chat/types'
diff --git a/apps/sim/app/w/[id]/components/control-bar/components/deploy-modal/components/deploy-form/deploy-form.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/deploy-form/deploy-form.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/control-bar/components/deploy-modal/components/deploy-form/deploy-form.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/deploy-form/deploy-form.tsx
diff --git a/apps/sim/app/w/[id]/components/control-bar/components/deploy-modal/components/deployment-info/components/api-endpoint/api-endpoint.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/deployment-info/components/api-endpoint/api-endpoint.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/control-bar/components/deploy-modal/components/deployment-info/components/api-endpoint/api-endpoint.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/deployment-info/components/api-endpoint/api-endpoint.tsx
diff --git a/apps/sim/app/w/[id]/components/control-bar/components/deploy-modal/components/deployment-info/components/api-key/api-key.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/deployment-info/components/api-key/api-key.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/control-bar/components/deploy-modal/components/deployment-info/components/api-key/api-key.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/deployment-info/components/api-key/api-key.tsx
diff --git a/apps/sim/app/w/[id]/components/control-bar/components/deploy-modal/components/deployment-info/components/deploy-status/deploy-status.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/deployment-info/components/deploy-status/deploy-status.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/control-bar/components/deploy-modal/components/deployment-info/components/deploy-status/deploy-status.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/deployment-info/components/deploy-status/deploy-status.tsx
diff --git a/apps/sim/app/w/[id]/components/control-bar/components/deploy-modal/components/deployment-info/components/example-command/example-command.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/deployment-info/components/example-command/example-command.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/control-bar/components/deploy-modal/components/deployment-info/components/example-command/example-command.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/deployment-info/components/example-command/example-command.tsx
diff --git a/apps/sim/app/w/[id]/components/control-bar/components/deploy-modal/components/deployment-info/deployment-info.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/deployment-info/deployment-info.tsx
similarity index 88%
rename from apps/sim/app/w/[id]/components/control-bar/components/deploy-modal/components/deployment-info/deployment-info.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/deployment-info/deployment-info.tsx
index f8a794b7fd1..5f98febf4ce 100644
--- a/apps/sim/app/w/[id]/components/control-bar/components/deploy-modal/components/deployment-info/deployment-info.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/deployment-info/deployment-info.tsx
@@ -15,10 +15,10 @@ import {
} from '@/components/ui/alert-dialog'
import { Button } from '@/components/ui/button'
import { Skeleton } from '@/components/ui/skeleton'
-import { ApiEndpoint } from '@/app/w/[id]/components/control-bar/components/deploy-modal/components/deployment-info/components/api-endpoint/api-endpoint'
-import { ApiKey } from '@/app/w/[id]/components/control-bar/components/deploy-modal/components/deployment-info/components/api-key/api-key'
-import { DeployStatus } from '@/app/w/[id]/components/control-bar/components/deploy-modal/components/deployment-info/components/deploy-status/deploy-status'
-import { ExampleCommand } from '@/app/w/[id]/components/control-bar/components/deploy-modal/components/deployment-info/components/example-command/example-command'
+import { ApiEndpoint } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/deployment-info/components/api-endpoint/api-endpoint'
+import { ApiKey } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/deployment-info/components/api-key/api-key'
+import { DeployStatus } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/deployment-info/components/deploy-status/deploy-status'
+import { ExampleCommand } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/deployment-info/components/example-command/example-command'
import { useNotificationStore } from '@/stores/notifications/store'
import type { WorkflowState } from '@/stores/workflows/workflow/types'
import { DeployedWorkflowModal } from '../../../deployment-controls/components/deployed-workflow-modal'
diff --git a/apps/sim/app/w/[id]/components/control-bar/components/deploy-modal/deploy-modal.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/deploy-modal.tsx
similarity index 98%
rename from apps/sim/app/w/[id]/components/control-bar/components/deploy-modal/deploy-modal.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/deploy-modal.tsx
index af068534848..8595d333f88 100644
--- a/apps/sim/app/w/[id]/components/control-bar/components/deploy-modal/deploy-modal.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/deploy-modal.tsx
@@ -20,9 +20,9 @@ import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/u
import { env } from '@/lib/env'
import { createLogger } from '@/lib/logs/console-logger'
import { cn } from '@/lib/utils'
-import { ChatDeploy } from '@/app/w/[id]/components/control-bar/components/deploy-modal/components/chat-deploy/chat-deploy'
-import { DeployForm } from '@/app/w/[id]/components/control-bar/components/deploy-modal/components/deploy-form/deploy-form'
-import { DeploymentInfo } from '@/app/w/[id]/components/control-bar/components/deploy-modal/components/deployment-info/deployment-info'
+import { ChatDeploy } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/chat-deploy/chat-deploy'
+import { DeployForm } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/deploy-form/deploy-form'
+import { DeploymentInfo } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/deployment-info/deployment-info'
import { useNotificationStore } from '@/stores/notifications/store'
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
import { useSubBlockStore } from '@/stores/workflows/subblock/store'
diff --git a/apps/sim/app/w/[id]/components/control-bar/components/deployment-controls/components/deployed-workflow-card.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deployment-controls/components/deployed-workflow-card.tsx
similarity index 96%
rename from apps/sim/app/w/[id]/components/control-bar/components/deployment-controls/components/deployed-workflow-card.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deployment-controls/components/deployed-workflow-card.tsx
index 187c4fe10e9..500eac1ff38 100644
--- a/apps/sim/app/w/[id]/components/control-bar/components/deployment-controls/components/deployed-workflow-card.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deployment-controls/components/deployed-workflow-card.tsx
@@ -6,7 +6,7 @@ import { Label } from '@/components/ui/label'
import { Switch } from '@/components/ui/switch'
import { createLogger } from '@/lib/logs/console-logger'
import { cn } from '@/lib/utils'
-import { WorkflowPreview } from '@/app/w/components/workflow-preview/workflow-preview'
+import { WorkflowPreview } from '@/app/workspace/[workspaceId]/w/components/workflow-preview/workflow-preview'
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
import type { WorkflowState } from '@/stores/workflows/workflow/types'
diff --git a/apps/sim/app/w/[id]/components/control-bar/components/deployment-controls/components/deployed-workflow-modal.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deployment-controls/components/deployed-workflow-modal.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/control-bar/components/deployment-controls/components/deployed-workflow-modal.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deployment-controls/components/deployed-workflow-modal.tsx
diff --git a/apps/sim/app/w/[id]/components/control-bar/components/deployment-controls/deployment-controls.test.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deployment-controls/deployment-controls.test.ts
similarity index 100%
rename from apps/sim/app/w/[id]/components/control-bar/components/deployment-controls/deployment-controls.test.ts
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deployment-controls/deployment-controls.test.ts
diff --git a/apps/sim/app/w/[id]/components/control-bar/components/deployment-controls/deployment-controls.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deployment-controls/deployment-controls.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/control-bar/components/deployment-controls/deployment-controls.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deployment-controls/deployment-controls.tsx
diff --git a/apps/sim/app/w/[id]/components/control-bar/components/history-dropdown-item/history-dropdown-item.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/history-dropdown-item/history-dropdown-item.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/control-bar/components/history-dropdown-item/history-dropdown-item.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/history-dropdown-item/history-dropdown-item.tsx
diff --git a/apps/sim/app/w/[id]/components/control-bar/components/marketplace-modal/marketplace-modal.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/marketplace-modal/marketplace-modal.tsx
similarity index 99%
rename from apps/sim/app/w/[id]/components/control-bar/components/marketplace-modal/marketplace-modal.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/marketplace-modal/marketplace-modal.tsx
index 3d64dcc06f2..7b7bdb59687 100644
--- a/apps/sim/app/w/[id]/components/control-bar/components/marketplace-modal/marketplace-modal.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/marketplace-modal/marketplace-modal.tsx
@@ -35,7 +35,7 @@ import {
getCategoryColor,
getCategoryIcon,
getCategoryLabel,
-} from '@/app/w/marketplace/constants/categories'
+} from '@/app/workspace/[workspaceId]/marketplace/constants/categories'
import { useNotificationStore } from '@/stores/notifications/store'
import { getWorkflowWithValues } from '@/stores/workflows'
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
diff --git a/apps/sim/app/w/[id]/components/control-bar/components/notification-dropdown-item/notification-dropdown-item.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/notification-dropdown-item/notification-dropdown-item.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/control-bar/components/notification-dropdown-item/notification-dropdown-item.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/notification-dropdown-item/notification-dropdown-item.tsx
diff --git a/apps/sim/app/w/[id]/components/control-bar/components/user-avatar-stack/components/user-avatar/user-avatar.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/user-avatar-stack/components/user-avatar/user-avatar.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/control-bar/components/user-avatar-stack/components/user-avatar/user-avatar.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/user-avatar-stack/components/user-avatar/user-avatar.tsx
diff --git a/apps/sim/app/w/[id]/components/control-bar/components/user-avatar-stack/user-avatar-stack.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/user-avatar-stack/user-avatar-stack.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/control-bar/components/user-avatar-stack/user-avatar-stack.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/user-avatar-stack/user-avatar-stack.tsx
diff --git a/apps/sim/app/w/[id]/components/control-bar/control-bar.test.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/control-bar.test.ts
similarity index 100%
rename from apps/sim/app/w/[id]/components/control-bar/control-bar.test.ts
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/control-bar.test.ts
diff --git a/apps/sim/app/w/[id]/components/control-bar/control-bar.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/control-bar.tsx
similarity index 92%
rename from apps/sim/app/w/[id]/components/control-bar/control-bar.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/control-bar.tsx
index 5da2dc64df6..eb8fa54c308 100644
--- a/apps/sim/app/w/[id]/components/control-bar/control-bar.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/control-bar.tsx
@@ -16,7 +16,7 @@ import {
Trash2,
X,
} from 'lucide-react'
-import { useRouter } from 'next/navigation'
+import { useParams, useRouter } from 'next/navigation'
import {
AlertDialog,
AlertDialogAction,
@@ -40,8 +40,9 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip
import { useSession } from '@/lib/auth-client'
import { createLogger } from '@/lib/logs/console-logger'
import { cn } from '@/lib/utils'
-import { useUserPermissionsContext } from '@/app/w/components/providers/workspace-permissions-provider'
+import { useUserPermissionsContext } from '@/app/workspace/[workspaceId]/w/components/providers/workspace-permissions-provider'
import { useExecutionStore } from '@/stores/execution/store'
+import { useFolderStore } from '@/stores/folders/store'
import { useNotificationStore } from '@/stores/notifications/store'
import { usePanelStore } from '@/stores/panel/store'
import { useGeneralStore } from '@/stores/settings/general/store'
@@ -84,6 +85,8 @@ interface ControlBarProps {
export function ControlBar({ hasValidationErrors = false }: ControlBarProps) {
const router = useRouter()
const { data: session } = useSession()
+ const params = useParams()
+ const workspaceId = params.workspaceId as string
// Store hooks
const {
@@ -100,7 +103,6 @@ export function ControlBar({ hasValidationErrors = false }: ControlBarProps) {
workflows,
updateWorkflow,
activeWorkflowId,
- activeWorkspaceId,
removeWorkflow,
duplicateWorkflow,
setDeploymentStatus,
@@ -108,6 +110,7 @@ export function ControlBar({ hasValidationErrors = false }: ControlBarProps) {
} = useWorkflowRegistry()
const { isExecuting, handleRunWorkflow } = useWorkflowExecution()
const { setActiveTab } = usePanelStore()
+ const { getFolderTree, expandedFolders } = useFolderStore()
// Get current workflow and workspace ID for permissions
const currentWorkflow = activeWorkflowId ? workflows[activeWorkflowId] : null
@@ -399,33 +402,82 @@ export function ControlBar({ hasValidationErrors = false }: ControlBarProps) {
}
}
+ /**
+ * Get workflows in the exact order they appear in the sidebar
+ */
+ const getSidebarOrderedWorkflows = () => {
+ // Get and sort regular workflows by last modified (newest first)
+ const regularWorkflows = Object.values(workflows)
+ .filter((workflow) => workflow.workspaceId === workspaceId)
+ .filter((workflow) => workflow.marketplaceData?.status !== 'temp')
+ .sort((a, b) => {
+ const dateA =
+ a.lastModified instanceof Date
+ ? a.lastModified.getTime()
+ : new Date(a.lastModified).getTime()
+ const dateB =
+ b.lastModified instanceof Date
+ ? b.lastModified.getTime()
+ : new Date(b.lastModified).getTime()
+ return dateB - dateA
+ })
+
+ // Group workflows by folder
+ const workflowsByFolder = regularWorkflows.reduce(
+ (acc, workflow) => {
+ const folderId = workflow.folderId || 'root'
+ if (!acc[folderId]) acc[folderId] = []
+ acc[folderId].push(workflow)
+ return acc
+ },
+ {} as Record
+ )
+
+ const orderedWorkflows: typeof regularWorkflows = []
+
+ // Recursively collect workflows from expanded folders
+ const collectFromFolders = (folders: ReturnType) => {
+ folders.forEach((folder) => {
+ if (expandedFolders.has(folder.id)) {
+ orderedWorkflows.push(...(workflowsByFolder[folder.id] || []))
+ if (folder.children.length > 0) {
+ collectFromFolders(folder.children)
+ }
+ }
+ })
+ }
+
+ // Get workflows from expanded folders first, then root workflows
+ if (workspaceId) collectFromFolders(getFolderTree(workspaceId))
+ orderedWorkflows.push(...(workflowsByFolder.root || []))
+
+ return orderedWorkflows
+ }
+
/**
* Handle deleting the current workflow
*/
const handleDeleteWorkflow = () => {
if (!activeWorkflowId || !userPermissions.canEdit) return
- const workflowIds = Object.keys(workflows)
- const currentIndex = workflowIds.indexOf(activeWorkflowId)
+ const sidebarWorkflows = getSidebarOrderedWorkflows()
+ const currentIndex = sidebarWorkflows.findIndex((w) => w.id === activeWorkflowId)
- // Find the next workflow to navigate to
- let nextWorkflowId = null
- if (workflowIds.length > 1) {
- // Try next workflow, then previous, then any other
- if (currentIndex < workflowIds.length - 1) {
- nextWorkflowId = workflowIds[currentIndex + 1]
+ // Find next workflow: try next, then previous
+ let nextWorkflowId: string | null = null
+ if (sidebarWorkflows.length > 1) {
+ if (currentIndex < sidebarWorkflows.length - 1) {
+ nextWorkflowId = sidebarWorkflows[currentIndex + 1].id
} else if (currentIndex > 0) {
- nextWorkflowId = workflowIds[currentIndex - 1]
- } else {
- nextWorkflowId = workflowIds.find((id) => id !== activeWorkflowId) || null
+ nextWorkflowId = sidebarWorkflows[currentIndex - 1].id
}
}
- // Navigate to the next workflow or home
+ // Navigate to next workflow or workspace home
if (nextWorkflowId) {
- router.push(`/w/${nextWorkflowId}`)
+ router.push(`/workspace/${workspaceId}/w/${nextWorkflowId}`)
} else {
- router.push('/')
+ router.push(`/workspace/${workspaceId}`)
}
// Remove the workflow from the registry
@@ -573,8 +625,17 @@ export function ControlBar({ hasValidationErrors = false }: ControlBarProps) {
const handleDuplicateWorkflow = async () => {
if (!activeWorkflowId || !userPermissions.canEdit) return
- // Duplicate the workflow - no automatic navigation
- await duplicateWorkflow(activeWorkflowId)
+ try {
+ const newWorkflow = await duplicateWorkflow(activeWorkflowId)
+ if (newWorkflow) {
+ router.push(`/workspace/${workspaceId}/w/${newWorkflow}`)
+ } else {
+ addNotification('error', 'Failed to duplicate workflow', activeWorkflowId)
+ }
+ } catch (error) {
+ logger.error('Error duplicating workflow:', { error })
+ addNotification('error', 'Failed to duplicate workflow', activeWorkflowId)
+ }
}
/**
diff --git a/apps/sim/app/w/[id]/components/copilot/copilot.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/copilot/copilot.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/copilot/copilot.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/copilot/copilot.tsx
diff --git a/apps/sim/app/w/[id]/components/error/index.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/error/index.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/error/index.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/error/index.tsx
diff --git a/apps/sim/app/w/[id]/components/loop-node/components/loop-badges.test.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/loop-node/components/loop-badges.test.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/loop-node/components/loop-badges.test.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/loop-node/components/loop-badges.test.tsx
diff --git a/apps/sim/app/w/[id]/components/loop-node/components/loop-badges.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/loop-node/components/loop-badges.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/loop-node/components/loop-badges.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/loop-node/components/loop-badges.tsx
diff --git a/apps/sim/app/w/[id]/components/loop-node/loop-config.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/loop-node/loop-config.ts
similarity index 100%
rename from apps/sim/app/w/[id]/components/loop-node/loop-config.ts
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/loop-node/loop-config.ts
diff --git a/apps/sim/app/w/[id]/components/loop-node/loop-node.test.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/loop-node/loop-node.test.tsx
similarity index 94%
rename from apps/sim/app/w/[id]/components/loop-node/loop-node.test.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/loop-node/loop-node.test.tsx
index 9625cb5f611..14f5343666f 100644
--- a/apps/sim/app/w/[id]/components/loop-node/loop-node.test.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/loop-node/loop-node.test.tsx
@@ -2,7 +2,6 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
import { useWorkflowStore } from '@/stores/workflows/workflow/store'
import { LoopNodeComponent } from './loop-node'
-// Mock dependencies that don't need DOM
vi.mock('@/stores/workflows/workflow/store', () => ({
useWorkflowStore: vi.fn(),
}))
@@ -16,7 +15,6 @@ vi.mock('@/lib/logs/console-logger', () => ({
})),
}))
-// Mock ReactFlow components and hooks
vi.mock('reactflow', () => ({
Handle: ({ id, type, position }: any) => ({ id, type, position }),
Position: {
@@ -32,7 +30,6 @@ vi.mock('reactflow', () => ({
memo: (component: any) => component,
}))
-// Mock React hooks
vi.mock('react', async () => {
const actual = await vi.importActual('react')
return {
@@ -43,7 +40,6 @@ vi.mock('react', async () => {
}
})
-// Mock UI components
vi.mock('@/components/ui/button', () => ({
Button: ({ children, onClick, ...props }: any) => ({ children, onClick, ...props }),
}))
@@ -60,7 +56,6 @@ vi.mock('@/lib/utils', () => ({
cn: (...classes: any[]) => classes.filter(Boolean).join(' '),
}))
-// Mock the LoopBadges component
vi.mock('./components/loop-badges', () => ({
LoopBadges: ({ loopId }: any) => ({ loopId }),
}))
@@ -87,8 +82,6 @@ describe('LoopNodeComponent', () => {
beforeEach(() => {
vi.clearAllMocks()
- // Mock useWorkflowStore
-
;(useWorkflowStore as any).mockImplementation((selector: any) => {
const state = {
removeBlock: mockRemoveBlock,
@@ -96,7 +89,6 @@ describe('LoopNodeComponent', () => {
return selector(state)
})
- // Mock getNodes
mockGetNodes.mockReturnValue([])
})
@@ -111,14 +103,12 @@ describe('LoopNodeComponent', () => {
})
it('should be a memoized component', () => {
- // Since we mocked memo to return the component as-is, we can verify it exists
expect(LoopNodeComponent).toBeDefined()
})
})
describe('Props Validation and Type Safety', () => {
it('should accept NodeProps interface', () => {
- // Test that the component accepts the correct prop types
const validProps = {
id: 'test-id',
type: 'loopNode' as const,
@@ -135,9 +125,7 @@ describe('LoopNodeComponent', () => {
dragging: false,
}
- // This tests that TypeScript compilation succeeds with these props
expect(() => {
- // We're not calling the component, just verifying the types
const _component: typeof LoopNodeComponent = LoopNodeComponent
expect(_component).toBeDefined()
}).not.toThrow()
@@ -163,10 +151,8 @@ describe('LoopNodeComponent', () => {
describe('Store Integration', () => {
it('should integrate with workflow store', () => {
- // Test that the component uses the store correctly
expect(useWorkflowStore).toBeDefined()
- // Verify the store selector function works
const mockState = { removeBlock: mockRemoveBlock }
const selector = vi.fn((state) => state.removeBlock)
@@ -181,7 +167,6 @@ describe('LoopNodeComponent', () => {
expect(mockRemoveBlock).toBeDefined()
expect(typeof mockRemoveBlock).toBe('function')
- // Test calling removeBlock
mockRemoveBlock('test-id')
expect(mockRemoveBlock).toHaveBeenCalledWith('test-id')
})
@@ -189,7 +174,6 @@ describe('LoopNodeComponent', () => {
describe('Component Logic Tests', () => {
it('should handle nesting level calculation logic', () => {
- // Test the nesting level calculation logic
const testCases = [
{ nodes: [], parentId: undefined, expectedLevel: 0 },
{ nodes: [{ id: 'parent', data: {} }], parentId: 'parent', expectedLevel: 1 },
diff --git a/apps/sim/app/w/[id]/components/loop-node/loop-node.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/loop-node/loop-node.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/loop-node/loop-node.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/loop-node/loop-node.tsx
diff --git a/apps/sim/app/w/[id]/components/notifications/notifications.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/notifications/notifications.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/notifications/notifications.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/notifications/notifications.tsx
diff --git a/apps/sim/app/w/[id]/components/panel/components/chat/chat.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/chat/chat.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/panel/components/chat/chat.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/chat/chat.tsx
diff --git a/apps/sim/app/w/[id]/components/panel/components/chat/components/chat-message/chat-message.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/chat/components/chat-message/chat-message.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/panel/components/chat/components/chat-message/chat-message.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/chat/components/chat-message/chat-message.tsx
diff --git a/apps/sim/app/w/[id]/components/panel/components/chat/components/chat-modal/chat-modal.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/chat/components/chat-modal/chat-modal.tsx
similarity index 97%
rename from apps/sim/app/w/[id]/components/panel/components/chat/components/chat-modal/chat-modal.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/chat/components/chat-modal/chat-modal.tsx
index 31b887312a2..f0b8d9498a2 100644
--- a/apps/sim/app/w/[id]/components/panel/components/chat/components/chat-modal/chat-modal.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/chat/components/chat-modal/chat-modal.tsx
@@ -4,8 +4,8 @@ import { type KeyboardEvent, useEffect, useMemo, useRef } from 'react'
import { ArrowUp, X } from 'lucide-react'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
-import { JSONView } from '@/app/w/[id]/components/panel/components/console/components/json-view/json-view'
-import { useWorkflowExecution } from '@/app/w/[id]/hooks/use-workflow-execution'
+import { JSONView } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/console/components/json-view/json-view'
+import { useWorkflowExecution } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution'
import { useExecutionStore } from '@/stores/execution/store'
import { useChatStore } from '@/stores/panel/chat/store'
import type { ChatMessage as ChatMessageType } from '@/stores/panel/chat/types'
diff --git a/apps/sim/app/w/[id]/components/panel/components/chat/components/output-select/output-select.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/chat/components/output-select/output-select.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/panel/components/chat/components/output-select/output-select.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/chat/components/output-select/output-select.tsx
diff --git a/apps/sim/app/w/[id]/components/panel/components/console/components/audio-player/audio-player.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/console/components/audio-player/audio-player.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/panel/components/console/components/audio-player/audio-player.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/console/components/audio-player/audio-player.tsx
diff --git a/apps/sim/app/w/[id]/components/panel/components/console/components/console-entry/console-entry.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/console/components/console-entry/console-entry.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/panel/components/console/components/console-entry/console-entry.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/console/components/console-entry/console-entry.tsx
diff --git a/apps/sim/app/w/[id]/components/panel/components/console/components/json-view/json-view.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/console/components/json-view/json-view.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/panel/components/console/components/json-view/json-view.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/console/components/json-view/json-view.tsx
diff --git a/apps/sim/app/w/[id]/components/panel/components/console/console.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/console/console.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/panel/components/console/console.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/console/console.tsx
diff --git a/apps/sim/app/w/[id]/components/panel/components/variables/variables.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/variables/variables.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/panel/components/variables/variables.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/variables/variables.tsx
diff --git a/apps/sim/app/w/[id]/components/panel/panel.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/panel.tsx
similarity index 99%
rename from apps/sim/app/w/[id]/components/panel/panel.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/panel.tsx
index 7afc5e3eb1e..27494712dc0 100644
--- a/apps/sim/app/w/[id]/components/panel/panel.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/panel.tsx
@@ -5,8 +5,8 @@ import { Expand, PanelRight } from 'lucide-react'
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
import { useChatStore } from '@/stores/panel/chat/store'
import { useConsoleStore } from '@/stores/panel/console/store'
+import { usePanelStore } from '@/stores/panel/store'
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
-import { usePanelStore } from '../../../../../stores/panel/store'
import { Chat } from './components/chat/chat'
import { ChatModal } from './components/chat/components/chat-modal/chat-modal'
import { Console } from './components/console/console'
diff --git a/apps/sim/app/w/[id]/components/parallel-node/components/parallel-badges.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/parallel-node/components/parallel-badges.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/parallel-node/components/parallel-badges.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/parallel-node/components/parallel-badges.tsx
diff --git a/apps/sim/app/w/[id]/components/parallel-node/parallel-config.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/parallel-node/parallel-config.ts
similarity index 100%
rename from apps/sim/app/w/[id]/components/parallel-node/parallel-config.ts
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/parallel-node/parallel-config.ts
diff --git a/apps/sim/app/w/[id]/components/parallel-node/parallel-node.test.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/parallel-node/parallel-node.test.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/parallel-node/parallel-node.test.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/parallel-node/parallel-node.test.tsx
diff --git a/apps/sim/app/w/[id]/components/parallel-node/parallel-node.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/parallel-node/parallel-node.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/parallel-node/parallel-node.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/parallel-node/parallel-node.tsx
diff --git a/apps/sim/app/w/[id]/components/skeleton-loading/skeleton-loading.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/skeleton-loading/skeleton-loading.tsx
similarity index 99%
rename from apps/sim/app/w/[id]/components/skeleton-loading/skeleton-loading.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/skeleton-loading/skeleton-loading.tsx
index 141700a1ec2..de8e90cdfab 100644
--- a/apps/sim/app/w/[id]/components/skeleton-loading/skeleton-loading.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/skeleton-loading/skeleton-loading.tsx
@@ -5,7 +5,6 @@ import { Button } from '@/components/ui/button'
import { Skeleton } from '@/components/ui/skeleton'
import { useSidebarStore } from '@/stores/sidebar/store'
-// Skeleton Components
const SkeletonControlBar = () => {
return (
diff --git a/apps/sim/app/w/[id]/components/toolbar/components/toolbar-block/toolbar-block.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/toolbar/components/toolbar-block/toolbar-block.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/toolbar/components/toolbar-block/toolbar-block.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/toolbar/components/toolbar-block/toolbar-block.tsx
diff --git a/apps/sim/app/w/[id]/components/toolbar/components/toolbar-loop-block/toolbar-loop-block.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/toolbar/components/toolbar-loop-block/toolbar-loop-block.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/toolbar/components/toolbar-loop-block/toolbar-loop-block.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/toolbar/components/toolbar-loop-block/toolbar-loop-block.tsx
diff --git a/apps/sim/app/w/[id]/components/toolbar/components/toolbar-parallel-block/toolbar-parallel-block.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/toolbar/components/toolbar-parallel-block/toolbar-parallel-block.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/toolbar/components/toolbar-parallel-block/toolbar-parallel-block.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/toolbar/components/toolbar-parallel-block/toolbar-parallel-block.tsx
diff --git a/apps/sim/app/w/[id]/components/toolbar/components/toolbar-tabs/toolbar-tabs.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/toolbar/components/toolbar-tabs/toolbar-tabs.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/toolbar/components/toolbar-tabs/toolbar-tabs.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/toolbar/components/toolbar-tabs/toolbar-tabs.tsx
diff --git a/apps/sim/app/w/[id]/components/toolbar/toolbar.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/toolbar/toolbar.tsx
similarity index 95%
rename from apps/sim/app/w/[id]/components/toolbar/toolbar.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/toolbar/toolbar.tsx
index 8d86f8407f5..177413e6ed7 100644
--- a/apps/sim/app/w/[id]/components/toolbar/toolbar.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/toolbar/toolbar.tsx
@@ -6,7 +6,7 @@ import { useParams } from 'next/navigation'
import { Input } from '@/components/ui/input'
import { ScrollArea } from '@/components/ui/scroll-area'
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
-import { useUserPermissionsContext } from '@/app/w/components/providers/workspace-permissions-provider'
+import { useUserPermissionsContext } from '@/app/workspace/[workspaceId]/w/components/providers/workspace-permissions-provider'
import { getAllBlocks, getBlocksByCategory } from '@/blocks'
import type { BlockCategory } from '@/blocks/types'
import { useSidebarStore } from '@/stores/sidebar/store'
@@ -43,16 +43,15 @@ export const Toolbar = React.memo(() => {
const params = useParams()
const workflowId = params?.id as string
- // Get the workspace ID from the workflow registry
- const { activeWorkspaceId, workflows } = useWorkflowRegistry()
+ // Get the workspace ID from URL params
+ const { workflows } = useWorkflowRegistry()
+ const workspaceId = params.workspaceId as string
const currentWorkflow = useMemo(
() => (workflowId ? workflows[workflowId] : null),
[workflowId, workflows]
)
- const workspaceId = currentWorkflow?.workspaceId || activeWorkspaceId
-
const userPermissions = useUserPermissionsContext()
const [activeTab, setActiveTab] = useState
('blocks')
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/action-bar/action-bar.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/action-bar/action-bar.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/action-bar/action-bar.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/action-bar/action-bar.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/connection-blocks/connection-blocks.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/connection-blocks/connection-blocks.tsx
similarity index 97%
rename from apps/sim/app/w/[id]/components/workflow-block/components/connection-blocks/connection-blocks.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/connection-blocks/connection-blocks.tsx
index baf322f53e7..b9f17f57024 100644
--- a/apps/sim/app/w/[id]/components/workflow-block/components/connection-blocks/connection-blocks.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/connection-blocks/connection-blocks.tsx
@@ -1,6 +1,9 @@
import { Card } from '@/components/ui/card'
import { cn } from '@/lib/utils'
-import { type ConnectedBlock, useBlockConnections } from '@/app/w/[id]/hooks/use-block-connections'
+import {
+ type ConnectedBlock,
+ useBlockConnections,
+} from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-block-connections'
import { useSubBlockStore } from '@/stores/workflows/subblock/store'
interface ConnectionBlocksProps {
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/channel-selector/channel-selector-input.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/channel-selector/channel-selector-input.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/channel-selector/channel-selector-input.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/channel-selector/channel-selector-input.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/channel-selector/components/slack-channel-selector.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/channel-selector/components/slack-channel-selector.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/channel-selector/components/slack-channel-selector.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/channel-selector/components/slack-channel-selector.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/checkbox-list.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/checkbox-list.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/checkbox-list.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/checkbox-list.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/code.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/code.tsx
similarity index 99%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/code.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/code.tsx
index d47adca2d8e..a228efb1714 100644
--- a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/code.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/code.tsx
@@ -11,7 +11,7 @@ import { checkEnvVarTrigger, EnvVarDropdown } from '@/components/ui/env-var-drop
import { checkTagTrigger, TagDropdown } from '@/components/ui/tag-dropdown'
import { createLogger } from '@/lib/logs/console-logger'
import { cn } from '@/lib/utils'
-import { useCodeGeneration } from '@/app/w/[id]/hooks/use-code-generation'
+import { useCodeGeneration } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-code-generation'
import { useSubBlockStore } from '@/stores/workflows/subblock/store'
import { CodePromptBar } from '../../../../code-prompt-bar/code-prompt-bar'
import { useSubBlockValue } from '../hooks/use-sub-block-value'
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/condition-input.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/condition-input.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/condition-input.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/condition-input.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/credential-selector/components/oauth-required-modal.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/credential-selector/components/oauth-required-modal.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/credential-selector/components/oauth-required-modal.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/credential-selector/components/oauth-required-modal.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/credential-selector/credential-selector.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/credential-selector/credential-selector.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/credential-selector/credential-selector.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/credential-selector/credential-selector.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/date-input.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/date-input.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/date-input.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/date-input.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/document-selector/document-selector.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/document-selector/document-selector.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/document-selector/document-selector.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/document-selector/document-selector.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/dropdown.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/dropdown.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/dropdown.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/dropdown.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/eval-input.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/eval-input.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/eval-input.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/eval-input.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/file-selector/components/confluence-file-selector.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/file-selector/components/confluence-file-selector.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/file-selector/components/confluence-file-selector.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/file-selector/components/confluence-file-selector.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/file-selector/components/discord-channel-selector.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/file-selector/components/discord-channel-selector.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/file-selector/components/discord-channel-selector.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/file-selector/components/discord-channel-selector.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/file-selector/components/google-calendar-selector.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/file-selector/components/google-calendar-selector.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/file-selector/components/google-calendar-selector.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/file-selector/components/google-calendar-selector.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/file-selector/components/google-drive-picker.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/file-selector/components/google-drive-picker.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/file-selector/components/google-drive-picker.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/file-selector/components/google-drive-picker.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/file-selector/components/jira-issue-selector.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/file-selector/components/jira-issue-selector.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/file-selector/components/jira-issue-selector.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/file-selector/components/jira-issue-selector.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/file-selector/components/microsoft-file-selector.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/file-selector/components/microsoft-file-selector.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/file-selector/components/microsoft-file-selector.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/file-selector/components/microsoft-file-selector.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/file-selector/components/teams-message-selector.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/file-selector/components/teams-message-selector.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/file-selector/components/teams-message-selector.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/file-selector/components/teams-message-selector.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/file-selector/file-selector-input.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/file-selector/file-selector-input.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/file-selector/file-selector-input.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/file-selector/file-selector-input.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/file-upload.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/file-upload.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/file-upload.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/file-upload.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/folder-selector/components/folder-selector-input.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/folder-selector/components/folder-selector-input.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/folder-selector/components/folder-selector-input.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/folder-selector/components/folder-selector-input.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/folder-selector/folder-selector.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/folder-selector/folder-selector.tsx
similarity index 98%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/folder-selector/folder-selector.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/folder-selector/folder-selector.tsx
index 2a0d9990eab..31abe42a2b3 100644
--- a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/folder-selector/folder-selector.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/folder-selector/folder-selector.tsx
@@ -15,7 +15,7 @@ import {
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
import { createLogger } from '@/lib/logs/console-logger'
import { type Credential, getProviderIdFromServiceId, getServiceIdFromScopes } from '@/lib/oauth'
-import { OAuthRequiredModal } from '@/app/w/[id]/components/workflow-block/components/sub-block/components/credential-selector/components/oauth-required-modal'
+import { OAuthRequiredModal } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/credential-selector/components/oauth-required-modal'
import { saveToStorage } from '@/stores/workflows/persistence'
const logger = createLogger('FolderSelector')
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/knowledge-base-selector/knowledge-base-selector.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/knowledge-base-selector/knowledge-base-selector.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/knowledge-base-selector/knowledge-base-selector.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/knowledge-base-selector/knowledge-base-selector.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/long-input.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/long-input.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/long-input.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/long-input.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/project-selector/components/discord-server-selector.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/project-selector/components/discord-server-selector.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/project-selector/components/discord-server-selector.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/project-selector/components/discord-server-selector.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/project-selector/components/jira-project-selector.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/project-selector/components/jira-project-selector.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/project-selector/components/jira-project-selector.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/project-selector/components/jira-project-selector.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/project-selector/components/linear-project-selector.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/project-selector/components/linear-project-selector.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/project-selector/components/linear-project-selector.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/project-selector/components/linear-project-selector.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/project-selector/components/linear-team-selector.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/project-selector/components/linear-team-selector.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/project-selector/components/linear-team-selector.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/project-selector/components/linear-team-selector.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/project-selector/project-selector-input.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/project-selector/project-selector-input.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/project-selector/project-selector-input.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/project-selector/project-selector-input.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/response/components/property-renderer.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/response/components/property-renderer.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/response/components/property-renderer.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/response/components/property-renderer.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/response/components/value-input.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/response/components/value-input.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/response/components/value-input.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/response/components/value-input.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/response/response-format.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/response/response-format.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/response/response-format.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/response/response-format.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/schedule/components/schedule-modal.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/schedule/components/schedule-modal.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/schedule/components/schedule-modal.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/schedule/components/schedule-modal.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/schedule/schedule-config.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/schedule/schedule-config.tsx
similarity index 99%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/schedule/schedule-config.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/schedule/schedule-config.tsx
index 182b8ae6922..9b9c58f6d1c 100644
--- a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/schedule/schedule-config.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/schedule/schedule-config.tsx
@@ -46,7 +46,7 @@ export function ScheduleConfig({
const [refreshCounter, setRefreshCounter] = useState(0)
const params = useParams()
- const workflowId = params.id as string
+ const workflowId = params.workflowId as string
// Get workflow state from store
const setScheduleStatus = useWorkflowStore((state) => state.setScheduleStatus)
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/short-input.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/short-input.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/short-input.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/short-input.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/slider-input.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/slider-input.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/slider-input.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/slider-input.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/starter/input-format.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/starter/input-format.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/starter/input-format.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/starter/input-format.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/switch.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/switch.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/switch.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/switch.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/table.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/table.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/table.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/table.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/time-input.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/time-input.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/time-input.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/time-input.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/tool-input/components/code-editor/code-editor.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/tool-input/components/code-editor/code-editor.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/tool-input/components/code-editor/code-editor.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/tool-input/components/code-editor/code-editor.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/tool-input/components/custom-tool-modal/custom-tool-modal.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/tool-input/components/custom-tool-modal/custom-tool-modal.tsx
similarity index 99%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/tool-input/components/custom-tool-modal/custom-tool-modal.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/tool-input/components/custom-tool-modal/custom-tool-modal.tsx
index aee40413bec..84f74fc0833 100644
--- a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/tool-input/components/custom-tool-modal/custom-tool-modal.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/tool-input/components/custom-tool-modal/custom-tool-modal.tsx
@@ -24,7 +24,7 @@ import { Label } from '@/components/ui/label'
import { checkTagTrigger, TagDropdown } from '@/components/ui/tag-dropdown'
import { createLogger } from '@/lib/logs/console-logger'
import { cn } from '@/lib/utils'
-import { useCodeGeneration } from '@/app/w/[id]/hooks/use-code-generation'
+import { useCodeGeneration } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-code-generation'
import { useCustomToolsStore } from '@/stores/custom-tools/store'
import { CodePromptBar } from '../../../../../../../code-prompt-bar/code-prompt-bar'
import { CodeEditor } from '../code-editor/code-editor'
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/tool-input/components/tool-command/tool-command.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/tool-input/components/tool-command/tool-command.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/tool-input/components/tool-command/tool-command.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/tool-input/components/tool-command/tool-command.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/tool-input/tool-input.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/tool-input/tool-input.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/tool-input/tool-input.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/tool-input/tool-input.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/providers/airtable.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/providers/airtable.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/providers/airtable.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/providers/airtable.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/providers/discord.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/providers/discord.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/providers/discord.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/providers/discord.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/providers/generic.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/providers/generic.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/providers/generic.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/providers/generic.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/providers/github.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/providers/github.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/providers/github.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/providers/github.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/providers/gmail.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/providers/gmail.tsx
similarity index 98%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/providers/gmail.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/providers/gmail.tsx
index a23eb809d83..3168af8fbfe 100644
--- a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/providers/gmail.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/providers/gmail.tsx
@@ -16,7 +16,7 @@ import {
import { Skeleton } from '@/components/ui/skeleton'
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
import { Logger } from '@/lib/logs/console-logger'
-import { JSONView } from '@/app/w/[id]/components/panel/components/console/components/json-view/json-view'
+import { JSONView } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/console/components/json-view/json-view'
import { ConfigSection } from '../ui/config-section'
const logger = new Logger('GmailConfig')
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/providers/slack.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/providers/slack.tsx
similarity index 97%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/providers/slack.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/providers/slack.tsx
index cb584d2e751..4bb03e252f1 100644
--- a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/providers/slack.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/providers/slack.tsx
@@ -1,6 +1,6 @@
import { SlackIcon } from '@/components/icons'
import { Notice } from '@/components/ui/notice'
-import { JSONView } from '@/app/w/[id]/components/panel/components/console/components/json-view/json-view'
+import { JSONView } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/console/components/json-view/json-view'
import { ConfigSection } from '../ui/config-section'
import { InstructionsSection } from '../ui/instructions-section'
import { TestResultDisplay } from '../ui/test-result'
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/providers/stripe.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/providers/stripe.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/providers/stripe.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/providers/stripe.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/providers/telegram.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/providers/telegram.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/providers/telegram.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/providers/telegram.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/providers/whatsapp.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/providers/whatsapp.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/providers/whatsapp.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/providers/whatsapp.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/config-field.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/ui/config-field.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/config-field.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/ui/config-field.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/config-section.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/ui/config-section.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/config-section.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/ui/config-section.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/confirmation.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/ui/confirmation.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/confirmation.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/ui/confirmation.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/copyable.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/ui/copyable.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/copyable.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/ui/copyable.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/instructions-section.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/ui/instructions-section.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/instructions-section.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/ui/instructions-section.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/test-result.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/ui/test-result.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/test-result.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/ui/test-result.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/webhook-config-field.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/ui/webhook-config-field.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/webhook-config-field.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/ui/webhook-config-field.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/webhook-footer.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/ui/webhook-footer.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/webhook-footer.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/ui/webhook-footer.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/webhook-url.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/ui/webhook-url.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/webhook-url.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/ui/webhook-url.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/webhook-modal.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/webhook-modal.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/webhook-modal.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/webhook-modal.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/webhook.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/webhook.tsx
similarity index 99%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/webhook.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/webhook.tsx
index a7a82be82ab..041ddd7aa41 100644
--- a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/webhook.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/webhook.tsx
@@ -310,7 +310,7 @@ export function WebhookConfig({
const [error, setError] = useState(null)
const [webhookId, setWebhookId] = useState(null)
const params = useParams()
- const workflowId = params.id as string
+ const workflowId = params.workflowId as string
const [isLoading, setIsLoading] = useState(false)
const [gmailCredentialId, setGmailCredentialId] = useState('')
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/hooks/use-sub-block-value.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/hooks/use-sub-block-value.ts
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/hooks/use-sub-block-value.ts
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/hooks/use-sub-block-value.ts
diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/sub-block.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/sub-block.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-block/components/sub-block/sub-block.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/sub-block.tsx
diff --git a/apps/sim/app/w/[id]/components/workflow-block/workflow-block.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/workflow-block.tsx
similarity index 99%
rename from apps/sim/app/w/[id]/components/workflow-block/workflow-block.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/workflow-block.tsx
index 90be7d0fa0e..0ffb7258664 100644
--- a/apps/sim/app/w/[id]/components/workflow-block/workflow-block.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/workflow-block.tsx
@@ -7,7 +7,7 @@ import { Card } from '@/components/ui/card'
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
import { parseCronToHumanReadable } from '@/lib/schedules/utils'
import { cn, formatDateTime, validateName } from '@/lib/utils'
-import { useUserPermissionsContext } from '@/app/w/components/providers/workspace-permissions-provider'
+import { useUserPermissionsContext } from '@/app/workspace/[workspaceId]/w/components/providers/workspace-permissions-provider'
import type { BlockConfig, SubBlockConfig } from '@/blocks/types'
import { useCollaborativeWorkflow } from '@/hooks/use-collaborative-workflow'
import { useExecutionStore } from '@/stores/execution/store'
diff --git a/apps/sim/app/w/[id]/components/workflow-edge/workflow-edge.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-edge/workflow-edge.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/components/workflow-edge/workflow-edge.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-edge/workflow-edge.tsx
diff --git a/apps/sim/app/w/[id]/hooks/use-block-connections.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-block-connections.ts
similarity index 100%
rename from apps/sim/app/w/[id]/hooks/use-block-connections.ts
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-block-connections.ts
diff --git a/apps/sim/app/w/[id]/hooks/use-code-generation.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-code-generation.ts
similarity index 100%
rename from apps/sim/app/w/[id]/hooks/use-code-generation.ts
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-code-generation.ts
diff --git a/apps/sim/app/w/[id]/hooks/use-presence.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-presence.ts
similarity index 97%
rename from apps/sim/app/w/[id]/hooks/use-presence.ts
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-presence.ts
index 972f000faf9..2e3b1a5f8ab 100644
--- a/apps/sim/app/w/[id]/hooks/use-presence.ts
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-presence.ts
@@ -3,7 +3,7 @@
import { useMemo } from 'react'
import { useSocket } from '@/contexts/socket-context'
-interface PresenceUser {
+type PresenceUser = {
connectionId: string | number
name?: string
color?: string
diff --git a/apps/sim/app/w/[id]/hooks/use-workflow-execution.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution.ts
similarity index 100%
rename from apps/sim/app/w/[id]/hooks/use-workflow-execution.ts
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution.ts
diff --git a/apps/sim/app/w/[id]/layout.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/layout.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/layout.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/layout.tsx
diff --git a/apps/sim/app/w/[id]/page.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/page.tsx
similarity index 100%
rename from apps/sim/app/w/[id]/page.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/page.tsx
diff --git a/apps/sim/app/w/[id]/utils.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils.ts
similarity index 100%
rename from apps/sim/app/w/[id]/utils.ts
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils.ts
diff --git a/apps/sim/app/w/[id]/workflow.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx
similarity index 96%
rename from apps/sim/app/w/[id]/workflow.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx
index 68a38d78d1d..72606e7f03a 100644
--- a/apps/sim/app/w/[id]/workflow.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx
@@ -11,12 +11,16 @@ import ReactFlow, {
useReactFlow,
} from 'reactflow'
import 'reactflow/dist/style.css'
-
import { createLogger } from '@/lib/logs/console-logger'
-import { LoopNodeComponent } from '@/app/w/[id]/components/loop-node/loop-node'
-import { NotificationList } from '@/app/w/[id]/components/notifications/notifications'
-import { ParallelNodeComponent } from '@/app/w/[id]/components/parallel-node/parallel-node'
-import { useUserPermissionsContext } from '@/app/w/components/providers/workspace-permissions-provider'
+import { ControlBar } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/control-bar'
+import { ErrorBoundary } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/error/index'
+import { LoopNodeComponent } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/loop-node/loop-node'
+import { NotificationList } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/notifications/notifications'
+import { Panel } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/panel'
+import { ParallelNodeComponent } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/parallel-node/parallel-node'
+import { SkeletonLoading } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/skeleton-loading/skeleton-loading'
+import { Toolbar } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/toolbar/toolbar'
+import { useUserPermissionsContext } from '@/app/workspace/[workspaceId]/w/components/providers/workspace-permissions-provider'
import { getBlock } from '@/blocks'
import { useSocket } from '@/contexts/socket-context'
import { useCollaborativeWorkflow } from '@/hooks/use-collaborative-workflow'
@@ -26,14 +30,8 @@ import { useNotificationStore } from '@/stores/notifications/store'
import { useVariablesStore } from '@/stores/panel/variables/store'
import { useGeneralStore } from '@/stores/settings/general/store'
import { useSidebarStore } from '@/stores/sidebar/store'
-// Removed sync manager import - Socket.IO handles real-time sync
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
import { useWorkflowStore } from '@/stores/workflows/workflow/store'
-import { ControlBar } from './components/control-bar/control-bar'
-import { ErrorBoundary } from './components/error/index'
-import { Panel } from './components/panel/panel'
-import { SkeletonLoading } from './components/skeleton-loading/skeleton-loading'
-import { Toolbar } from './components/toolbar/toolbar'
import { WorkflowBlock } from './components/workflow-block/workflow-block'
import { WorkflowEdge } from './components/workflow-edge/workflow-edge'
import {
@@ -95,7 +93,7 @@ const WorkflowContent = React.memo(() => {
const { project, getNodes, fitView } = useReactFlow()
// Get workspace ID from current workflow
- const workflowId = params.id as string
+ const workflowId = params.workflowId as string
const { workflows, activeWorkflowId, isLoading, setActiveWorkflow, createWorkflow } =
useWorkflowRegistry()
@@ -806,7 +804,7 @@ const WorkflowContent = React.memo(() => {
// Track when workflow is fully ready for rendering
useEffect(() => {
- const currentId = params.id as string
+ const currentId = params.workflowId as string
// Reset workflow ready state when workflow changes
if (activeWorkflowId !== currentId) {
@@ -832,13 +830,13 @@ const WorkflowContent = React.memo(() => {
return () => clearTimeout(timeoutId)
}
setIsWorkflowReady(false)
- }, [activeWorkflowId, params.id, workflows, isLoading])
+ }, [activeWorkflowId, params.workflowId, workflows, isLoading])
// Init workflow
useEffect(() => {
const validateAndNavigate = async () => {
const workflowIds = Object.keys(workflows)
- const currentId = params.id as string
+ const currentId = params.workflowId as string
// Wait for both initialization and workflow loading to complete
if (isLoading) {
@@ -849,14 +847,14 @@ const WorkflowContent = React.memo(() => {
// If no workflows exist, redirect to workspace root to let server handle workflow creation
if (workflowIds.length === 0 && !isLoading) {
logger.info('No workflows found, redirecting to workspace root')
- router.replace('/w')
+ router.replace(`/workspace/${workspaceId}/w`)
return
}
// Navigate to existing workflow or first available
if (!workflows[currentId]) {
logger.info(`Workflow ${currentId} not found, redirecting to first available workflow`)
- router.replace(`/w/${workflowIds[0]}`)
+ router.replace(`/workspace/${workspaceId}/w/${workflowIds[0]}`)
return
}
@@ -877,7 +875,7 @@ const WorkflowContent = React.memo(() => {
validateAndNavigate()
}, [
- params.id,
+ params.workflowId,
workflows,
isLoading,
setActiveWorkflow,
@@ -1033,6 +1031,11 @@ const WorkflowContent = React.memo(() => {
validateNestedSubflows()
}, [blocks, validateNestedSubflows])
+ // Validate nested subflows whenever blocks change
+ useEffect(() => {
+ validateNestedSubflows()
+ }, [blocks, validateNestedSubflows])
+
// Update edges
const onEdgesChange = useCallback(
(changes: any) => {
@@ -1473,7 +1476,7 @@ const WorkflowContent = React.memo(() => {
@@ -1489,12 +1492,12 @@ const WorkflowContent = React.memo(() => {
return (
-
+
0} />
diff --git a/apps/sim/app/w/components/providers/providers.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/providers/providers.tsx
similarity index 100%
rename from apps/sim/app/w/components/providers/providers.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/providers/providers.tsx
diff --git a/apps/sim/app/w/components/providers/theme-provider.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/providers/theme-provider.tsx
similarity index 100%
rename from apps/sim/app/w/components/providers/theme-provider.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/providers/theme-provider.tsx
diff --git a/apps/sim/app/w/components/providers/workspace-permissions-provider.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/providers/workspace-permissions-provider.tsx
similarity index 86%
rename from apps/sim/app/w/components/providers/workspace-permissions-provider.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/providers/workspace-permissions-provider.tsx
index 77b4dfbf5d8..9ebbd4286e8 100644
--- a/apps/sim/app/w/components/providers/workspace-permissions-provider.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/components/providers/workspace-permissions-provider.tsx
@@ -1,12 +1,15 @@
'use client'
import React, { createContext, useContext, useMemo } from 'react'
+import { useParams } from 'next/navigation'
+import { createLogger } from '@/lib/logs/console-logger'
import { useUserPermissions, type WorkspaceUserPermissions } from '@/hooks/use-user-permissions'
import {
useWorkspacePermissions,
type WorkspacePermissions,
} from '@/hooks/use-workspace-permissions'
-import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
+
+const logger = createLogger('WorkspacePermissionsProvider')
interface WorkspacePermissionsContextType {
// Raw workspace permissions data
@@ -27,17 +30,20 @@ interface WorkspacePermissionsProviderProps {
const WorkspacePermissionsProvider = React.memo
(
({ children }) => {
- const { activeWorkspaceId } = useWorkflowRegistry()
+ const params = useParams()
+ const workspaceId = params.workspaceId as string
+
+ if (!workspaceId) {
+ logger.warn('Workspace ID is undefined from params:', params)
+ }
- // Fetch workspace permissions once
const {
permissions: workspacePermissions,
loading: permissionsLoading,
error: permissionsError,
updatePermissions,
- } = useWorkspacePermissions(activeWorkspaceId)
+ } = useWorkspacePermissions(workspaceId)
- // Compute user permissions based on workspace permissions
const userPermissions = useUserPermissions(
workspacePermissions,
permissionsLoading,
diff --git a/apps/sim/app/w/components/sidebar/components/create-menu/create-menu.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/create-menu/create-menu.tsx
similarity index 94%
rename from apps/sim/app/w/components/sidebar/components/create-menu/create-menu.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/create-menu/create-menu.tsx
index 5ff60db8657..188ee91ea8d 100644
--- a/apps/sim/app/w/components/sidebar/components/create-menu/create-menu.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/create-menu/create-menu.tsx
@@ -1,7 +1,9 @@
'use client'
import { useState } from 'react'
+import { logger } from '@sentry/nextjs'
import { File, Folder, Plus } from 'lucide-react'
+import { useParams } from 'next/navigation'
import { Button } from '@/components/ui/button'
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'
import { Input } from '@/components/ui/input'
@@ -9,7 +11,6 @@ import { Label } from '@/components/ui/label'
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
import { cn } from '@/lib/utils'
import { useFolderStore } from '@/stores/folders/store'
-import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
interface CreateMenuProps {
onCreateWorkflow: (folderId?: string) => void
@@ -22,7 +23,8 @@ export function CreateMenu({ onCreateWorkflow, isCollapsed }: CreateMenuProps) {
const [isCreating, setIsCreating] = useState(false)
const [isHoverOpen, setIsHoverOpen] = useState(false)
- const { activeWorkspaceId } = useWorkflowRegistry()
+ const params = useParams()
+ const workspaceId = params.workspaceId as string
const { createFolder } = useFolderStore()
const handleCreateWorkflow = () => {
@@ -37,18 +39,18 @@ export function CreateMenu({ onCreateWorkflow, isCollapsed }: CreateMenuProps) {
const handleFolderSubmit = async (e: React.FormEvent) => {
e.preventDefault()
- if (!folderName.trim() || !activeWorkspaceId) return
+ if (!folderName.trim() || !workspaceId) return
setIsCreating(true)
try {
await createFolder({
name: folderName.trim(),
- workspaceId: activeWorkspaceId,
+ workspaceId: workspaceId,
})
setFolderName('')
setShowFolderDialog(false)
} catch (error) {
- console.error('Failed to create folder:', error)
+ logger.error('Failed to create folder:', { error })
} finally {
setIsCreating(false)
}
diff --git a/apps/sim/app/w/components/sidebar/components/folder-context-menu/folder-context-menu.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/folder-context-menu/folder-context-menu.tsx
similarity index 93%
rename from apps/sim/app/w/components/sidebar/components/folder-context-menu/folder-context-menu.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/folder-context-menu/folder-context-menu.tsx
index fcda8a79bec..08cebccd299 100644
--- a/apps/sim/app/w/components/sidebar/components/folder-context-menu/folder-context-menu.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/folder-context-menu/folder-context-menu.tsx
@@ -2,6 +2,7 @@
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 {
@@ -13,8 +14,10 @@ import {
} from '@/components/ui/dropdown-menu'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
+import { createLogger } from '@/lib/logs/console-logger'
import { useFolderStore } from '@/stores/folders/store'
-import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
+
+const logger = createLogger('FolderContextMenu')
interface FolderContextMenuProps {
folderId: string
@@ -37,8 +40,9 @@ export function FolderContextMenu({
const [renameName, setRenameName] = useState(folderName)
const [isCreating, setIsCreating] = useState(false)
const [isRenaming, setIsRenaming] = useState(false)
+ const params = useParams()
+ const workspaceId = params.workspaceId as string
- const { activeWorkspaceId } = useWorkflowRegistry()
const { createFolder, updateFolder, deleteFolder } = useFolderStore()
const handleCreateWorkflow = () => {
@@ -59,25 +63,25 @@ export function FolderContextMenu({
onDelete(folderId)
} else {
// Default delete behavior
- deleteFolder(folderId)
+ deleteFolder(folderId, workspaceId)
}
}
const handleSubfolderSubmit = async (e: React.FormEvent) => {
e.preventDefault()
- if (!subfolderName.trim() || !activeWorkspaceId) return
+ if (!subfolderName.trim() || !workspaceId) return
setIsCreating(true)
try {
await createFolder({
name: subfolderName.trim(),
- workspaceId: activeWorkspaceId,
+ workspaceId: workspaceId,
parentId: folderId,
})
setSubfolderName('')
setShowSubfolderDialog(false)
} catch (error) {
- console.error('Failed to create subfolder:', error)
+ logger.error('Failed to create subfolder:', { error })
} finally {
setIsCreating(false)
}
diff --git a/apps/sim/app/w/components/sidebar/components/folder-tree/components/folder-item.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/folder-tree/components/folder-item.tsx
similarity index 94%
rename from apps/sim/app/w/components/sidebar/components/folder-tree/components/folder-item.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/folder-tree/components/folder-item.tsx
index db9ffe073a2..5d0accc0e3d 100644
--- a/apps/sim/app/w/components/sidebar/components/folder-tree/components/folder-item.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/folder-tree/components/folder-item.tsx
@@ -3,6 +3,7 @@
import { useCallback, useEffect, useRef, useState } from 'react'
import clsx from 'clsx'
import { ChevronDown, ChevronRight, Folder, FolderOpen } from 'lucide-react'
+import { useParams } from 'next/navigation'
import {
AlertDialog,
AlertDialogAction,
@@ -14,9 +15,12 @@ import {
AlertDialogTitle,
} from '@/components/ui/alert-dialog'
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
+import { createLogger } from '@/lib/logs/console-logger'
import { type FolderTreeNode, useFolderStore } from '@/stores/folders/store'
import { FolderContextMenu } from '../../folder-context-menu/folder-context-menu'
+const logger = createLogger('FolderItem')
+
interface FolderItemProps {
folder: FolderTreeNode
isCollapsed?: boolean
@@ -39,7 +43,8 @@ export function FolderItem({
const { expandedFolders, toggleExpanded, updateFolderAPI, deleteFolder } = useFolderStore()
const [showDeleteDialog, setShowDeleteDialog] = useState(false)
const [isDeleting, setIsDeleting] = useState(false)
-
+ const params = useParams()
+ const workspaceId = params.workspaceId as string
const isExpanded = expandedFolders.has(folder.id)
const updateTimeoutRef = useRef | undefined>(undefined)
const pendingStateRef = useRef(null)
@@ -76,7 +81,7 @@ export function FolderItem({
try {
await updateFolderAPI(folderId, { name: newName })
} catch (error) {
- console.error('Failed to rename folder:', error)
+ logger.error('Failed to rename folder:', { error })
}
}
@@ -87,10 +92,10 @@ export function FolderItem({
const confirmDelete = async () => {
setIsDeleting(true)
try {
- await deleteFolder(folder.id)
+ await deleteFolder(folder.id, workspaceId)
setShowDeleteDialog(false)
} catch (error) {
- console.error('Failed to delete folder:', error)
+ logger.error('Failed to delete folder:', { error })
} finally {
setIsDeleting(false)
}
diff --git a/apps/sim/app/w/components/sidebar/components/folder-tree/components/workflow-item.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/folder-tree/components/workflow-item.tsx
similarity index 91%
rename from apps/sim/app/w/components/sidebar/components/folder-tree/components/workflow-item.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/folder-tree/components/workflow-item.tsx
index 07bf393d9bb..f054a4ca7a7 100644
--- a/apps/sim/app/w/components/sidebar/components/folder-tree/components/workflow-item.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/folder-tree/components/workflow-item.tsx
@@ -3,10 +3,14 @@
import { useRef, useState } from 'react'
import clsx from 'clsx'
import Link from 'next/link'
+import { useParams } from 'next/navigation'
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
+import { createLogger } from '@/lib/logs/console-logger'
import { useFolderStore, useIsWorkflowSelected } from '@/stores/folders/store'
import type { WorkflowMetadata } from '@/stores/workflows/registry/types'
+const logger = createLogger('WorkflowItem')
+
interface WorkflowItemProps {
workflow: WorkflowMetadata
active: boolean
@@ -26,6 +30,8 @@ export function WorkflowItem({
}: WorkflowItemProps) {
const [isDragging, setIsDragging] = useState(false)
const dragStartedRef = useRef(false)
+ const params = useParams()
+ const workspaceId = params.workspaceId as string
const { selectedWorkflows, selectOnly, toggleWorkflowSelection } = useFolderStore()
const isSelected = useIsWorkflowSelected(workflow.id)
@@ -74,7 +80,7 @@ export function WorkflowItem({
{
- if (activeWorkspaceId) {
- fetchFolders(activeWorkspaceId)
+ if (workspaceId) {
+ fetchFolders(workspaceId)
}
- }, [activeWorkspaceId, fetchFolders])
+ }, [workspaceId, fetchFolders])
useEffect(() => {
clearSelection()
- }, [activeWorkspaceId, clearSelection])
+ }, [workspaceId, clearSelection])
- const folderTree = activeWorkspaceId ? getFolderTree(activeWorkspaceId) : []
+ const folderTree = workspaceId ? getFolderTree(workspaceId) : []
// Group workflows by folder
const workflowsByFolder = regularWorkflows.reduce(
@@ -255,7 +258,7 @@ export function FolderTree({
- No workflows or folders in {activeWorkspaceId ? 'this workspace' : 'your account'}.
- Create one to get started.
+ No workflows or folders in {workspaceId ? 'this workspace' : 'your account'}. Create one
+ to get started.
)}
diff --git a/apps/sim/app/w/components/sidebar/components/help-modal/components/help-form/help-form.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/help-modal/components/help-form/help-form.tsx
similarity index 100%
rename from apps/sim/app/w/components/sidebar/components/help-modal/components/help-form/help-form.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/help-modal/components/help-form/help-form.tsx
diff --git a/apps/sim/app/w/components/sidebar/components/help-modal/help-modal.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/help-modal/help-modal.tsx
similarity index 100%
rename from apps/sim/app/w/components/sidebar/components/help-modal/help-modal.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/help-modal/help-modal.tsx
diff --git a/apps/sim/app/w/components/sidebar/components/invite-modal/invite-modal.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/invite-modal/invite-modal.tsx
similarity index 98%
rename from apps/sim/app/w/components/sidebar/components/invite-modal/invite-modal.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/invite-modal/invite-modal.tsx
index fd28d8d910f..ff51008450e 100644
--- a/apps/sim/app/w/components/sidebar/components/invite-modal/invite-modal.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/invite-modal/invite-modal.tsx
@@ -2,6 +2,7 @@
import React, { type KeyboardEvent, useCallback, useEffect, useMemo, useState } from 'react'
import { HelpCircle, Loader2, X } from 'lucide-react'
+import { useParams } from 'next/navigation'
import { Button } from '@/components/ui/button'
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'
import { Input } from '@/components/ui/input'
@@ -15,10 +16,9 @@ import { cn } from '@/lib/utils'
import {
useUserPermissionsContext,
useWorkspacePermissionsContext,
-} from '@/app/w/components/providers/workspace-permissions-provider'
+} from '@/app/workspace/[workspaceId]/w/components/providers/workspace-permissions-provider'
import type { WorkspacePermissions } from '@/hooks/use-workspace-permissions'
import { API_ENDPOINTS } from '@/stores/constants'
-import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
const logger = createLogger('InviteModal')
@@ -397,7 +397,9 @@ export function InviteModal({ open, onOpenChange }: InviteModalProps) {
const [showSent, setShowSent] = useState(false)
const [errorMessage, setErrorMessage] = useState
(null)
const [successMessage, setSuccessMessage] = useState(null)
- const { activeWorkspaceId } = useWorkflowRegistry()
+ const params = useParams()
+ const workspaceId = params.workspaceId as string
+
const { data: session } = useSession()
const {
workspacePermissions,
@@ -410,7 +412,7 @@ export function InviteModal({ open, onOpenChange }: InviteModalProps) {
const hasNewInvites = emails.length > 0 || inputValue.trim()
const fetchPendingInvitations = useCallback(async () => {
- if (!activeWorkspaceId) return
+ if (!workspaceId) return
setIsPendingInvitationsLoading(true)
try {
@@ -421,7 +423,7 @@ export function InviteModal({ open, onOpenChange }: InviteModalProps) {
data.invitations
?.filter(
(inv: PendingInvitation) =>
- inv.status === 'pending' && inv.workspaceId === activeWorkspaceId
+ inv.status === 'pending' && inv.workspaceId === workspaceId
)
.map((inv: PendingInvitation) => ({
email: inv.email,
@@ -436,10 +438,10 @@ export function InviteModal({ open, onOpenChange }: InviteModalProps) {
} finally {
setIsPendingInvitationsLoading(false)
}
- }, [activeWorkspaceId])
+ }, [workspaceId])
useEffect(() => {
- if (open && activeWorkspaceId) {
+ if (open && workspaceId) {
fetchPendingInvitations()
}
}, [open, fetchPendingInvitations])
@@ -535,7 +537,7 @@ export function InviteModal({ open, onOpenChange }: InviteModalProps) {
)
const handleSaveChanges = useCallback(async () => {
- if (!userPerms.canAdmin || !hasPendingChanges || !activeWorkspaceId) return
+ if (!userPerms.canAdmin || !hasPendingChanges || !workspaceId) return
setIsSaving(true)
setErrorMessage(null)
@@ -546,7 +548,7 @@ export function InviteModal({ open, onOpenChange }: InviteModalProps) {
permissions: changes.permissionType || 'read',
}))
- const response = await fetch(API_ENDPOINTS.WORKSPACE_PERMISSIONS(activeWorkspaceId), {
+ const response = await fetch(API_ENDPOINTS.WORKSPACE_PERMISSIONS(workspaceId), {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
@@ -583,7 +585,7 @@ export function InviteModal({ open, onOpenChange }: InviteModalProps) {
}, [
userPerms.canAdmin,
hasPendingChanges,
- activeWorkspaceId,
+ workspaceId,
existingUserPermissionChanges,
updatePermissions,
])
@@ -646,7 +648,7 @@ export function InviteModal({ open, onOpenChange }: InviteModalProps) {
setErrorMessage(null)
setSuccessMessage(null)
- if (emails.length === 0 || !activeWorkspaceId) {
+ if (emails.length === 0 || !workspaceId) {
return
}
@@ -667,7 +669,7 @@ export function InviteModal({ open, onOpenChange }: InviteModalProps) {
'Content-Type': 'application/json',
},
body: JSON.stringify({
- workspaceId: activeWorkspaceId,
+ workspaceId,
email: email,
role: 'member',
permission: permissionType,
@@ -739,7 +741,7 @@ export function InviteModal({ open, onOpenChange }: InviteModalProps) {
inputValue,
addEmail,
emails,
- activeWorkspaceId,
+ workspaceId,
userPermissions,
invalidEmails,
fetchPendingInvitations,
@@ -922,7 +924,7 @@ export function InviteModal({ open, onOpenChange }: InviteModalProps) {
!hasNewInvites ||
isSubmitting ||
isSaving ||
- !activeWorkspaceId
+ !workspaceId
}
className={cn(
'ml-auto gap-2 font-medium',
diff --git a/apps/sim/app/w/components/sidebar/components/invite-modal/invites-sent/invites-sent.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/invite-modal/invites-sent/invites-sent.tsx
similarity index 96%
rename from apps/sim/app/w/components/sidebar/components/invite-modal/invites-sent/invites-sent.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/invite-modal/invites-sent/invites-sent.tsx
index dc04a9e719c..12ff428a0f5 100644
--- a/apps/sim/app/w/components/sidebar/components/invite-modal/invites-sent/invites-sent.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/invite-modal/invites-sent/invites-sent.tsx
@@ -1,6 +1,7 @@
'use client'
import { useEffect, useState } from 'react'
+import { useParams } from 'next/navigation'
import { Skeleton } from '@/components/ui/skeleton'
import {
Table,
@@ -11,7 +12,6 @@ import {
TableRow,
} from '@/components/ui/table'
import { createLogger } from '@/lib/logs/console-logger'
-import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
const logger = createLogger('InvitesSent')
@@ -47,11 +47,12 @@ export function InvitesSent() {
const [invitations, setInvitations] = useState([])
const [isLoading, setIsLoading] = useState(true)
const [error, setError] = useState(null)
- const { activeWorkspaceId } = useWorkflowRegistry()
+ const params = useParams()
+ const workspaceId = params.workspaceId as string
useEffect(() => {
async function fetchInvitations() {
- if (!activeWorkspaceId) {
+ if (!workspaceId) {
setIsLoading(false)
return
}
@@ -82,7 +83,7 @@ export function InvitesSent() {
}
fetchInvitations()
- }, [activeWorkspaceId])
+ }, [workspaceId])
const TableSkeleton = () => (
@@ -106,7 +107,7 @@ export function InvitesSent() {
)
}
- if (!activeWorkspaceId) {
+ if (!workspaceId) {
return null
}
diff --git a/apps/sim/app/w/components/sidebar/components/nav-section/nav-section.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/nav-section/nav-section.tsx
similarity index 100%
rename from apps/sim/app/w/components/sidebar/components/nav-section/nav-section.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/nav-section/nav-section.tsx
diff --git a/apps/sim/app/w/components/sidebar/components/settings-modal/components/account/account.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/account/account.tsx
similarity index 100%
rename from apps/sim/app/w/components/sidebar/components/settings-modal/components/account/account.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/account/account.tsx
diff --git a/apps/sim/app/w/components/sidebar/components/settings-modal/components/api-keys/api-keys.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/api-keys/api-keys.tsx
similarity index 100%
rename from apps/sim/app/w/components/sidebar/components/settings-modal/components/api-keys/api-keys.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/api-keys/api-keys.tsx
diff --git a/apps/sim/app/w/components/sidebar/components/settings-modal/components/credentials/credentials.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/credentials/credentials.tsx
similarity index 99%
rename from apps/sim/app/w/components/sidebar/components/settings-modal/components/credentials/credentials.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/credentials/credentials.tsx
index da4faef5dc4..21ad99b186b 100644
--- a/apps/sim/app/w/components/sidebar/components/settings-modal/components/credentials/credentials.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/credentials/credentials.tsx
@@ -172,10 +172,10 @@ export function Credentials({ onOpenChange }: CredentialsProps) {
}
// Clear the URL parameters
- router.replace('/w')
+ router.replace('/workspace')
} else if (error) {
logger.error('OAuth error:', { error })
- router.replace('/w')
+ router.replace('/workspace')
}
}, [searchParams, router, userId])
diff --git a/apps/sim/app/w/components/sidebar/components/settings-modal/components/environment/environment.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/environment/environment.tsx
similarity index 100%
rename from apps/sim/app/w/components/sidebar/components/settings-modal/components/environment/environment.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/environment/environment.tsx
diff --git a/apps/sim/app/w/components/sidebar/components/settings-modal/components/general/general.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/general/general.tsx
similarity index 100%
rename from apps/sim/app/w/components/sidebar/components/settings-modal/components/general/general.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/general/general.tsx
diff --git a/apps/sim/app/w/components/sidebar/components/settings-modal/components/privacy/privacy.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/privacy/privacy.tsx
similarity index 100%
rename from apps/sim/app/w/components/sidebar/components/settings-modal/components/privacy/privacy.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/privacy/privacy.tsx
diff --git a/apps/sim/app/w/components/sidebar/components/settings-modal/components/settings-navigation/settings-navigation.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/settings-navigation/settings-navigation.tsx
similarity index 100%
rename from apps/sim/app/w/components/sidebar/components/settings-modal/components/settings-navigation/settings-navigation.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/settings-navigation/settings-navigation.tsx
diff --git a/apps/sim/app/w/components/sidebar/components/settings-modal/components/subscription/components/team-seats-dialog.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/subscription/components/team-seats-dialog.tsx
similarity index 100%
rename from apps/sim/app/w/components/sidebar/components/settings-modal/components/subscription/components/team-seats-dialog.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/subscription/components/team-seats-dialog.tsx
diff --git a/apps/sim/app/w/components/sidebar/components/settings-modal/components/subscription/subscription.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/subscription/subscription.tsx
similarity index 100%
rename from apps/sim/app/w/components/sidebar/components/settings-modal/components/subscription/subscription.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/subscription/subscription.tsx
diff --git a/apps/sim/app/w/components/sidebar/components/settings-modal/components/team-management/team-management.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/team-management/team-management.tsx
similarity index 100%
rename from apps/sim/app/w/components/sidebar/components/settings-modal/components/team-management/team-management.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/team-management/team-management.tsx
diff --git a/apps/sim/app/w/components/sidebar/components/settings-modal/settings-modal.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/settings-modal.tsx
similarity index 100%
rename from apps/sim/app/w/components/sidebar/components/settings-modal/settings-modal.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/settings-modal.tsx
diff --git a/apps/sim/app/w/components/sidebar/components/sidebar-control/sidebar-control.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/sidebar-control/sidebar-control.tsx
similarity index 100%
rename from apps/sim/app/w/components/sidebar/components/sidebar-control/sidebar-control.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/sidebar-control/sidebar-control.tsx
diff --git a/apps/sim/app/w/components/sidebar/components/workflow-list/workflow-list.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workflow-list/workflow-list.tsx
similarity index 87%
rename from apps/sim/app/w/components/sidebar/components/workflow-list/workflow-list.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workflow-list/workflow-list.tsx
index bf4e067eb8f..c54e7d73e94 100644
--- a/apps/sim/app/w/components/sidebar/components/workflow-list/workflow-list.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workflow-list/workflow-list.tsx
@@ -3,10 +3,9 @@
import { useMemo } from 'react'
import clsx from 'clsx'
import Link from 'next/link'
-import { usePathname } from 'next/navigation'
+import { useParams, usePathname } from 'next/navigation'
import { Skeleton } from '@/components/ui/skeleton'
import { useSession } from '@/lib/auth-client'
-import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
import type { WorkflowMetadata } from '@/stores/workflows/registry/types'
interface WorkflowItemProps {
@@ -17,9 +16,12 @@ interface WorkflowItemProps {
}
function WorkflowItem({ workflow, active, isMarketplace, isCollapsed }: WorkflowItemProps) {
+ const params = useParams()
+ const workspaceId = params.workspaceId as string
+
return (
))}
@@ -121,7 +124,7 @@ export function WorkflowList({
@@ -132,8 +135,8 @@ export function WorkflowList({
{/* Empty state */}
{showEmptyState && !isCollapsed && (
- No workflows in {activeWorkspaceId ? 'this workspace' : 'your account'}. Create one to
- get started.
+ No workflows in {workspaceId ? 'this workspace' : 'your account'}. Create one to get
+ started.
)}
>
diff --git a/apps/sim/app/w/components/sidebar/components/workspace-header/workspace-header.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workspace-header/workspace-header.tsx
similarity index 93%
rename from apps/sim/app/w/components/sidebar/components/workspace-header/workspace-header.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workspace-header/workspace-header.tsx
index 4f9351d0154..3d67c0087d6 100644
--- a/apps/sim/app/w/components/sidebar/components/workspace-header/workspace-header.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workspace-header/workspace-header.tsx
@@ -3,7 +3,7 @@
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import { ChevronDown, Pencil, Trash2, X } from 'lucide-react'
import Link from 'next/link'
-import { useRouter } from 'next/navigation'
+import { useParams, useRouter } from 'next/navigation'
import { AgentIcon } from '@/components/icons'
import {
AlertDialog,
@@ -28,11 +28,14 @@ import {
import { Input } from '@/components/ui/input'
import { Skeleton } from '@/components/ui/skeleton'
import { useSession } from '@/lib/auth-client'
+import { createLogger } from '@/lib/logs/console-logger'
import { cn } from '@/lib/utils'
-import { useUserPermissionsContext } from '@/app/w/components/providers/workspace-permissions-provider'
+import { useUserPermissionsContext } from '@/app/workspace/[workspaceId]/w/components/providers/workspace-permissions-provider'
import { useSidebarStore } from '@/stores/sidebar/store'
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
+const logger = createLogger('WorkspaceHeader')
+
interface Workspace {
id: string
name: string
@@ -254,7 +257,9 @@ export const WorkspaceHeader = React.memo
(
const router = useRouter()
// Get workflowRegistry state and actions
- const { activeWorkspaceId, switchToWorkspace, setActiveWorkspaceId } = useWorkflowRegistry()
+ const { switchToWorkspace } = useWorkflowRegistry()
+ const params = useParams()
+ const currentWorkspaceId = params.workspaceId as string
// Get user permissions for the active workspace
const userPermissions = useUserPermissionsContext()
@@ -275,7 +280,7 @@ export const WorkspaceHeader = React.memo(
const data = await response.json()
setPlan(data.isPro ? 'Pro Plan' : 'Free Plan')
} catch (err) {
- console.error('Error fetching subscription status:', err)
+ logger.error('Error fetching subscription status:', err)
}
}, [])
@@ -289,30 +294,36 @@ export const WorkspaceHeader = React.memo(
const fetchedWorkspaces = data.workspaces as Workspace[]
setWorkspaces(fetchedWorkspaces)
- // Only update workspace if we have a valid activeWorkspaceId from registry
- if (activeWorkspaceId) {
+ // Only update workspace if we have a valid currentWorkspaceId from URL
+ if (currentWorkspaceId) {
const matchingWorkspace = fetchedWorkspaces.find(
- (workspace) => workspace.id === activeWorkspaceId
+ (workspace) => workspace.id === currentWorkspaceId
)
if (matchingWorkspace) {
setActiveWorkspace(matchingWorkspace)
} else {
- // Active workspace not found, fallback to first workspace
- const fallbackWorkspace = fetchedWorkspaces[0]
- if (fallbackWorkspace) {
+ // Log the mismatch for debugging
+ logger.warn(`Workspace ${currentWorkspaceId} not found in user's workspaces`)
+
+ // Current workspace not found, fallback to first workspace
+ if (fetchedWorkspaces.length > 0) {
+ const fallbackWorkspace = fetchedWorkspaces[0]
setActiveWorkspace(fallbackWorkspace)
- setActiveWorkspaceId(fallbackWorkspace.id)
+ // Navigate to the fallback workspace
+ router.push(`/workspace/${fallbackWorkspace.id}/w`)
+ } else {
+ // No workspaces available - handle this edge case
+ logger.error('No workspaces available for user')
}
}
}
- // If no activeWorkspaceId, let loadWorkspaceFromWorkflowId handle workspace selection
}
} catch (err) {
- console.error('Error fetching workspaces:', err)
+ logger.error('Error fetching workspaces:', err)
} finally {
setIsWorkspacesLoading(false)
}
- }, [activeWorkspaceId, setActiveWorkspaceId])
+ }, [currentWorkspaceId, router])
useEffect(() => {
// Fetch subscription status if user is logged in
@@ -337,7 +348,7 @@ export const WorkspaceHeader = React.memo(
switchToWorkspace(workspace.id)
// Update URL to include workspace ID
- router.push(`/w/${workspace.id}`)
+ router.push(`/workspace/${workspace.id}/w`)
},
[activeWorkspace?.id, switchToWorkspace, router]
)
@@ -367,10 +378,10 @@ export const WorkspaceHeader = React.memo(
switchToWorkspace(newWorkspace.id)
// Update URL to include new workspace ID
- router.push(`/w/${newWorkspace.id}`)
+ router.push(`/workspace/${newWorkspace.id}/w`)
}
} catch (err) {
- console.error('Error creating workspace:', err)
+ logger.error('Error creating workspace:', err)
} finally {
setIsWorkspacesLoading(false)
}
@@ -396,7 +407,7 @@ export const WorkspaceHeader = React.memo(
if (!response.ok) {
if (response.status === 403) {
- console.error(
+ logger.error(
'Permission denied: Only users with admin permissions can update workspaces'
)
}
@@ -420,7 +431,7 @@ export const WorkspaceHeader = React.memo(
})
}
} catch (err) {
- console.error('Error updating workspace:', err)
+ logger.error('Error updating workspace:', err)
} finally {
setIsWorkspacesLoading(false)
}
@@ -442,7 +453,7 @@ export const WorkspaceHeader = React.memo(
if (!response.ok) {
if (response.status === 403) {
- console.error(
+ logger.error(
'Permission denied: Only users with admin permissions can delete workspaces'
)
}
@@ -463,7 +474,7 @@ export const WorkspaceHeader = React.memo(
setIsOpen(false)
} catch (err) {
- console.error('Error deleting workspace:', err)
+ logger.error('Error deleting workspace:', err)
} finally {
setIsDeleting(false)
}
@@ -486,7 +497,7 @@ export const WorkspaceHeader = React.memo(
// Determine URL for workspace links
const workspaceUrl = useMemo(
- () => (activeWorkspace ? `/w/${activeWorkspace.id}` : '/w'),
+ () => (activeWorkspace ? `/workspace/${activeWorkspace.id}/w` : '/workspace'),
[activeWorkspace]
)
diff --git a/apps/sim/app/w/components/sidebar/sidebar.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/sidebar.tsx
similarity index 91%
rename from apps/sim/app/w/components/sidebar/sidebar.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/sidebar/sidebar.tsx
index e8485572e82..f1557a64796 100644
--- a/apps/sim/app/w/components/sidebar/sidebar.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/sidebar.tsx
@@ -3,12 +3,15 @@
import { useEffect, useMemo, useState } from 'react'
import clsx from 'clsx'
import { HelpCircle, LibraryBig, ScrollText, Send, Settings } from 'lucide-react'
-import { usePathname, useRouter } from 'next/navigation'
+import { useParams, usePathname, useRouter } from 'next/navigation'
import { Skeleton } from '@/components/ui/skeleton'
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
import { useSession } from '@/lib/auth-client'
import { createLogger } from '@/lib/logs/console-logger'
-import { getKeyboardShortcutText, useGlobalShortcuts } from '@/app/w/hooks/use-keyboard-shortcuts'
+import {
+ getKeyboardShortcutText,
+ useGlobalShortcuts,
+} from '@/app/workspace/[workspaceId]/w/hooks/use-keyboard-shortcuts'
import { useSidebarStore } from '@/stores/sidebar/store'
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
import type { WorkflowMetadata } from '@/stores/workflows/registry/types'
@@ -31,16 +34,13 @@ export function Sidebar() {
useRegistryLoading()
useGlobalShortcuts()
- const {
- workflows,
- activeWorkspaceId,
- createWorkflow,
- isLoading: workflowsLoading,
- } = useWorkflowRegistry()
+ const { workflows, createWorkflow, isLoading: workflowsLoading } = useWorkflowRegistry()
const { isPending: sessionLoading } = useSession()
const userPermissions = useUserPermissionsContext()
const isLoading = workflowsLoading || sessionLoading
const router = useRouter()
+ const params = useParams()
+ const workspaceId = params.workspaceId as string
const pathname = usePathname()
const [showSettings, setShowSettings] = useState(false)
@@ -66,7 +66,7 @@ export function Sidebar() {
if (!isLoading) {
Object.values(workflows).forEach((workflow) => {
- if (workflow.workspaceId === activeWorkspaceId || !workflow.workspaceId) {
+ if (workflow.workspaceId === workspaceId || !workflow.workspaceId) {
if (workflow.marketplaceData?.status === 'temp') {
temp.push(workflow)
} else {
@@ -93,16 +93,16 @@ export function Sidebar() {
}
return { regularWorkflows: regular, tempWorkflows: temp }
- }, [workflows, isLoading, activeWorkspaceId])
+ }, [workflows, isLoading, workspaceId])
// Create workflow handler
const handleCreateWorkflow = async (folderId?: string) => {
try {
const id = await createWorkflow({
- workspaceId: activeWorkspaceId || undefined,
+ workspaceId: workspaceId || undefined,
folderId: folderId || undefined,
})
- router.push(`/w/${id}`)
+ router.push(`/workspace/${workspaceId}/w/${id}`)
} catch (error) {
logger.error('Error creating workflow:', error)
}
@@ -154,10 +154,10 @@ export function Sidebar() {
{/* Workflows Section */}
{isLoading ? : 'Workflows'}
@@ -179,18 +179,18 @@ export function Sidebar() {
}
- href='/w/logs'
+ href={`/workspace/${workspaceId}/logs`}
label='Logs'
- active={pathname === '/w/logs'}
+ active={pathname === `/workspace/${workspaceId}/logs`}
isCollapsed={isCollapsed}
shortcutCommand={getKeyboardShortcutText('L', true, true)}
shortcutCommandPosition='below'
/>
}
- href='/w/knowledge'
+ href={`/workspace/${workspaceId}/knowledge`}
label='Knowledge'
- active={pathname === '/w/knowledge'}
+ active={pathname === `/workspace/${workspaceId}/knowledge`}
isCollapsed={isCollapsed}
shortcutCommand={getKeyboardShortcutText('K', true, true)}
shortcutCommandPosition='below'
diff --git a/apps/sim/app/w/components/workflow-preview/workflow-preview.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/workflow-preview/workflow-preview.tsx
similarity index 93%
rename from apps/sim/app/w/components/workflow-preview/workflow-preview.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/components/workflow-preview/workflow-preview.tsx
index 79abac5ab47..ff6a7c2e97a 100644
--- a/apps/sim/app/w/components/workflow-preview/workflow-preview.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/components/workflow-preview/workflow-preview.tsx
@@ -15,10 +15,10 @@ import 'reactflow/dist/style.css'
import { createLogger } from '@/lib/logs/console-logger'
import { cn } from '@/lib/utils'
-import { LoopNodeComponent } from '@/app/w/[id]/components/loop-node/loop-node'
-import { ParallelNodeComponent } from '@/app/w/[id]/components/parallel-node/parallel-node'
-import { WorkflowBlock } from '@/app/w/[id]/components/workflow-block/workflow-block'
-import { WorkflowEdge } from '@/app/w/[id]/components/workflow-edge/workflow-edge'
+import { LoopNodeComponent } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/loop-node/loop-node'
+import { ParallelNodeComponent } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/parallel-node/parallel-node'
+import { WorkflowBlock } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/workflow-block'
+import { WorkflowEdge } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-edge/workflow-edge'
import { getBlock } from '@/blocks'
import type { WorkflowState } from '@/stores/workflows/workflow/types'
diff --git a/apps/sim/app/w/hooks/use-keyboard-shortcuts.ts b/apps/sim/app/workspace/[workspaceId]/w/hooks/use-keyboard-shortcuts.ts
similarity index 89%
rename from apps/sim/app/w/hooks/use-keyboard-shortcuts.ts
rename to apps/sim/app/workspace/[workspaceId]/w/hooks/use-keyboard-shortcuts.ts
index 9f49d8a1818..70d418eb620 100644
--- a/apps/sim/app/w/hooks/use-keyboard-shortcuts.ts
+++ b/apps/sim/app/workspace/[workspaceId]/w/hooks/use-keyboard-shortcuts.ts
@@ -95,7 +95,16 @@ export function useGlobalShortcuts() {
((isMac && event.metaKey) || (!isMac && event.ctrlKey))
) {
event.preventDefault()
- router.push('/w/logs')
+
+ const pathParts = window.location.pathname.split('/')
+ const workspaceIndex = pathParts.indexOf('workspace')
+
+ if (workspaceIndex !== -1 && pathParts[workspaceIndex + 1]) {
+ const workspaceId = pathParts[workspaceIndex + 1]
+ router.push(`/workspace/${workspaceId}/logs`)
+ } else {
+ router.push('/workspace')
+ }
}
}
diff --git a/apps/sim/app/w/hooks/use-registry-loading.ts b/apps/sim/app/workspace/[workspaceId]/w/hooks/use-registry-loading.ts
similarity index 69%
rename from apps/sim/app/w/hooks/use-registry-loading.ts
rename to apps/sim/app/workspace/[workspaceId]/w/hooks/use-registry-loading.ts
index 207514e18fd..239a7148dbe 100644
--- a/apps/sim/app/w/hooks/use-registry-loading.ts
+++ b/apps/sim/app/workspace/[workspaceId]/w/hooks/use-registry-loading.ts
@@ -1,7 +1,7 @@
'use client'
import { useEffect } from 'react'
-import { usePathname, useRouter } from 'next/navigation'
+import { useParams, usePathname, useRouter } from 'next/navigation'
import { createLogger } from '@/lib/logs/console-logger'
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
@@ -34,44 +34,41 @@ function extractWorkflowIdFromPathname(pathname: string): string | null {
* Custom hook to manage workflow registry loading state and handle first-time navigation
*
* This hook initializes the loading state and automatically clears it
- * when workflows are loaded. It also handles smart workspace selection
- * and navigation for first-time users.
+ * when workflows are loaded. It also handles navigation for first-time users.
*/
export function useRegistryLoading() {
- const { workflows, setLoading, isLoading, activeWorkspaceId, loadWorkspaceFromWorkflowId } =
- useWorkflowRegistry()
+ const { workflows, setLoading, isLoading, loadWorkflows } = useWorkflowRegistry()
const pathname = usePathname()
const router = useRouter()
+ const params = useParams()
+ const workspaceId = params.workspaceId as string
- // Handle workspace selection from URL
+ // Load workflows for current workspace
useEffect(() => {
- if (!activeWorkspaceId) {
- const workflowIdFromUrl = extractWorkflowIdFromPathname(pathname)
- if (workflowIdFromUrl) {
- loadWorkspaceFromWorkflowId(workflowIdFromUrl).catch((error) => {
- logger.warn('Failed to load workspace from workflow ID:', error)
- })
- }
+ if (workspaceId) {
+ loadWorkflows(workspaceId).catch((error) => {
+ logger.warn('Failed to load workflows for workspace:', error)
+ })
}
- }, [activeWorkspaceId, pathname, loadWorkspaceFromWorkflowId])
+ }, [workspaceId, loadWorkflows])
// Handle first-time navigation: if we're at /w and have workflows, navigate to first one
useEffect(() => {
- if (!isLoading && activeWorkspaceId && Object.keys(workflows).length > 0) {
- const workflowCount = Object.keys(workflows).length
+ if (!isLoading && workspaceId && Object.keys(workflows).length > 0) {
const currentWorkflowId = extractWorkflowIdFromPathname(pathname)
- // If we're at a generic workspace URL (/w, /w/, or /w/workspaceId) without a specific workflow
+ // Check if we're on the workspace root and need to redirect to first workflow
if (
- !currentWorkflowId &&
- (pathname === '/w' || pathname === '/w/' || pathname === `/w/${activeWorkspaceId}`)
+ (pathname === `/workspace/${workspaceId}/w` ||
+ pathname === `/workspace/${workspaceId}/w/`) &&
+ Object.keys(workflows).length > 0
) {
const firstWorkflowId = Object.keys(workflows)[0]
logger.info('First-time navigation: redirecting to first workflow:', firstWorkflowId)
- router.replace(`/w/${firstWorkflowId}`)
+ router.replace(`/workspace/${workspaceId}/w/${firstWorkflowId}`)
}
}
- }, [isLoading, activeWorkspaceId, workflows, pathname, router])
+ }, [isLoading, workspaceId, workflows, pathname, router])
// Handle loading states
useEffect(() => {
diff --git a/apps/sim/app/w/page.tsx b/apps/sim/app/workspace/[workspaceId]/w/page.tsx
similarity index 70%
rename from apps/sim/app/w/page.tsx
rename to apps/sim/app/workspace/[workspaceId]/w/page.tsx
index fea6f1d2df9..998bd9a27b8 100644
--- a/apps/sim/app/w/page.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/page.tsx
@@ -1,12 +1,15 @@
'use client'
import { useEffect } from 'react'
-import { useRouter } from 'next/navigation'
+import { useParams, useRouter } from 'next/navigation'
+import { LoadingAgent } from '@/components/ui/loading-agent'
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
export default function WorkflowsPage() {
const router = useRouter()
const { workflows, isLoading } = useWorkflowRegistry()
+ const params = useParams()
+ const workspaceId = params.workspaceId
useEffect(() => {
// Wait for workflows to load
@@ -16,7 +19,7 @@ export default function WorkflowsPage() {
// If we have workflows, redirect to the first one
if (workflowIds.length > 0) {
- router.replace(`/w/${workflowIds[0]}`)
+ router.replace(`/workspace/${workspaceId}/w/${workflowIds[0]}`)
return
}
@@ -24,14 +27,15 @@ export default function WorkflowsPage() {
// or the user doesn't have any workspaces. Redirect to home to let the system
// handle workspace/workflow creation properly.
router.replace('/')
- }, [workflows, isLoading, router])
+ }, [workflows, isLoading, router, workspaceId])
// Show loading state while determining where to redirect
return (
-
-
Loading workflows...
+
+
+
)
diff --git a/apps/sim/app/workspace/page.tsx b/apps/sim/app/workspace/page.tsx
new file mode 100644
index 00000000000..d6d6b54e62b
--- /dev/null
+++ b/apps/sim/app/workspace/page.tsx
@@ -0,0 +1,134 @@
+'use client'
+
+import { useEffect } from 'react'
+import { useRouter } from 'next/navigation'
+import { LoadingAgent } from '@/components/ui/loading-agent'
+import { useSession } from '@/lib/auth-client'
+import { createLogger } from '@/lib/logs/console-logger'
+
+const logger = createLogger('WorkspacePage')
+
+export default function WorkspacePage() {
+ const router = useRouter()
+ const { data: session, isPending } = useSession()
+
+ useEffect(() => {
+ const redirectToFirstWorkspace = async () => {
+ // Wait for session to load
+ if (isPending) {
+ return
+ }
+
+ // If user is not authenticated, redirect to login
+ if (!session?.user) {
+ logger.info('User not authenticated, redirecting to login')
+ router.replace('/login')
+ return
+ }
+
+ try {
+ // Check if we need to redirect a specific workflow from old URL format
+ const urlParams = new URLSearchParams(window.location.search)
+ const redirectWorkflowId = urlParams.get('redirect_workflow')
+
+ if (redirectWorkflowId) {
+ // Try to get the workspace for this workflow
+ try {
+ const workflowResponse = await fetch(`/api/workflows/${redirectWorkflowId}`)
+ if (workflowResponse.ok) {
+ const workflowData = await workflowResponse.json()
+ const workspaceId = workflowData.data?.workspaceId
+
+ if (workspaceId) {
+ logger.info(
+ `Redirecting workflow ${redirectWorkflowId} to workspace ${workspaceId}`
+ )
+ router.replace(`/workspace/${workspaceId}/w/${redirectWorkflowId}`)
+ return
+ }
+ }
+ } catch (error) {
+ logger.error('Error fetching workflow for redirect:', error)
+ }
+ }
+
+ // Fetch user's workspaces
+ const response = await fetch('/api/workspaces')
+
+ if (!response.ok) {
+ throw new Error('Failed to fetch workspaces')
+ }
+
+ const data = await response.json()
+ const workspaces = data.workspaces || []
+
+ if (workspaces.length === 0) {
+ logger.warn('No workspaces found for user, creating default workspace')
+
+ try {
+ const createResponse = await fetch('/api/workspaces', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({ name: 'My Workspace' }),
+ })
+
+ if (createResponse.ok) {
+ const createData = await createResponse.json()
+ const newWorkspace = createData.workspace
+
+ if (newWorkspace?.id) {
+ logger.info(`Created default workspace: ${newWorkspace.id}`)
+ router.replace(`/workspace/${newWorkspace.id}/w`)
+ return
+ }
+ }
+
+ logger.error('Failed to create default workspace')
+ } catch (createError) {
+ logger.error('Error creating default workspace:', createError)
+ }
+
+ // If we can't create a workspace, redirect to login to reset state
+ router.replace('/login')
+ return
+ }
+
+ // Get the first workspace (they should be ordered by most recent)
+ const firstWorkspace = workspaces[0]
+ logger.info(`Redirecting to first workspace: ${firstWorkspace.id}`)
+
+ // Redirect to the first workspace
+ router.replace(`/workspace/${firstWorkspace.id}/w`)
+ } catch (error) {
+ logger.error('Error fetching workspaces for redirect:', error)
+ // Don't redirect if there's an error - let the user stay on the page
+ }
+ }
+
+ // Only run this logic when we're at the root /workspace path
+ // If we're already in a specific workspace, the children components will handle it
+ if (typeof window !== 'undefined' && window.location.pathname === '/workspace') {
+ redirectToFirstWorkspace()
+ }
+ }, [session, isPending, router])
+
+ // Show loading state while we determine where to redirect
+ if (isPending) {
+ return (
+
+ )
+ }
+
+ // If user is not authenticated, show nothing (redirect will happen)
+ if (!session?.user) {
+ return null
+ }
+
+ return null
+}
diff --git a/apps/sim/components/ui/loading-agent.tsx b/apps/sim/components/ui/loading-agent.tsx
index 582d2ae609f..5f87b57f17d 100644
--- a/apps/sim/components/ui/loading-agent.tsx
+++ b/apps/sim/components/ui/loading-agent.tsx
@@ -11,7 +11,6 @@ export interface LoadingAgentProps {
export function LoadingAgent({ size = 'md' }: LoadingAgentProps) {
const pathLength = 120
- // Size mappings for width and height
const sizes = {
sm: { width: 16, height: 18 },
md: { width: 21, height: 24 },
diff --git a/apps/sim/components/ui/tag-dropdown.tsx b/apps/sim/components/ui/tag-dropdown.tsx
index 78c9bf0a146..cb3c15b9f00 100644
--- a/apps/sim/components/ui/tag-dropdown.tsx
+++ b/apps/sim/components/ui/tag-dropdown.tsx
@@ -2,7 +2,10 @@ import type React from 'react'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { createLogger } from '@/lib/logs/console-logger'
import { cn } from '@/lib/utils'
-import { type ConnectedBlock, useBlockConnections } from '@/app/w/[id]/hooks/use-block-connections'
+import {
+ type ConnectedBlock,
+ useBlockConnections,
+} from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-block-connections'
import { getBlock } from '@/blocks'
import { useVariablesStore } from '@/stores/panel/variables/store'
import type { Variable } from '@/stores/panel/variables/types'
diff --git a/apps/sim/hooks/use-workspace-permissions.ts b/apps/sim/hooks/use-workspace-permissions.ts
index fb5ec21ba67..c4b4941ea60 100644
--- a/apps/sim/hooks/use-workspace-permissions.ts
+++ b/apps/sim/hooks/use-workspace-permissions.ts
@@ -5,7 +5,6 @@ import { API_ENDPOINTS } from '@/stores/constants'
const logger = createLogger('useWorkspacePermissions')
-// Use the enum from the database schema for type safety
export type PermissionType = (typeof permissionTypeEnum.enumValues)[number]
export interface WorkspaceUser {
diff --git a/apps/sim/lib/logs/trace-spans.ts b/apps/sim/lib/logs/trace-spans.ts
index eed9418a59f..02ef418f954 100644
--- a/apps/sim/lib/logs/trace-spans.ts
+++ b/apps/sim/lib/logs/trace-spans.ts
@@ -1,4 +1,4 @@
-import type { TraceSpan } from '@/app/w/logs/stores/types'
+import type { TraceSpan } from '@/app/workspace/[workspaceId]/logs/stores/types'
import type { ExecutionResult } from '@/executor/types'
// Helper function to build a tree of trace spans from execution logs
diff --git a/apps/sim/middleware.ts b/apps/sim/middleware.ts
index 6e958c91d16..286620c31b1 100644
--- a/apps/sim/middleware.ts
+++ b/apps/sim/middleware.ts
@@ -44,13 +44,24 @@ export async function middleware(request: NextRequest) {
return NextResponse.rewrite(new URL(`/chat/${subdomain}${url.pathname}`, request.url))
}
- // Check if the path is exactly /w
- if (url.pathname === '/w') {
- return NextResponse.redirect(new URL('/w/1', request.url))
+ // Legacy redirect: /w -> /workspace (will be handled by workspace layout)
+ if (url.pathname === '/w' || url.pathname.startsWith('/w/')) {
+ // Extract workflow ID if present
+ const pathParts = url.pathname.split('/')
+ if (pathParts.length >= 3 && pathParts[1] === 'w') {
+ const workflowId = pathParts[2]
+ // Redirect old workflow URLs to new format
+ // We'll need to resolve the workspace ID for this workflow
+ return NextResponse.redirect(
+ new URL(`/workspace?redirect_workflow=${workflowId}`, request.url)
+ )
+ }
+ // Simple /w redirect to workspace root
+ return NextResponse.redirect(new URL('/workspace', request.url))
}
// Handle protected routes that require authentication
- if (url.pathname.startsWith('/w/') || url.pathname === '/w') {
+ if (url.pathname.startsWith('/workspace')) {
if (!hasActiveSession) {
return NextResponse.redirect(new URL('/login', request.url))
}
@@ -137,8 +148,9 @@ export async function middleware(request: NextRequest) {
// Update matcher to include invitation routes
export const config = {
matcher: [
- '/w', // Match exactly /w
- '/w/:path*', // Match protected routes
+ '/w', // Legacy /w redirect
+ '/w/:path*', // Legacy /w/* redirects
+ '/workspace/:path*', // New workspace routes
'/login',
'/signup',
'/invite/:path*', // Match invitation routes
diff --git a/apps/sim/stores/folders/store.ts b/apps/sim/stores/folders/store.ts
index efa25f2ef79..57ad937eb4f 100644
--- a/apps/sim/stores/folders/store.ts
+++ b/apps/sim/stores/folders/store.ts
@@ -71,7 +71,7 @@ interface FolderState {
color?: string
}) => Promise
updateFolderAPI: (id: string, updates: Partial) => Promise
- deleteFolder: (id: string) => Promise
+ deleteFolder: (id: string, workspaceId: string) => Promise
// Helper functions
isWorkflowInDeletedSubfolder: (workflow: Workflow, deletedFolderId: string) => boolean
@@ -304,7 +304,7 @@ export const useFolderStore = create()(
return processedFolder
},
- deleteFolder: async (id: string) => {
+ deleteFolder: async (id: string, workspaceId: string) => {
const response = await fetch(`/api/folders/${id}`, { method: 'DELETE' })
if (!response.ok) {
@@ -346,9 +346,9 @@ export const useFolderStore = create()(
}
}
- if (workflowRegistry.activeWorkspaceId) {
+ if (workspaceId) {
// Trigger workflow refresh through registry store
- await workflowRegistry.switchToWorkspace(workflowRegistry.activeWorkspaceId)
+ await workflowRegistry.switchToWorkspace(workspaceId)
}
},
diff --git a/apps/sim/stores/index.ts b/apps/sim/stores/index.ts
index 347685dce12..8c265e03452 100644
--- a/apps/sim/stores/index.ts
+++ b/apps/sim/stores/index.ts
@@ -9,7 +9,6 @@ import { useNotificationStore } from './notifications/store'
import { useConsoleStore } from './panel/console/store'
import { useVariablesStore } from './panel/variables/store'
import { useEnvironmentStore } from './settings/environment/store'
-// Removed sync system imports - Socket.IO handles real-time sync
import { useWorkflowRegistry } from './workflows/registry/store'
import { useSubBlockStore } from './workflows/subblock/store'
import { useWorkflowStore } from './workflows/workflow/store'
@@ -41,12 +40,6 @@ async function initializeApplication(): Promise {
// Load custom tools from server
await useCustomToolsStore.getState().loadCustomTools()
- // Extract workflow ID from URL for smart workspace selection
- const workflowIdFromUrl = extractWorkflowIdFromUrl()
-
- // Load workspace based on workflow ID in URL, with fallback to last active workspace
- await useWorkflowRegistry.getState().loadWorkspaceFromWorkflowId(workflowIdFromUrl)
-
// Load workflows from database (replaced sync system)
await useWorkflowRegistry.getState().loadWorkflows()
diff --git a/apps/sim/stores/workflows/index.ts b/apps/sim/stores/workflows/index.ts
index 161957de7c7..5fe909c51f6 100644
--- a/apps/sim/stores/workflows/index.ts
+++ b/apps/sim/stores/workflows/index.ts
@@ -88,7 +88,7 @@ export function getBlockWithValues(blockId: string): BlockState | null {
* @returns An object containing workflows, with state only for the active workflow
*/
export function getAllWorkflowsWithValues() {
- const { workflows, activeWorkspaceId } = useWorkflowRegistry.getState()
+ const { workflows } = useWorkflowRegistry.getState()
const result: Record = {}
const activeWorkflowId = useWorkflowRegistry.getState().activeWorkflowId
const currentState = useWorkflowStore.getState()
@@ -97,14 +97,6 @@ export function getAllWorkflowsWithValues() {
if (activeWorkflowId && workflows[activeWorkflowId]) {
const metadata = workflows[activeWorkflowId]
- // Skip if workflow doesn't belong to the active workspace
- if (activeWorkspaceId && metadata.workspaceId !== activeWorkspaceId) {
- logger.debug(
- `Skipping active workflow ${activeWorkflowId} - belongs to workspace ${metadata.workspaceId}, not active workspace ${activeWorkspaceId}`
- )
- return result
- }
-
// Get deployment status from registry
const deploymentStatus = useWorkflowRegistry
.getState()
@@ -157,17 +149,10 @@ export function getAllWorkflowsWithValues() {
return result
}
-// Removed syncWorkflows - Socket.IO handles real-time sync automatically
-
-// Workflows store exports - localStorage persistence removed
-
export { useWorkflowRegistry } from './registry/store'
export type { WorkflowMetadata } from './registry/types'
export { useSubBlockStore } from './subblock/store'
export type { SubBlockStore } from './subblock/types'
-// Re-export utilities
export { mergeSubblockState } from './utils'
-// Re-export store hooks
export { useWorkflowStore } from './workflow/store'
-// Re-export types
export type { WorkflowState } from './workflow/types'
diff --git a/apps/sim/stores/workflows/registry/store.ts b/apps/sim/stores/workflows/registry/store.ts
index 0ce08f959d5..4968c2dac29 100644
--- a/apps/sim/stores/workflows/registry/store.ts
+++ b/apps/sim/stores/workflows/registry/store.ts
@@ -4,7 +4,6 @@ import { createLogger } from '@/lib/logs/console-logger'
import { clearWorkflowVariablesTracking } from '@/stores/panel/variables/store'
import { API_ENDPOINTS } from '../../constants'
import { useSubBlockStore } from '../subblock/store'
-// Removed fetchWorkflowsFromDB import - moved to local function
import { useWorkflowStore } from '../workflow/store'
import type { BlockState } from '../workflow/types'
import type { DeploymentStatus, WorkflowMetadata, WorkflowRegistry } from './types'
@@ -12,11 +11,10 @@ import { generateUniqueName, getNextWorkflowColor } from './utils'
const logger = createLogger('WorkflowRegistry')
-// Simplified function to fetch workflows from DB (moved from sync.ts)
let isFetching = false
let lastFetchTimestamp = 0
-async function fetchWorkflowsFromDB(): Promise {
+async function fetchWorkflowsFromDB(workspaceId?: string): Promise {
if (typeof window === 'undefined') return
// Prevent concurrent fetch operations
@@ -31,11 +29,10 @@ async function fetchWorkflowsFromDB(): Promise {
try {
useWorkflowRegistry.getState().setLoading(true)
- const activeWorkspaceId = useWorkflowRegistry.getState().activeWorkspaceId
const url = new URL(API_ENDPOINTS.SYNC, window.location.origin)
- if (activeWorkspaceId) {
- url.searchParams.append('workspaceId', activeWorkspaceId)
+ if (workspaceId) {
+ url.searchParams.append('workspaceId', workspaceId)
}
const response = await fetch(url.toString(), { method: 'GET' })
@@ -99,10 +96,7 @@ async function fetchWorkflowsFromDB(): Promise {
apiKey,
} = workflow
- // Skip if workflow doesn't belong to active workspace
- if (activeWorkspaceId && workspaceId !== activeWorkspaceId) {
- return
- }
+ // No need to filter by workspace since we're already fetching for specific workspace
// Add to registry
registryWorkflows[id] = {
@@ -256,7 +250,6 @@ export const useWorkflowRegistry = create()(
// Store state
workflows: {},
activeWorkflowId: null,
- activeWorkspaceId: null, // No longer persisted in localStorage
isLoading: true,
error: null,
// Initialize deployment statuses
@@ -270,24 +263,17 @@ export const useWorkflowRegistry = create()(
},
// Simple method to load workflows (replaces sync system)
- loadWorkflows: async () => {
- await fetchWorkflowsFromDB()
+ loadWorkflows: async (workspaceId?: string) => {
+ await fetchWorkflowsFromDB(workspaceId)
},
// Handle cleanup on workspace deletion
handleWorkspaceDeletion: async (newWorkspaceId: string) => {
- const currentWorkspaceId = get().activeWorkspaceId
-
- if (!newWorkspaceId || newWorkspaceId === currentWorkspaceId) {
- logger.error('Cannot switch to invalid workspace after deletion')
- return
- }
-
// Set transition state
setWorkspaceTransitioning(true)
try {
- logger.info(`Switching from deleted workspace ${currentWorkspaceId} to ${newWorkspaceId}`)
+ logger.info(`Switching to new workspace after deletion: ${newWorkspaceId}`)
// Reset all workflow state
resetWorkflowStores()
@@ -296,12 +282,11 @@ export const useWorkflowRegistry = create()(
set({
isLoading: true,
workflows: {},
- activeWorkspaceId: newWorkspaceId,
activeWorkflowId: null,
})
// Properly await workflow fetching to prevent race conditions
- await fetchWorkflowsFromDB()
+ await fetchWorkflowsFromDB(newWorkspaceId)
set({ isLoading: false })
logger.info(`Successfully switched to workspace after deletion: ${newWorkspaceId}`)
@@ -327,29 +312,17 @@ export const useWorkflowRegistry = create()(
return
}
- const { activeWorkspaceId: currentWorkspaceId } = get()
-
- // Early return if switching to the same workspace (before setting flag)
- if (currentWorkspaceId === workspaceId) {
- logger.info(`Already in workspace ${workspaceId}`)
- return
- }
-
- // Only set transition flag AFTER validating the switch is needed
+ // Set transition flag
setWorkspaceTransitioning(true)
try {
- logger.info(`Switching workspace from ${currentWorkspaceId || 'none'} to ${workspaceId}`)
-
- // Save to localStorage first before any async operations
- get().setActiveWorkspaceId(workspaceId)
+ logger.info(`Switching to workspace: ${workspaceId}`)
// Clear current workspace state
resetWorkflowStores()
- // Update workspace in state
+ // Update state
set({
- activeWorkspaceId: workspaceId,
activeWorkflowId: null,
workflows: {},
isLoading: true,
@@ -357,7 +330,7 @@ export const useWorkflowRegistry = create()(
})
// Fetch workflows for the new workspace
- await fetchWorkflowsFromDB()
+ await fetchWorkflowsFromDB(workspaceId)
logger.info(`Successfully switched to workspace: ${workspaceId}`)
} catch (error) {
@@ -371,128 +344,6 @@ export const useWorkflowRegistry = create()(
}
},
- // Load user's last active workspace from localStorage
- loadLastActiveWorkspace: async () => {
- try {
- const savedWorkspaceId = localStorage.getItem('lastActiveWorkspaceId')
- if (!savedWorkspaceId || savedWorkspaceId === get().activeWorkspaceId) {
- return // No saved workspace or already active
- }
-
- logger.info(`Attempting to restore last active workspace: ${savedWorkspaceId}`)
-
- // Validate that the workspace exists by making a simple API call
- try {
- const response = await fetch('/api/workspaces')
- if (response.ok) {
- const data = await response.json()
- const workspaces = data.workspaces || []
- const workspaceExists = workspaces.some((ws: any) => ws.id === savedWorkspaceId)
-
- if (workspaceExists) {
- // Set the validated workspace ID
- set({ activeWorkspaceId: savedWorkspaceId })
- logger.info(`Restored last active workspace from localStorage: ${savedWorkspaceId}`)
- } else {
- logger.warn(
- `Saved workspace ${savedWorkspaceId} no longer exists, clearing from localStorage`
- )
- localStorage.removeItem('lastActiveWorkspaceId')
- }
- }
- } catch (apiError) {
- logger.warn('Failed to validate saved workspace, will use default:', apiError)
- // Don't remove from localStorage in case it's a temporary network issue
- }
- } catch (error) {
- logger.warn('Failed to load last active workspace from localStorage:', error)
- // This is non-critical, so we continue with default behavior
- }
- },
-
- // Load workspace based on workflow ID from URL, with fallback to last active workspace
- loadWorkspaceFromWorkflowId: async (workflowId: string | null) => {
- try {
- logger.info(`Loading workspace for workflow ID: ${workflowId}`)
-
- // If workflow ID provided, try to get its workspace
- if (workflowId) {
- try {
- const response = await fetch(`/api/workflows/${workflowId}`)
- if (response.ok) {
- const data = await response.json()
- const workflow = data.data
-
- if (workflow?.workspaceId) {
- // Validate workspace access
- const workspacesResponse = await fetch('/api/workspaces')
- if (workspacesResponse.ok) {
- const workspacesData = await workspacesResponse.json()
- const workspaces = workspacesData.workspaces || []
- const workspaceExists = workspaces.some(
- (ws: any) => ws.id === workflow.workspaceId
- )
-
- if (workspaceExists) {
- set({ activeWorkspaceId: workflow.workspaceId })
- localStorage.setItem('lastActiveWorkspaceId', workflow.workspaceId)
- logger.info(`Set active workspace from workflow: ${workflow.workspaceId}`)
- return
- }
- }
- }
- }
- } catch (error) {
- logger.warn('Error fetching workflow:', error)
- }
- }
-
- // Fallback: use last active workspace or first available
- const savedWorkspaceId = localStorage.getItem('lastActiveWorkspaceId')
- const response = await fetch('/api/workspaces')
-
- if (response.ok) {
- const data = await response.json()
- const workspaces = data.workspaces || []
-
- if (workspaces.length === 0) {
- logger.warn('No workspaces found')
- return
- }
-
- // Try saved workspace first
- let targetWorkspace = savedWorkspaceId
- ? workspaces.find((ws: any) => ws.id === savedWorkspaceId)
- : null
-
- // Fall back to first workspace
- if (!targetWorkspace) {
- targetWorkspace = workspaces[0]
- if (savedWorkspaceId) {
- localStorage.removeItem('lastActiveWorkspaceId')
- }
- }
-
- set({ activeWorkspaceId: targetWorkspace.id })
- localStorage.setItem('lastActiveWorkspaceId', targetWorkspace.id)
- logger.info(`Set active workspace: ${targetWorkspace.id}`)
- }
- } catch (error) {
- logger.error('Error in loadWorkspaceFromWorkflowId:', error)
- }
- },
-
- // Simple method to set active workspace ID without triggering full switch
- setActiveWorkspaceId: (id: string) => {
- set({ activeWorkspaceId: id })
- // Save to localStorage as well
- try {
- localStorage.setItem('lastActiveWorkspaceId', id)
- } catch (error) {
- logger.warn('Failed to save workspace to localStorage:', error)
- }
- },
-
// Method to get deployment status for a specific workflow
getWorkflowDeploymentStatus: (workflowId: string | null): DeploymentStatus | null => {
if (!workflowId) {
@@ -735,14 +586,19 @@ export const useWorkflowRegistry = create()(
* @returns The ID of the newly created workflow
*/
createWorkflow: async (options = {}) => {
- const { workflows, activeWorkspaceId } = get()
+ const { workflows } = get()
const id = crypto.randomUUID()
- // Use provided workspace ID or fall back to active workspace ID
- const workspaceId = options.workspaceId || activeWorkspaceId || undefined
+ // Use provided workspace ID (must be provided since we no longer track active workspace)
+ const workspaceId = options.workspaceId
- logger.info(`Creating new workflow in workspace: ${workspaceId || 'none'}`)
+ if (!workspaceId) {
+ logger.error('Cannot create workflow without workspaceId')
+ set({ error: 'Workspace ID is required to create a workflow' })
+ throw new Error('Workspace ID is required to create a workflow')
+ }
+ logger.info(`Creating new workflow in workspace: ${workspaceId || 'none'}`)
// Generate workflow metadata with appropriate name and color
const newWorkflow: WorkflowMetadata = {
id,
@@ -1153,7 +1009,7 @@ export const useWorkflowRegistry = create()(
* Duplicates an existing workflow
*/
duplicateWorkflow: async (sourceId: string) => {
- const { workflows, activeWorkspaceId } = get()
+ const { workflows } = get()
const sourceWorkflow = workflows[sourceId]
if (!sourceWorkflow) {
@@ -1161,8 +1017,8 @@ export const useWorkflowRegistry = create()(
return null
}
- // Get the workspace ID from the source workflow or fall back to active workspace
- const workspaceId = sourceWorkflow.workspaceId || activeWorkspaceId || undefined
+ // Get the workspace ID from the source workflow (required)
+ const workspaceId = sourceWorkflow.workspaceId
// Call the server to duplicate the workflow - server generates all IDs
let duplicatedWorkflow
@@ -1594,7 +1450,6 @@ export const useWorkflowRegistry = create()(
set({
workflows: {},
activeWorkflowId: null,
- activeWorkspaceId: null,
isLoading: true,
error: null,
})
diff --git a/apps/sim/stores/workflows/registry/types.ts b/apps/sim/stores/workflows/registry/types.ts
index efc854b835b..5e9234b28bb 100644
--- a/apps/sim/stores/workflows/registry/types.ts
+++ b/apps/sim/stores/workflows/registry/types.ts
@@ -24,7 +24,6 @@ export interface WorkflowMetadata {
export interface WorkflowRegistryState {
workflows: Record
activeWorkflowId: string | null
- activeWorkspaceId: string | null
isLoading: boolean
error: string | null
deploymentStatuses: Record
@@ -34,10 +33,7 @@ export interface WorkflowRegistryActions {
setLoading: (loading: boolean) => void
setActiveWorkflow: (id: string) => Promise
switchToWorkspace: (id: string) => void
- setActiveWorkspaceId: (id: string) => void
- loadLastActiveWorkspace: () => Promise
- loadWorkspaceFromWorkflowId: (workflowId: string | null) => Promise
- loadWorkflows: () => Promise
+ loadWorkflows: (workspaceId?: string) => Promise
handleWorkspaceDeletion: (newWorkspaceId: string) => void
removeWorkflow: (id: string) => Promise
updateWorkflow: (id: string, metadata: Partial) => Promise
diff --git a/apps/sim/stores/workflows/workflow/types.ts b/apps/sim/stores/workflows/workflow/types.ts
index 3ad2725f0cd..65ef3624515 100644
--- a/apps/sim/stores/workflows/workflow/types.ts
+++ b/apps/sim/stores/workflows/workflow/types.ts
@@ -2,24 +2,17 @@ import type { Edge } from 'reactflow'
import type { BlockOutput, SubBlockType } from '@/blocks/types'
import type { DeploymentStatus } from '../registry/types'
-// Centralized subflow type system - easy to extend without database changes
export const SUBFLOW_TYPES = {
LOOP: 'loop',
PARALLEL: 'parallel',
- // Future types can be added here:
- // CONDITIONAL: 'conditional',
- // RETRY: 'retry',
- // BATCH: 'batch',
} as const
export type SubflowType = (typeof SUBFLOW_TYPES)[keyof typeof SUBFLOW_TYPES]
-// Type guard for runtime validation
export function isValidSubflowType(type: string): type is SubflowType {
return Object.values(SUBFLOW_TYPES).includes(type as SubflowType)
}
-// Subflow configuration interfaces
export interface LoopConfig {
nodes: string[]
iterations: number