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 { PlaygroundResultsTable } from './PlaygroundResultsTable/PlaygroundResultsTable'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { usePlaygroundApi } from 'hooks/api/actions/usePlayground/usePlayground'; import { PlaygroundResponseSchema } from 'component/playground/Playground/interfaces/playground.model'; import { useEnvironments } from 'hooks/api/getters/useEnvironments/useEnvironments'; import { PlaygroundForm } from './PlaygroundForm/PlaygroundForm'; import { resolveDefaultEnvironment, resolveProjects, resolveResultsWidth, } from './playground.utils'; import { PlaygroundGuidance } from './PlaygroundGuidance/PlaygroundGuidance'; import { PlaygroundGuidancePopper } from './PlaygroundGuidancePopper/PlaygroundGuidancePopper'; export const Playground: VFC<{}> = () => { const { environments } = useEnvironments(); const theme = useTheme(); const matches = useMediaQuery(theme.breakpoints.down('lg')); const [environment, setEnvironment] = useState(''); const [projects, setProjects] = useState([]); const [context, setContext] = useState(); const [results, setResults] = useState< PlaygroundResponseSchema | undefined >(); const { setToastData } = useToast(); const [searchParams, setSearchParams] = useSearchParams(); const { evaluatePlayground, loading } = usePlaygroundApi(); useEffect(() => { setEnvironment(resolveDefaultEnvironment(environments)); }, [environments]); useEffect(() => { // Load initial values from URL try { const environmentFromUrl = searchParams.get('environment'); if (environmentFromUrl) { setEnvironment(environmentFromUrl); } let projectsArray: string[]; let projectsFromUrl = searchParams.get('projects'); if (projectsFromUrl) { projectsArray = projectsFromUrl.split(','); setProjects(projectsArray); } let contextFromUrl = searchParams.get('context'); if (contextFromUrl) { contextFromUrl = decodeURI(contextFromUrl); setContext(contextFromUrl); } const makePlaygroundRequest = async () => { if (environmentFromUrl && contextFromUrl) { await evaluatePlaygroundContext( environmentFromUrl, projectsArray || '*', contextFromUrl ); } }; makePlaygroundRequest(); } catch (error) { setToastData({ type: 'error', title: `Failed to parse URL parameters: ${formatUnknownError( error )}`, }); } // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const evaluatePlaygroundContext = async ( environment: string, projects: string[] | string, context: string | undefined, action?: () => void ) => { try { const parsedContext = JSON.parse(context || '{}'); const response = await evaluatePlayground({ environment, 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( environment, projects, context, setURLParameters ); }; const setURLParameters = () => { searchParams.set('context', encodeURI(context || '')); // always set because of native validation searchParams.set('environment', environment); 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={} /> ); }; export default Playground;