diff --git a/typescript-sdk/apps/dojo/scripts/run-dojo-everything.js b/typescript-sdk/apps/dojo/scripts/run-dojo-everything.js index d93ba15fa..90d76e615 100755 --- a/typescript-sdk/apps/dojo/scripts/run-dojo-everything.js +++ b/typescript-sdk/apps/dojo/scripts/run-dojo-everything.js @@ -126,6 +126,7 @@ const dojo = { LLAMA_INDEX_URL: 'http://localhost:8007', MASTRA_URL: 'http://localhost:8008', PYDANTIC_AI_URL: 'http://localhost:8009', + NEXT_PUBLIC_CUSTOM_DOMAIN_TITLE: 'cpkdojo.local___CopilotKit Feature Viewer', } } diff --git a/typescript-sdk/apps/dojo/src/components/layout/main-layout.tsx b/typescript-sdk/apps/dojo/src/components/layout/main-layout.tsx index 3173ecc10..9706452ce 100644 --- a/typescript-sdk/apps/dojo/src/components/layout/main-layout.tsx +++ b/typescript-sdk/apps/dojo/src/components/layout/main-layout.tsx @@ -7,6 +7,7 @@ import { Menu, X } from "lucide-react"; import { Button } from "@/components/ui/button"; import { useURLParams } from "@/contexts/url-params-context"; +import { getTitleForCurrentDomain } from "@/utils/domain-config"; export function MainLayout({ children }: { children: React.ReactNode }) { const [isMobileSidebarOpen, setIsMobileSidebarOpen] = useState(false); @@ -52,7 +53,7 @@ export function MainLayout({ children }: { children: React.ReactNode }) { > {isMobileSidebarOpen ? : } -

AG-UI Dojo

+

{getTitleForCurrentDomain() || "AG-UI Dojo"}

{/* Spacer for centering */}
@@ -100,8 +101,8 @@ function MaybeSidebar({ isMobile, isMobileSidebarOpen, onMobileClose }: MaybeSid return (
diff --git a/typescript-sdk/apps/dojo/src/components/sidebar/sidebar.tsx b/typescript-sdk/apps/dojo/src/components/sidebar/sidebar.tsx index 7743e593f..aef8940df 100644 --- a/typescript-sdk/apps/dojo/src/components/sidebar/sidebar.tsx +++ b/typescript-sdk/apps/dojo/src/components/sidebar/sidebar.tsx @@ -19,6 +19,7 @@ import { menuIntegrations } from "@/menu"; import { Feature } from "@/types/integration"; import { useURLParams } from "@/contexts/url-params-context"; import { View } from "@/types/interface"; +import { getTitleForCurrentDomain } from "@/utils/domain-config"; interface SidebarProps { isMobile?: boolean; @@ -28,7 +29,7 @@ interface SidebarProps { export function Sidebar({ isMobile, onMobileClose }: SidebarProps) { const router = useRouter(); const pathname = usePathname(); - const { view, pickerDisabled, setView } = useURLParams(); + const { view, frameworkPickerHidden, viewPickerHidden, featurePickerHidden, setView} = useURLParams(); const [isDarkTheme, setIsDarkTheme] = useState(false); // Extract the current integration ID from the pathname @@ -98,7 +99,7 @@ export function Sidebar({ isMobile, onMobileClose }: SidebarProps) { }, []); return ( -
{/* Sidebar Header */} @@ -106,7 +107,7 @@ export function Sidebar({ isMobile, onMobileClose }: SidebarProps) {

- AG-UI Interactive Dojo + {getTitleForCurrentDomain() || "AG-UI Interactive Dojo"}

@@ -115,9 +116,10 @@ export function Sidebar({ isMobile, onMobileClose }: SidebarProps) {
{/* Controls Section */} + {(!frameworkPickerHidden|| !viewPickerHidden) && (
{/* Integration picker */} - {!pickerDisabled && ( + {!frameworkPickerHidden&& (
@@ -143,6 +145,7 @@ export function Sidebar({ isMobile, onMobileClose }: SidebarProps) { )} {/* Preview/Code Tabs */} + {!viewPickerHidden &&
+ }
+ )} {/* Demo List */}
- {currentIntegration ? ( + {(currentIntegration && !featurePickerHidden) ? ( void; setSidebarHidden: (disabled: boolean) => void; - setPickerDisabled: (disabled: boolean) => void; + setFrameworkPickerHidden: (disabled: boolean) => void; + setViewPickerHidden: (disabled: boolean) => void; + setFeaturePickerHidden: (disabled: boolean) => void; setCodeFile: (fileName: string) => void; } @@ -32,14 +36,16 @@ export function URLParamsProvider({ children }: URLParamsProviderProps) { // Initialize state from URL params const [state, setState] = useState(() => ({ view: (searchParams.get("view") as View) || "preview", - sidebarHidden: searchParams.get("sidebar") === "disabled", - pickerDisabled: searchParams.get("picker") === "false", + sidebarHidden: searchParams.get("sidebar") === "false", + frameworkPickerHidden: searchParams.get("frameworkPicker") === "false", + viewPickerHidden: searchParams.get("viewPicker") === "false", + featurePickerHidden: searchParams.get("featurePicker") === "false", })); // Update URL when state changes const updateURL = (newState: Partial) => { const params = new URLSearchParams(searchParams.toString()); - + // Update view param if (newState.view !== undefined) { if (newState.view === "preview") { @@ -48,22 +54,39 @@ export function URLParamsProvider({ children }: URLParamsProviderProps) { params.set("view", newState.view); } } - + // Update sidebar param if (newState.sidebarHidden !== undefined) { if (newState.sidebarHidden) { - params.set("sidebar", "disabled"); + params.set("sidebar", "false"); } else { params.delete("sidebar"); } } - - // Update picker param - if (newState.pickerDisabled !== undefined) { - if (newState.pickerDisabled) { - params.set("picker", "false"); + + // Update frameworkPicker param + if (newState.frameworkPickerHidden !== undefined) { + if (newState.frameworkPickerHidden) { + params.set("frameworkPicker", "false"); } else { - params.delete("picker"); + params.delete("frameworkPicker"); + } + } + + // Update viewPicker param + if (newState.viewPickerHidden !== undefined) { + if (newState.viewPickerHidden) { + params.set("viewPicker", "false"); + } else { + params.delete("viewPicker"); + } + } + // Update featurePicker param + if (newState.featurePickerHidden !== undefined) { + if (newState.featurePickerHidden) { + params.set("featurePicker", "false"); + } else { + params.delete("features"); } } @@ -76,9 +99,11 @@ export function URLParamsProvider({ children }: URLParamsProviderProps) { const newState: URLParamsState = { view: (searchParams.get("view") as View) || "preview", sidebarHidden: searchParams.get("sidebar") === "disabled", - pickerDisabled: searchParams.get("picker") === "false", + frameworkPickerHidden: searchParams.get("frameworkPicker") === "false", + viewPickerHidden: searchParams.get("viewPicker") === "false", + featurePickerHidden: searchParams.get("featurePicker") === "false", }; - + setState(newState); }, [searchParams]); @@ -95,10 +120,22 @@ export function URLParamsProvider({ children }: URLParamsProviderProps) { updateURL({ sidebarHidden }); }; - const setPickerDisabled = (pickerDisabled: boolean) => { - const newState = { ...state, pickerDisabled }; + const setFrameworkPickerHidden = (frameworkPickerHidden: boolean) => { + const newState = { ...state, frameworkPickerHidden }; + setState(newState); + updateURL({ frameworkPickerHidden }); + }; + + const setViewPickerHidden = (viewPickerHidden: boolean) => { + const newState = { ...state, viewPickerHidden }; + setState(newState); + updateURL({ viewPickerHidden }); + }; + + const setFeaturePickerHidden = (featurePickerHidden: boolean) => { + const newState = { ...state, featurePickerHidden }; setState(newState); - updateURL({ pickerDisabled }); + updateURL({ featurePickerHidden }); }; const setCodeFile = (fileName: string) => { @@ -111,7 +148,9 @@ export function URLParamsProvider({ children }: URLParamsProviderProps) { ...state, setView, setSidebarHidden, - setPickerDisabled, + setFrameworkPickerHidden, + setViewPickerHidden, + setFeaturePickerHidden, setCodeFile, }; diff --git a/typescript-sdk/apps/dojo/src/env.ts b/typescript-sdk/apps/dojo/src/env.ts index 4ac83b257..df4df2f37 100644 --- a/typescript-sdk/apps/dojo/src/env.ts +++ b/typescript-sdk/apps/dojo/src/env.ts @@ -8,18 +8,28 @@ type envVars = { llamaIndexUrl: string; crewAiUrl: string; pydanticAIUrl: string; + customDomainTitle: Record; } export default function getEnvVars(): envVars { - return { - serverStarterUrl: process.env.SERVER_STARTER_URL || 'http://localhost:8000', - serverStarterAllFeaturesUrl: process.env.SERVER_STARTER_ALL_FEATURES_URL || 'http://localhost:8000', - mastraUrl: process.env.MASTRA_URL || 'http://localhost:4111', - langgraphUrl: process.env.LANGGRAPH_URL || 'http://localhost:2024', - langgraphFastApiUrl: process.env.LANGGRAPH_FAST_API_URL || 'http://localhost:8000', - agnoUrl: process.env.AGNO_URL || 'http://localhost:9001', - llamaIndexUrl: process.env.LLAMA_INDEX_URL || 'http://localhost:9000', - crewAiUrl: process.env.CREW_AI_URL || 'http://localhost:9002', - pydanticAIUrl: process.env.PYDANTIC_AI_URL || 'http://localhost:9000', + const customDomainTitle: Record = {}; + if (process.env.NEXT_PUBLIC_CUSTOM_DOMAIN_TITLE) { + const [domain, title] = process.env.NEXT_PUBLIC_CUSTOM_DOMAIN_TITLE.split('___'); + if (domain && title) { + customDomainTitle[domain] = title; } + } + + return { + serverStarterUrl: process.env.SERVER_STARTER_URL || 'http://localhost:8000', + serverStarterAllFeaturesUrl: process.env.SERVER_STARTER_ALL_FEATURES_URL || 'http://localhost:8000', + mastraUrl: process.env.MASTRA_URL || 'http://localhost:4111', + langgraphUrl: process.env.LANGGRAPH_URL || 'http://localhost:2024', + langgraphFastApiUrl: process.env.LANGGRAPH_FAST_API_URL || 'http://localhost:8000', + agnoUrl: process.env.AGNO_URL || 'http://localhost:9001', + llamaIndexUrl: process.env.LLAMA_INDEX_URL || 'http://localhost:9000', + crewAiUrl: process.env.CREW_AI_URL || 'http://localhost:9002', + pydanticAIUrl: process.env.PYDANTIC_AI_URL || 'http://localhost:9000', + customDomainTitle: customDomainTitle, + } } \ No newline at end of file diff --git a/typescript-sdk/apps/dojo/src/utils/domain-config.ts b/typescript-sdk/apps/dojo/src/utils/domain-config.ts new file mode 100644 index 000000000..e44b7fcf1 --- /dev/null +++ b/typescript-sdk/apps/dojo/src/utils/domain-config.ts @@ -0,0 +1,14 @@ +import getEnvVars from "@/env"; + + +export function getTitleForCurrentDomain(): string | undefined { + const envVars = getEnvVars(); + + // Check if we're in the browser + if (typeof window == "undefined") { + return undefined; + } + + const host = window.location.hostname; + return envVars.customDomainTitle[host] || undefined; +} \ No newline at end of file