mirror of
https://github.com/Unleash/unleash.git
synced 2025-03-18 00:19:49 +01:00
Playground fields with Change request (#7724)
using `changeRequest` value from URL
This commit is contained in:
parent
65131727c1
commit
4b6813aa5e
@ -1,4 +1,4 @@
|
|||||||
import { type FormEventHandler, useEffect, useState, type VFC } from 'react';
|
import { type FormEventHandler, useEffect, useState, type FC } from 'react';
|
||||||
import { useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
import { Box, Paper, useTheme, styled, Alert } from '@mui/material';
|
import { Box, Paper, useTheme, styled, Alert } from '@mui/material';
|
||||||
import { PageContent } from 'component/common/PageContent/PageContent';
|
import { PageContent } from 'component/common/PageContent/PageContent';
|
||||||
@ -81,7 +81,7 @@ const GenerateWarningMessages: React.FC<{
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const AdvancedPlayground: VFC<{
|
export const AdvancedPlayground: FC<{
|
||||||
FormComponent?: typeof PlaygroundForm;
|
FormComponent?: typeof PlaygroundForm;
|
||||||
}> = ({ FormComponent = PlaygroundForm }) => {
|
}> = ({ FormComponent = PlaygroundForm }) => {
|
||||||
const defaultSettings: {
|
const defaultSettings: {
|
||||||
@ -112,7 +112,7 @@ export const AdvancedPlayground: VFC<{
|
|||||||
>();
|
>();
|
||||||
const { setToastData } = useToast();
|
const { setToastData } = useToast();
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
const searchParamsLength = Array.from(searchParams.entries()).length;
|
const [changeRequest, setChangeRequest] = useState<string>();
|
||||||
const { evaluateAdvancedPlayground, loading, errors } = usePlaygroundApi();
|
const { evaluateAdvancedPlayground, loading, errors } = usePlaygroundApi();
|
||||||
const [hasFormBeenSubmitted, setHasFormBeenSubmitted] = useState(false);
|
const [hasFormBeenSubmitted, setHasFormBeenSubmitted] = useState(false);
|
||||||
|
|
||||||
@ -123,28 +123,25 @@ export const AdvancedPlayground: VFC<{
|
|||||||
}, [JSON.stringify(environments), JSON.stringify(availableEnvironments)]);
|
}, [JSON.stringify(environments), JSON.stringify(availableEnvironments)]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (searchParamsLength > 0) {
|
loadInitialValuesFromUrl();
|
||||||
loadInitialValuesFromUrl();
|
|
||||||
}
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const loadInitialValuesFromUrl = () => {
|
const loadInitialValuesFromUrl = async () => {
|
||||||
try {
|
try {
|
||||||
const environments = resolveEnvironmentsFromUrl();
|
const environments = resolveEnvironmentsFromUrl();
|
||||||
const projects = resolveProjectsFromUrl();
|
const projects = resolveProjectsFromUrl();
|
||||||
const context = resolveContextFromUrl();
|
const context = resolveContextFromUrl();
|
||||||
const token = resolveTokenFromUrl();
|
resolveTokenFromUrl();
|
||||||
const makePlaygroundRequest = async () => {
|
resolveChangeRequestFromUrl();
|
||||||
if (environments && context) {
|
// TODO: Add support for changeRequest
|
||||||
await evaluatePlaygroundContext(
|
|
||||||
environments || [],
|
|
||||||
projects || '*',
|
|
||||||
context,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
makePlaygroundRequest();
|
if (environments && context) {
|
||||||
|
await evaluatePlaygroundContext(
|
||||||
|
environments || [],
|
||||||
|
projects || '*',
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setToastData({
|
setToastData({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
@ -191,6 +188,13 @@ export const AdvancedPlayground: VFC<{
|
|||||||
return tokenFromUrl;
|
return tokenFromUrl;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const resolveChangeRequestFromUrl = () => {
|
||||||
|
const changeRequestFromUrl = searchParams.get('changeRequest');
|
||||||
|
if (changeRequestFromUrl) {
|
||||||
|
setChangeRequest(changeRequestFromUrl);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const evaluatePlaygroundContext = async (
|
const evaluatePlaygroundContext = async (
|
||||||
environments: string[] | string,
|
environments: string[] | string,
|
||||||
projects: string[] | string,
|
projects: string[] | string,
|
||||||
@ -243,14 +247,20 @@ export const AdvancedPlayground: VFC<{
|
|||||||
|
|
||||||
await evaluatePlaygroundContext(environments, projects, context, () => {
|
await evaluatePlaygroundContext(environments, projects, context, () => {
|
||||||
setURLParameters();
|
setURLParameters();
|
||||||
setValue({
|
if (!changeRequest) {
|
||||||
environments,
|
setValue({
|
||||||
projects,
|
environments,
|
||||||
context,
|
projects,
|
||||||
});
|
context,
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onClearChangeRequest = () => {
|
||||||
|
setChangeRequest(undefined);
|
||||||
|
};
|
||||||
|
|
||||||
const setURLParameters = () => {
|
const setURLParameters = () => {
|
||||||
searchParams.set('context', encodeURI(context || '')); // always set because of native validation
|
searchParams.set('context', encodeURI(context || '')); // always set because of native validation
|
||||||
if (
|
if (
|
||||||
@ -271,6 +281,11 @@ export const AdvancedPlayground: VFC<{
|
|||||||
} else {
|
} else {
|
||||||
searchParams.delete('projects');
|
searchParams.delete('projects');
|
||||||
}
|
}
|
||||||
|
if (changeRequest) {
|
||||||
|
searchParams.set('changeRequest', changeRequest);
|
||||||
|
} else {
|
||||||
|
searchParams.delete('changeRequest');
|
||||||
|
}
|
||||||
setSearchParams(searchParams);
|
setSearchParams(searchParams);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -326,6 +341,8 @@ export const AdvancedPlayground: VFC<{
|
|||||||
setToken={setToken}
|
setToken={setToken}
|
||||||
setProjects={setProjects}
|
setProjects={setProjects}
|
||||||
setEnvironments={setEnvironments}
|
setEnvironments={setEnvironments}
|
||||||
|
changeRequest={changeRequest || undefined}
|
||||||
|
onClearChangeRequest={onClearChangeRequest}
|
||||||
/>
|
/>
|
||||||
</Paper>
|
</Paper>
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -0,0 +1,71 @@
|
|||||||
|
import type { ComponentProps, Dispatch, FC, SetStateAction } from 'react';
|
||||||
|
import { Autocomplete, TextField } from '@mui/material';
|
||||||
|
import { renderOption } from '../../renderOption';
|
||||||
|
|
||||||
|
interface IEnvironmentsFieldProps {
|
||||||
|
environments: string[];
|
||||||
|
setEnvironments: Dispatch<SetStateAction<string[]>>;
|
||||||
|
availableEnvironments: string[];
|
||||||
|
disabled?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IOption {
|
||||||
|
label: string;
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const EnvironmentsField: FC<IEnvironmentsFieldProps> = ({
|
||||||
|
environments,
|
||||||
|
setEnvironments,
|
||||||
|
availableEnvironments,
|
||||||
|
disabled,
|
||||||
|
}) => {
|
||||||
|
const environmentOptions = [
|
||||||
|
...availableEnvironments.map((name) => ({
|
||||||
|
label: name,
|
||||||
|
id: name,
|
||||||
|
})),
|
||||||
|
];
|
||||||
|
const envValue = environmentOptions.filter(({ id }) =>
|
||||||
|
environments.includes(id),
|
||||||
|
);
|
||||||
|
|
||||||
|
const onEnvironmentsChange: ComponentProps<
|
||||||
|
typeof Autocomplete
|
||||||
|
>['onChange'] = (event, value, reason) => {
|
||||||
|
const newEnvironments = value as IOption | IOption[];
|
||||||
|
if (reason === 'clear' || newEnvironments === null) {
|
||||||
|
return setEnvironments([]);
|
||||||
|
}
|
||||||
|
if (Array.isArray(newEnvironments)) {
|
||||||
|
if (newEnvironments.length === 0) {
|
||||||
|
return setEnvironments([]);
|
||||||
|
}
|
||||||
|
return setEnvironments(newEnvironments.map(({ id }) => id));
|
||||||
|
}
|
||||||
|
|
||||||
|
return setEnvironments([newEnvironments.id]);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Autocomplete
|
||||||
|
disablePortal
|
||||||
|
limitTags={3}
|
||||||
|
id='environment'
|
||||||
|
multiple={true}
|
||||||
|
options={environmentOptions}
|
||||||
|
sx={{ flex: 1 }}
|
||||||
|
renderInput={(params) => (
|
||||||
|
<TextField {...params} label='Environments' />
|
||||||
|
)}
|
||||||
|
renderOption={renderOption}
|
||||||
|
getOptionLabel={({ label }) => label}
|
||||||
|
disableCloseOnSelect={false}
|
||||||
|
size='small'
|
||||||
|
value={envValue}
|
||||||
|
onChange={onEnvironmentsChange}
|
||||||
|
disabled={disabled}
|
||||||
|
data-testid={'PLAYGROUND_ENVIRONMENT_SELECT'}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
@ -3,6 +3,7 @@ import { render } from 'utils/testRenderer';
|
|||||||
import { fireEvent, screen, within } from '@testing-library/react';
|
import { fireEvent, screen, within } from '@testing-library/react';
|
||||||
import { PlaygroundConnectionFieldset } from './PlaygroundConnectionFieldset';
|
import { PlaygroundConnectionFieldset } from './PlaygroundConnectionFieldset';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
import userEvent from '@testing-library/user-event';
|
||||||
|
|
||||||
const server = testServerSetup();
|
const server = testServerSetup();
|
||||||
|
|
||||||
@ -11,6 +12,9 @@ beforeEach(() => {
|
|||||||
versionInfo: {
|
versionInfo: {
|
||||||
current: { oss: 'version', enterprise: 'version' },
|
current: { oss: 'version', enterprise: 'version' },
|
||||||
},
|
},
|
||||||
|
flags: {
|
||||||
|
changeRequestPlayground: true,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
testServerRoute(
|
testServerRoute(
|
||||||
server,
|
server,
|
||||||
@ -203,3 +207,43 @@ test('should have a working clear button when token is filled', async () => {
|
|||||||
|
|
||||||
expect(tokenInput).toHaveValue('');
|
expect(tokenInput).toHaveValue('');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should show change request and disable other fields until removed', async () => {
|
||||||
|
const Component = () => {
|
||||||
|
const [environments, setEnvironments] = useState<string[]>([]);
|
||||||
|
const [projects, setProjects] = useState<string[]>(['test-project']);
|
||||||
|
const [token, setToken] = useState<string>();
|
||||||
|
const [changeRequest, setChangeRequest] = useState('CR #1');
|
||||||
|
|
||||||
|
const availableEnvironments = ['development', 'production'];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PlaygroundConnectionFieldset
|
||||||
|
environments={environments}
|
||||||
|
projects={projects}
|
||||||
|
token={token}
|
||||||
|
setToken={setToken}
|
||||||
|
setEnvironments={setEnvironments}
|
||||||
|
setProjects={setProjects}
|
||||||
|
availableEnvironments={availableEnvironments}
|
||||||
|
changeRequest={changeRequest}
|
||||||
|
onClearChangeRequest={() => setChangeRequest('')}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
render(<Component />);
|
||||||
|
|
||||||
|
const changeRequestInput = await screen.findByDisplayValue('CR #1');
|
||||||
|
// expect(changeRequestInput).toHaveValue('CR #1');
|
||||||
|
const viewButton = await screen.findByText(/View change request/);
|
||||||
|
expect(viewButton).toHaveProperty(
|
||||||
|
'href',
|
||||||
|
'http://localhost:3000/projects/test-project/change-requests/CR%20#1',
|
||||||
|
);
|
||||||
|
// TODO: check if other fields are disabled
|
||||||
|
|
||||||
|
const clearButton = await screen.findByLabelText(/clear change request/i);
|
||||||
|
|
||||||
|
await userEvent.click(clearButton);
|
||||||
|
expect(changeRequestInput).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
@ -3,22 +3,20 @@ import {
|
|||||||
type Dispatch,
|
type Dispatch,
|
||||||
type SetStateAction,
|
type SetStateAction,
|
||||||
useState,
|
useState,
|
||||||
type VFC,
|
type FC,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import {
|
import {
|
||||||
Autocomplete,
|
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
IconButton,
|
IconButton,
|
||||||
InputAdornment,
|
InputAdornment,
|
||||||
styled,
|
styled,
|
||||||
TextField,
|
type TextField,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
Typography,
|
Typography,
|
||||||
useTheme,
|
useTheme,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import useProjects from 'hooks/api/getters/useProjects/useProjects';
|
import useProjects from 'hooks/api/getters/useProjects/useProjects';
|
||||||
import { renderOption } from '../renderOption';
|
|
||||||
import {
|
import {
|
||||||
type IApiToken,
|
type IApiToken,
|
||||||
useApiTokens,
|
useApiTokens,
|
||||||
@ -32,6 +30,8 @@ import Clear from '@mui/icons-material/Clear';
|
|||||||
import { ProjectSelect } from '../../../../common/ProjectSelect/ProjectSelect';
|
import { ProjectSelect } from '../../../../common/ProjectSelect/ProjectSelect';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { useUiFlag } from 'hooks/useUiFlag';
|
import { useUiFlag } from 'hooks/useUiFlag';
|
||||||
|
import { EnvironmentsField } from './EnvironmentsField/EnvironmentsField';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
interface IPlaygroundConnectionFieldsetProps {
|
interface IPlaygroundConnectionFieldsetProps {
|
||||||
environments: string[];
|
environments: string[];
|
||||||
@ -41,6 +41,8 @@ interface IPlaygroundConnectionFieldsetProps {
|
|||||||
setEnvironments: Dispatch<SetStateAction<string[]>>;
|
setEnvironments: Dispatch<SetStateAction<string[]>>;
|
||||||
setToken?: Dispatch<SetStateAction<string | undefined>>;
|
setToken?: Dispatch<SetStateAction<string | undefined>>;
|
||||||
availableEnvironments: string[];
|
availableEnvironments: string[];
|
||||||
|
changeRequest?: string;
|
||||||
|
onClearChangeRequest?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IOption {
|
interface IOption {
|
||||||
@ -61,7 +63,7 @@ const StyledInput = styled(Input)(() => ({
|
|||||||
const StyledGrid = styled(Box)(({ theme }) => ({
|
const StyledGrid = styled(Box)(({ theme }) => ({
|
||||||
display: 'grid',
|
display: 'grid',
|
||||||
columnGap: theme.spacing(2),
|
columnGap: theme.spacing(2),
|
||||||
rowGap: theme.spacing(4),
|
rowGap: theme.spacing(2),
|
||||||
gridTemplateColumns: '1fr',
|
gridTemplateColumns: '1fr',
|
||||||
|
|
||||||
[theme.breakpoints.up('md')]: {
|
[theme.breakpoints.up('md')]: {
|
||||||
@ -69,7 +71,16 @@ const StyledGrid = styled(Box)(({ theme }) => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const PlaygroundConnectionFieldset: VFC<
|
const StyledChangeRequestInput = styled(StyledInput)(({ theme }) => ({
|
||||||
|
'& label': {
|
||||||
|
WebkitTextFillColor: theme.palette.text.secondary,
|
||||||
|
},
|
||||||
|
'& input.Mui-disabled': {
|
||||||
|
WebkitTextFillColor: theme.palette.text.secondary,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const PlaygroundConnectionFieldset: FC<
|
||||||
IPlaygroundConnectionFieldsetProps
|
IPlaygroundConnectionFieldsetProps
|
||||||
> = ({
|
> = ({
|
||||||
environments,
|
environments,
|
||||||
@ -79,6 +90,8 @@ export const PlaygroundConnectionFieldset: VFC<
|
|||||||
setEnvironments,
|
setEnvironments,
|
||||||
setToken,
|
setToken,
|
||||||
availableEnvironments,
|
availableEnvironments,
|
||||||
|
changeRequest,
|
||||||
|
onClearChangeRequest,
|
||||||
}) => {
|
}) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { tokens } = useApiTokens();
|
const { tokens } = useApiTokens();
|
||||||
@ -86,9 +99,7 @@ export const PlaygroundConnectionFieldset: VFC<
|
|||||||
|
|
||||||
const { projects: availableProjects } = useProjects();
|
const { projects: availableProjects } = useProjects();
|
||||||
|
|
||||||
const isChangeRequestPlaygroundEnabled = useUiFlag(
|
const changeRequestPlaygroundEnabled = useUiFlag('changeRequestPlayground');
|
||||||
'changeRequestPlayground',
|
|
||||||
);
|
|
||||||
|
|
||||||
const projectsOptions = [
|
const projectsOptions = [
|
||||||
allOption,
|
allOption,
|
||||||
@ -97,35 +108,6 @@ export const PlaygroundConnectionFieldset: VFC<
|
|||||||
id,
|
id,
|
||||||
})),
|
})),
|
||||||
];
|
];
|
||||||
|
|
||||||
const environmentOptions = [
|
|
||||||
...availableEnvironments.map((name) => ({
|
|
||||||
label: name,
|
|
||||||
id: name,
|
|
||||||
})),
|
|
||||||
];
|
|
||||||
|
|
||||||
const onEnvironmentsChange: ComponentProps<
|
|
||||||
typeof Autocomplete
|
|
||||||
>['onChange'] = (event, value, reason) => {
|
|
||||||
const newEnvironments = value as IOption | IOption[];
|
|
||||||
if (reason === 'clear' || newEnvironments === null) {
|
|
||||||
return setEnvironments([]);
|
|
||||||
}
|
|
||||||
if (Array.isArray(newEnvironments)) {
|
|
||||||
if (newEnvironments.length === 0) {
|
|
||||||
return setEnvironments([]);
|
|
||||||
}
|
|
||||||
return setEnvironments(newEnvironments.map(({ id }) => id));
|
|
||||||
}
|
|
||||||
|
|
||||||
return setEnvironments([newEnvironments.id]);
|
|
||||||
};
|
|
||||||
|
|
||||||
const envValue = environmentOptions.filter(({ id }) =>
|
|
||||||
environments.includes(id),
|
|
||||||
);
|
|
||||||
|
|
||||||
const onSetToken: ComponentProps<typeof TextField>['onChange'] = async (
|
const onSetToken: ComponentProps<typeof TextField>['onChange'] = async (
|
||||||
event,
|
event,
|
||||||
) => {
|
) => {
|
||||||
@ -208,18 +190,6 @@ export const PlaygroundConnectionFieldset: VFC<
|
|||||||
resetTokenState();
|
resetTokenState();
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderClearButton = () => (
|
|
||||||
<InputAdornment position='end' data-testid='TOKEN_INPUT_CLEAR_BTN'>
|
|
||||||
<IconButton
|
|
||||||
aria-label='toggle password visibility'
|
|
||||||
onClick={clearToken}
|
|
||||||
edge='end'
|
|
||||||
>
|
|
||||||
<SmallClear />
|
|
||||||
</IconButton>
|
|
||||||
</InputAdornment>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ pb: 2 }}>
|
<Box sx={{ pb: 2 }}>
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', mb: 2 }}>
|
<Box sx={{ display: 'flex', alignItems: 'center', mb: 2 }}>
|
||||||
@ -241,25 +211,14 @@ export const PlaygroundConnectionFieldset: VFC<
|
|||||||
: 'Select environments to use in the playground'
|
: 'Select environments to use in the playground'
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Autocomplete
|
<Box>
|
||||||
disablePortal
|
<EnvironmentsField
|
||||||
limitTags={3}
|
environments={environments}
|
||||||
id='environment'
|
setEnvironments={setEnvironments}
|
||||||
multiple={true}
|
availableEnvironments={availableEnvironments}
|
||||||
options={environmentOptions}
|
disabled={Boolean(token || changeRequest)}
|
||||||
sx={{ flex: 1 }}
|
/>
|
||||||
renderInput={(params) => (
|
</Box>
|
||||||
<TextField {...params} label='Environments' />
|
|
||||||
)}
|
|
||||||
renderOption={renderOption}
|
|
||||||
getOptionLabel={({ label }) => label}
|
|
||||||
disableCloseOnSelect={false}
|
|
||||||
size='small'
|
|
||||||
value={envValue}
|
|
||||||
onChange={onEnvironmentsChange}
|
|
||||||
disabled={Boolean(token)}
|
|
||||||
data-testid={'PLAYGROUND_ENVIRONMENT_SELECT'}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box>
|
||||||
@ -275,7 +234,7 @@ export const PlaygroundConnectionFieldset: VFC<
|
|||||||
selectedProjects={projects}
|
selectedProjects={projects}
|
||||||
onChange={setProjects}
|
onChange={setProjects}
|
||||||
dataTestId={'PLAYGROUND_PROJECT_SELECT'}
|
dataTestId={'PLAYGROUND_PROJECT_SELECT'}
|
||||||
disabled={Boolean(token)}
|
disabled={Boolean(token || changeRequest)}
|
||||||
limitTags={3}
|
limitTags={3}
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@ -283,7 +242,7 @@ export const PlaygroundConnectionFieldset: VFC<
|
|||||||
<Box>
|
<Box>
|
||||||
<StyledInput
|
<StyledInput
|
||||||
label='API token'
|
label='API token'
|
||||||
value={token || ''}
|
value={token || changeRequest ? ' ' : ''}
|
||||||
onChange={onSetToken}
|
onChange={onSetToken}
|
||||||
type={'text'}
|
type={'text'}
|
||||||
error={Boolean(tokenError)}
|
error={Boolean(tokenError)}
|
||||||
@ -291,36 +250,67 @@ export const PlaygroundConnectionFieldset: VFC<
|
|||||||
placeholder={'Enter your API token'}
|
placeholder={'Enter your API token'}
|
||||||
data-testid={'PLAYGROUND_TOKEN_INPUT'}
|
data-testid={'PLAYGROUND_TOKEN_INPUT'}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
endAdornment: token ? renderClearButton() : null,
|
endAdornment: token ? (
|
||||||
|
<InputAdornment
|
||||||
|
position='end'
|
||||||
|
data-testid='TOKEN_INPUT_CLEAR_BTN'
|
||||||
|
>
|
||||||
|
<IconButton
|
||||||
|
aria-label='clear API token'
|
||||||
|
onClick={clearToken}
|
||||||
|
edge='end'
|
||||||
|
>
|
||||||
|
<SmallClear />
|
||||||
|
</IconButton>
|
||||||
|
</InputAdornment>
|
||||||
|
) : null,
|
||||||
}}
|
}}
|
||||||
|
disabled={Boolean(changeRequest)}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={Boolean(isChangeRequestPlaygroundEnabled)}
|
condition={Boolean(
|
||||||
|
changeRequestPlaygroundEnabled && changeRequest,
|
||||||
|
)}
|
||||||
show={
|
show={
|
||||||
<Box sx={{ display: 'flex', gap: 2 }}>
|
<Box sx={{ display: 'flex', gap: 2 }}>
|
||||||
<Box sx={{ flex: 1 }}>
|
<Box sx={{ flex: 1 }}>
|
||||||
<StyledInput
|
<StyledChangeRequestInput
|
||||||
label='Change request'
|
label='Change request'
|
||||||
value={
|
value={changeRequest || ''}
|
||||||
'// TODO: Change request #5 (feature1, feature2)'
|
|
||||||
}
|
|
||||||
onChange={() => {}}
|
onChange={() => {}}
|
||||||
type={'text'}
|
type={'text'}
|
||||||
// error={Boolean(tokenError)}
|
// error={Boolean(changeRequestError)}
|
||||||
// errorText={tokenError}
|
// errorText={changeRequestError)}}
|
||||||
placeholder={'Enter your API token'}
|
placeholder={'Enter your API token'}
|
||||||
data-testid={'PLAYGROUND_TOKEN_INPUT'}
|
data-testid={'PLAYGROUND_TOKEN_INPUT'}
|
||||||
// disabled
|
disabled
|
||||||
InputProps={{
|
InputProps={{
|
||||||
endAdornment: renderClearButton(),
|
endAdornment: (
|
||||||
sx: {
|
<InputAdornment
|
||||||
cursor: 'default',
|
position='end'
|
||||||
},
|
data-testid='CR_INPUT_CLEAR_BTN'
|
||||||
|
>
|
||||||
|
<IconButton
|
||||||
|
aria-label='clear Change request results'
|
||||||
|
onClick={
|
||||||
|
onClearChangeRequest
|
||||||
|
}
|
||||||
|
edge='end'
|
||||||
|
>
|
||||||
|
<SmallClear />
|
||||||
|
</IconButton>
|
||||||
|
</InputAdornment>
|
||||||
|
),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<Button variant='outlined' size='small'>
|
<Button
|
||||||
|
variant='outlined'
|
||||||
|
size='small'
|
||||||
|
to={`/projects/${projects[0]}/change-requests/${changeRequest}`}
|
||||||
|
component={Link}
|
||||||
|
>
|
||||||
View change request
|
View change request
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -15,6 +15,8 @@ interface IPlaygroundFormProps {
|
|||||||
setEnvironments: React.Dispatch<React.SetStateAction<string[]>>;
|
setEnvironments: React.Dispatch<React.SetStateAction<string[]>>;
|
||||||
context: string | undefined;
|
context: string | undefined;
|
||||||
setContext: React.Dispatch<React.SetStateAction<string | undefined>>;
|
setContext: React.Dispatch<React.SetStateAction<string | undefined>>;
|
||||||
|
changeRequest?: string;
|
||||||
|
onClearChangeRequest?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PlaygroundForm: VFC<IPlaygroundFormProps> = ({
|
export const PlaygroundForm: VFC<IPlaygroundFormProps> = ({
|
||||||
@ -28,6 +30,8 @@ export const PlaygroundForm: VFC<IPlaygroundFormProps> = ({
|
|||||||
setEnvironments,
|
setEnvironments,
|
||||||
context,
|
context,
|
||||||
setContext,
|
setContext,
|
||||||
|
changeRequest,
|
||||||
|
onClearChangeRequest,
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
@ -50,6 +54,8 @@ export const PlaygroundForm: VFC<IPlaygroundFormProps> = ({
|
|||||||
availableEnvironments={availableEnvironments.map(
|
availableEnvironments={availableEnvironments.map(
|
||||||
({ name }) => name,
|
({ name }) => name,
|
||||||
)}
|
)}
|
||||||
|
changeRequest={changeRequest}
|
||||||
|
onClearChangeRequest={onClearChangeRequest}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<PlaygroundCodeFieldset context={context} setContext={setContext} />
|
<PlaygroundCodeFieldset context={context} setContext={setContext} />
|
||||||
|
Loading…
Reference in New Issue
Block a user