diff --git a/docker-compose-local.yaml b/docker-compose-local.yaml new file mode 100644 index 0000000..1145451 --- /dev/null +++ b/docker-compose-local.yaml @@ -0,0 +1,47 @@ +services: + postgres: + image: postgres:17 + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: postgres + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + ports: + - "5432:5432" + volumes: + - postgres_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 3s + timeout: 3s + retries: 10 + networks: + - app-network + + redis: + image: redis:7 + ports: + - "6379:6379" + command: > + --requirepass redissecret + volumes: + - redis_data:/data + healthcheck: + test: ["CMD", "redis-cli", "-a", "redissecret", "ping"] + interval: 3s + timeout: 10s + retries: 10 + networks: + - app-network + +volumes: + postgres_data: + redis_data: + +networks: + app-network: + driver: bridge diff --git a/docker-compose.yaml b/docker-compose.yaml index 223b6be..2182153 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -83,8 +83,6 @@ services: MINIO_BUCKET: "voice-audio" MINIO_SECURE: "false" - MPS_API_URL: "https://dograh.a.pinggy.link" - # Langfuse ENABLE_TRACING: "false" # LANGFUSE_SECRET_KEY: "" diff --git a/ui/src/app/create-workflow/page.tsx b/ui/src/app/create-workflow/page.tsx index ed5b53e..e043459 100644 --- a/ui/src/app/create-workflow/page.tsx +++ b/ui/src/app/create-workflow/page.tsx @@ -6,6 +6,14 @@ import { useState } from 'react'; import { createWorkflowFromTemplateApiV1WorkflowCreateTemplatePost } from '@/client/sdk.gen'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardDescription, CardHeader } from '@/components/ui/card'; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from '@/components/ui/dialog'; import { Input } from '@/components/ui/input'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { useAuth } from '@/lib/auth'; @@ -16,6 +24,8 @@ export default function CreateWorkflowPage() { const { user, getAccessToken } = useAuth(); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); + const [showSuccessModal, setShowSuccessModal] = useState(false); + const [workflowId, setWorkflowId] = useState(null); const [callType, setCallType] = useState<'INBOUND' | 'OUTBOUND'>('INBOUND'); const [useCase, setUseCase] = useState(''); @@ -51,7 +61,8 @@ export default function CreateWorkflowPage() { }); if (response.data?.id) { - router.push(`/workflow/${response.data.id}`); + setWorkflowId(String(response.data.id)); + setShowSuccessModal(true); } } catch (err) { setError('Failed to create workflow. Please try again.'); @@ -61,6 +72,12 @@ export default function CreateWorkflowPage() { } }; + const handleModalContinue = () => { + if (workflowId) { + router.push(`/workflow/${workflowId}`); + } + }; + return (
@@ -165,6 +182,79 @@ export default function CreateWorkflowPage() {
+ + {/* Loading Overlay */} + {isLoading && ( +
+ +
+ {/* Animated spinner */} +
+
+
+
+
+ +
+

+ Creating Your Workflow +

+

+ We're setting up your voice agent with your specifications. This will just take a moment... +

+
+ + {/* Animated dots */} +
+
+
+
+
+
+
+
+ )} + + {/* Success Modal */} + + + + + + + + Workflow Created Successfully! + + +
+

+ A starter template has been generated for your use case, with some randomised data and sample actions. +

+

+ The voice bot is pre-set to communicate in English with an American accent. +

+

+ You're encouraged to first test the bot and then modify it to your specific requirements and location (currency/accent etc). +

+

+ Feel free to join our Slack channel for any queries and star us on GitHub. +

+
+
+
+ + + +
+
); } diff --git a/ui/src/app/globals.css b/ui/src/app/globals.css index cbce9b1..679436e 100644 --- a/ui/src/app/globals.css +++ b/ui/src/app/globals.css @@ -123,3 +123,16 @@ } } +@keyframes spin-slow { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +.animate-spin-slow { + animation: spin-slow 3s linear infinite; +} + diff --git a/ui/src/app/workflow/[workflowId]/components/WorkflowHeader.tsx b/ui/src/app/workflow/[workflowId]/components/WorkflowHeader.tsx index 7320e63..b766f5e 100644 --- a/ui/src/app/workflow/[workflowId]/components/WorkflowHeader.tsx +++ b/ui/src/app/workflow/[workflowId]/components/WorkflowHeader.tsx @@ -67,6 +67,7 @@ const WorkflowHeader = ({ isDirty, workflowName, rfInstance, onRun, workflowId, const { user, getAccessToken } = useAuth(); const hasValidationErrors = workflowValidationErrors.length > 0; + const isOSSDeployment = process.env.NEXT_PUBLIC_DEPLOYMENT_MODE === 'oss'; // Reset call-related state whenever the dialog is closed so that a new call can be placed useEffect(() => { @@ -195,15 +196,17 @@ const WorkflowHeader = ({ isDirty, workflowName, rfInstance, onRun, workflowId, Web Call - + {!isOSSDeployment && ( + + )} {isDirty ? (