import { FormEventHandler, useEffect, useState, VFC } from 'react'; import { useSearchParams } from 'react-router-dom'; import { Box, Paper, useMediaQuery, useTheme } from '@mui/material'; import { PageContent } from 'component/common/PageContent/PageContent'; import { PageHeader } from 'component/common/PageHeader/PageHeader'; import useToast from 'hooks/useToast'; import { formatUnknownError } from 'utils/formatUnknownError'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { usePlaygroundApi } from 'hooks/api/actions/usePlayground/usePlayground'; import { useEnvironments } from 'hooks/api/getters/useEnvironments/useEnvironments'; import { PlaygroundForm } from './PlaygroundForm/PlaygroundForm'; import { resolveDefaultEnvironment, resolveEnvironments, resolveProjects, resolveResultsWidth, } from './playground.utils'; import { PlaygroundGuidance } from './PlaygroundGuidance/PlaygroundGuidance'; import { PlaygroundGuidancePopper } from './PlaygroundGuidancePopper/PlaygroundGuidancePopper'; import Loader from '../../common/Loader/Loader'; import { AdvancedPlaygroundResultsTable } from './AdvancedPlaygroundResultsTable/AdvancedPlaygroundResultsTable'; import { AdvancedPlaygroundResponseSchema } from 'openapi'; export const AdvancedPlayground: VFC<{}> = () => { const { environments: availableEnvironments } = useEnvironments(); const theme = useTheme(); const matches = true; const [environments, setEnvironments] = useState([]); const [projects, setProjects] = useState([]); const [context, setContext] = useState(); const [results, setResults] = useState< AdvancedPlaygroundResponseSchema | undefined >(); const { setToastData } = useToast(); const [searchParams, setSearchParams] = useSearchParams(); const { evaluateAdvancedPlayground, loading } = usePlaygroundApi(); useEffect(() => { setEnvironments([resolveDefaultEnvironment(availableEnvironments)]); }, [availableEnvironments]); useEffect(() => { loadInitialValuesFromUrl(); }, []); const loadInitialValuesFromUrl = () => { try { const environments = resolveEnvironmentsFromUrl(); const projects = resolveProjectsFromUrl(); const context = resolveContextFromUrl(); const makePlaygroundRequest = async () => { if (environments && context) { await evaluatePlaygroundContext( environments || [], projects || '*', context ); } }; makePlaygroundRequest(); } catch (error) { setToastData({ type: 'error', title: `Failed to parse URL parameters: ${formatUnknownError( error )}`, }); } }; const resolveEnvironmentsFromUrl = (): string[] | null => { let environmentArray: string[] | null = null; const environmentsFromUrl = searchParams.get('environments'); if (environmentsFromUrl) { environmentArray = environmentsFromUrl.split(','); setEnvironments(environmentArray); } return environmentArray; }; const resolveProjectsFromUrl = (): string[] | null => { let projectsArray: string[] | null = null; let projectsFromUrl = searchParams.get('projects'); if (projectsFromUrl) { projectsArray = projectsFromUrl.split(','); setProjects(projectsArray); } return projectsArray; }; const resolveContextFromUrl = () => { let contextFromUrl = searchParams.get('context'); if (contextFromUrl) { contextFromUrl = decodeURI(contextFromUrl); setContext(contextFromUrl); } return contextFromUrl; }; const evaluatePlaygroundContext = async ( environments: string[] | string, projects: string[] | string, context: string | undefined, action?: () => void ) => { try { const parsedContext = JSON.parse(context || '{}'); const response = await evaluateAdvancedPlayground({ environments: resolveEnvironments(environments), projects: resolveProjects(projects), context: { appName: 'playground', ...parsedContext, }, }); if (action && typeof action === 'function') { action(); } setResults(response); } catch (error: unknown) { setToastData({ type: 'error', title: `Error parsing context: ${formatUnknownError(error)}`, }); } }; const onSubmit: FormEventHandler = async event => { event.preventDefault(); await evaluatePlaygroundContext( environments, projects, context, setURLParameters ); }; const setURLParameters = () => { searchParams.set('context', encodeURI(context || '')); // always set because of native validation if ( Array.isArray(environments) && environments.length > 0 && !(environments.length === 1 && environments[0] === '*') ) { searchParams.set('environments', environments.join(',')); } else { searchParams.delete('projects'); } if ( Array.isArray(projects) && projects.length > 0 && !(projects.length === 1 && projects[0] === '*') ) { searchParams.set('projects', projects.join(',')); } else { searchParams.delete('projects'); } setSearchParams(searchParams); }; const formWidth = results && !matches ? '35%' : 'auto'; const resultsWidth = resolveResultsWidth(matches, results); return ( } /> } disableLoading bodyClass={'no-padding'} > ({ width: resultsWidth, transition: 'width 0.4s ease', padding: theme.spacing(4, 2), })} > } elseShow={ } elseShow={} /> } /> ); }; export default AdvancedPlayground;