Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(frotend): Test Definition Name Input #2830

Merged
merged 1 commit into from
Jun 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 25 additions & 0 deletions web/src/components/InputOverlay/InputOverlay.styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {EditOutlined} from '@ant-design/icons';
import {Button} from 'antd';
import styled from 'styled-components';

export const Overlay = styled.div`
display: flex;
align-items: center;
gap: 8px;
cursor: pointer;
`;

export const SaveButton = styled(Button)``;

export const InputContainer = styled.div`
display: grid;
grid-template-columns: 45% 64px;
align-items: center;
max-width: 80%;
`;

export const EditIcon = styled(EditOutlined)`
&& {
color: ${({theme}) => theme.color.primary};
}
`;
38 changes: 38 additions & 0 deletions web/src/components/InputOverlay/InputOverlay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {useState} from 'react';
import {Input} from 'antd';
import {noop} from 'lodash';
import * as S from './InputOverlay.styled';

interface IProps {
onChange?(value: string): void;
value?: string;
}

const InputOverlay = ({onChange = noop, value = ''}: IProps) => {
const [isOpen, setIsOpen] = useState(false);
const [inputValue, setInputValue] = useState(value);

return isOpen ? (
<S.InputContainer>
<Input onChange={event => setInputValue(event.target.value)} value={inputValue} />
<S.SaveButton
ghost
type="primary"
onClick={() => {
setIsOpen(false);
onChange(inputValue);
}}
>
Save
</S.SaveButton>
</S.InputContainer>
) : (
<S.Overlay
onClick={() => setIsOpen(true)}
>
{inputValue} <S.EditIcon />
</S.Overlay>
);
};

export default InputOverlay;
2 changes: 2 additions & 0 deletions web/src/components/InputOverlay/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// eslint-disable-next-line no-restricted-exports
export {default} from './InputOverlay';
28 changes: 17 additions & 11 deletions web/src/components/RunDetailAutomate/RunDetailAutomate.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
import {snakeCase} from 'lodash';
import Test from 'models/Test.model';
import {useState} from 'react';
import TestRun from 'models/TestRun.model';
import * as S from './RunDetailAutomate.styled';
import TestDefinition from '../RunDetailAutomateDefinition';
import RunDetailAutomateDefinition from '../RunDetailAutomateDefinition';
import RunDetailAutomateMethods from '../RunDetailAutomateMethods/RunDetailAutomateMethods';

interface IProps {
test: Test;
run: TestRun;
}

const RunDetailAutomate = ({test, run}: IProps) => (
<S.Container>
<S.SectionLeft>
<TestDefinition test={test} />
</S.SectionLeft>
<S.SectionRight>
<RunDetailAutomateMethods test={test} run={run} />
</S.SectionRight>
</S.Container>
);
const RunDetailAutomate = ({test, run}: IProps) => {
const [fileName, setFileName] = useState<string>(`${snakeCase(test.name)}.yaml`);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went back and forth on having this to be a local state or something from a provider, but to keep it simple I just add it as a state. If we need to carry over multiple things for the techniques we can have an automate provider instead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it. Keep it simple.


return (
<S.Container>
<S.SectionLeft>
<RunDetailAutomateDefinition onFileNameChange={setFileName} fileName={fileName} test={test} />
</S.SectionLeft>
<S.SectionRight>
<RunDetailAutomateMethods fileName={fileName} test={test} run={run} />
</S.SectionRight>
</S.Container>
);
};

export default RunDetailAutomate;
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,7 @@ export const Footer = styled.div`
justify-content: flex-end;
margin-top: 16px;
`;

export const FileName = styled.div`
margin-bottom: 14px;
`;
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,20 @@ import {ResourceType} from 'types/Resource.type';
import Test from 'models/Test.model';
import * as S from './RunDetailAutomateDefinition.styled';
import {FramedCodeBlock} from '../CodeBlock';
import InputOverlay from '../InputOverlay/InputOverlay';

interface IProps {
test: Test;
onFileNameChange(value: string): void;
fileName: string;
}

const RunDetailAutomateDefinition = ({test: {id, version}}: IProps) => {
const RunDetailAutomateDefinition = ({test: {id, version}, onFileNameChange, fileName}: IProps) => {
const {definition, loadDefinition} = useDefinitionFile();

const onDownload = useCallback(() => {
downloadFile(definition, 'test_definition.yaml');
}, [definition]);
downloadFile(definition, fileName);
}, [definition, fileName]);

useEffect(() => {
loadDefinition(ResourceType.Test, id, version);
Expand All @@ -26,6 +29,9 @@ const RunDetailAutomateDefinition = ({test: {id, version}}: IProps) => {
return (
<S.Container>
<S.Title>Test Definition</S.Title>
<S.FileName>
<InputOverlay value={fileName} onChange={onFileNameChange} />
</S.FileName>
<FramedCodeBlock title="Preview your YAML file" value={definition} language="yaml" />
<S.Footer>
<Button data-cy="file-viewer-download" icon={<DownloadOutlined />} onClick={onDownload} type="primary">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ export interface IMethodProps {
environmentId?: string;
test: Test;
run: TestRun;
fileName?: string;
}

const RunDetailAutomateMethods = ({test, run}: IMethodProps) => {
const RunDetailAutomateMethods = ({test, run, fileName}: IMethodProps) => {
const [query, updateQuery] = useSearchParams();
const {selectedEnvironment: {id: environmentId} = {}} = useEnvironment();

Expand All @@ -37,7 +38,7 @@ const RunDetailAutomateMethods = ({test, run}: IMethodProps) => {
}}
>
<Tabs.TabPane key={TabsKeys.CLI} tab="CLI">
<CliCommand test={test} environmentId={environmentId} run={run} />
<CliCommand test={test} environmentId={environmentId} run={run} fileName={fileName} />
</Tabs.TabPane>
<Tabs.TabPane key={TabsKeys.DeepLink} tab="Deep Link">
<DeepLink test={test} environmentId={environmentId} run={run} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Controls from './Controls';
import useCliCommand from './hooks/useCliCommand';
import {IMethodProps} from '../../RunDetailAutomateMethods';

const CLiCommand = ({test, environmentId}: IMethodProps) => {
const CLiCommand = ({test, environmentId, fileName = ''}: IMethodProps) => {
const {command, onGetCommand} = useCliCommand();

return (
Expand All @@ -24,7 +24,7 @@ const CLiCommand = ({test, environmentId}: IMethodProps) => {
minHeight="100px"
maxHeight="100px"
/>
<Controls onChange={onGetCommand} test={test} environmentId={environmentId} />
<Controls onChange={onGetCommand} test={test} fileName={fileName} environmentId={environmentId} />
</S.Container>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ interface IProps {
onChange(cmdConfig: TCliCommandConfig): void;
test: Test;
environmentId?: string;
fileName: string;
}

const Controls = ({onChange, test, environmentId}: IProps) => {
const Controls = ({onChange, test, environmentId, fileName}: IProps) => {
const [form] = Form.useForm<TCliCommandConfig>();
const options = Form.useWatch('options', form);
const format = Form.useWatch('format', form);
Expand All @@ -33,8 +34,9 @@ const Controls = ({onChange, test, environmentId}: IProps) => {
format: format ?? CliCommandFormat.Pretty,
test,
environmentId,
fileName,
});
}, [environmentId, format, onChange, options, test]);
}, [environmentId, fileName, format, onChange, options, test]);

return (
<Form<TCliCommandConfig>
Expand Down
5 changes: 3 additions & 2 deletions web/src/services/CliCommand.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export type TCliCommandConfig = {
format: CliCommandFormat;
environmentId?: string;
test: Test;
fileName: string;
};

type TApplyProps = {
Expand Down Expand Up @@ -50,11 +51,11 @@ const CliCommandService = () => ({
: 'tracetest'
} ${command}`,
} as Record<CliCommandOption, TApplyOption>,
getCommand({options, format, test, environmentId}: TCliCommandConfig) {
getCommand({options, format, test, environmentId, fileName}: TCliCommandConfig) {
const command = Object.entries(options).reduce(
(acc, [option, enabled]) =>
this.applyOptions[option as CliCommandOption]({command: acc, enabled, test, environmentId}),
'test run -d test_definition.yaml'
`test run -d ${fileName}`
);

return `${command} -o ${format}`;
Expand Down