Skip to content

Commit

Permalink
Adds reproduce tab to replace the test code generation clicks from th…
Browse files Browse the repository at this point in the history
…e data page
  • Loading branch information
elijahbenizzy committed Aug 16, 2024
1 parent 73305d1 commit 5d0bdce
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 65 deletions.
62 changes: 2 additions & 60 deletions telemetry/ui/src/components/routes/app/DataView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Button } from '../../common/button';
import { Switch, SwitchField } from '../../common/switch';
import { Label } from '../../common/fieldset';
import { classNames } from '../../../utils/tailwind';
import { ChevronDownIcon, ChevronUpIcon, QuestionMarkCircleIcon } from '@heroicons/react/20/solid';
import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/20/solid';
import { getUniqueAttributeID } from '../../../utils';
import { AppViewHighlightContext } from './AppView';
import { MinusIcon } from '@heroicons/react/24/outline';
Expand Down Expand Up @@ -140,27 +140,6 @@ const SectionHeaderWithExpand = (props: {
);
};

const FlashMessage = ({
message,
duration,
onClose
}: {
message: string;
duration: number;
onClose: () => void;
}) => {
useEffect(() => {
const timer = setTimeout(onClose, duration);
return () => clearTimeout(timer);
}, [duration, onClose]);

return (
<div className="fixed bottom-4 right-4 bg-blue-500 text-white p-2 rounded shadow-lg">
{message}
</div>
);
};

export const DataView = (props: { currentStep: Step | undefined; priorStep: Step | undefined }) => {
const [whichState, setWhichState] = useState<'after' | 'before' | 'compare'>('after');
const stepToExamine = whichState !== 'before' ? props.currentStep : props.priorStep;
Expand All @@ -179,18 +158,7 @@ export const DataView = (props: { currentStep: Step | undefined; priorStep: Step
useState<EXPANDED_TOGGLE>('default_expanded');

const attributes = stepToExamine?.attributes || [];
const step = props.currentStep || props.priorStep;
const [isFlashVisible, setIsFlashVisible] = useState(false);
const url = window.location.href;
const parts = url.split('/');
const [projectName, partitionKey, appID] = parts.slice(-3);
const cmd =
'burr-test-case create \\\n' +
` --project-name "${projectName}" \\\n` +
` --partition-key "${partitionKey}" \\\n` +
` --app-id "${appID}" \\\n` +
` --sequence-id ${step ? step.step_start_log.sequence_id : '?'} \\\n` +
' --target-file-name YOUR_FIXTURE_FILE.json \n';

return (
<div className="pl-1 flex flex-col gap-2 hide-scrollbar">
<div className="flex flex-row justify-between sticky top-0 z-20 bg-white">
Expand All @@ -200,32 +168,6 @@ export const DataView = (props: { currentStep: Step | undefined; priorStep: Step
setDefaultExpanded={setAllStateExpanded}
dualToggle={viewRawData === 'raw'}
/>
<div className="text-xs pt-3 flex items-center">
{' '}
<span
className="cursor-pointer"
onClick={() => {
navigator.clipboard.writeText(cmd);
setIsFlashVisible(true);
// alert(`Copied ${cmd} to clipboard`);
}}
>
Step {step ? step.step_start_log.sequence_id : '?'} Test Case 📋
</span>
<QuestionMarkCircleIcon
className="h-3 w-3 text-gray-500 hover:text-gray-700 cursor-pointer"
onClick={() =>
window.open('https://burr.dagworks.io/examples/creating_tests/', '_blank')
}
/>
{isFlashVisible && (
<FlashMessage
message={`${cmd} copied to clipboard!`}
duration={3000}
onClose={() => setIsFlashVisible(false)}
/>
)}
</div>
<div className="flex flex-row justify-end gap-2 pr-2">
<SwitchField>
<Switch
Expand Down
85 changes: 85 additions & 0 deletions telemetry/ui/src/components/routes/app/ReproduceView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { ClipboardIcon } from '@heroicons/react/24/outline';
import { Step } from '../../../api';
import { useEffect, useState } from 'react';

const FlashMessage = ({
message,
duration,
onClose
}: {
message: string;
duration: number;
onClose: () => void;
}) => {
useEffect(() => {
const timer = setTimeout(onClose, duration);
return () => clearTimeout(timer);
}, [duration, onClose]);

return (
<div className="fixed bottom-4 right-4 bg-dwlightblue text-white p-2 rounded shadow-lg">
{message}
</div>
);
};

export const ReproduceView = (props: {
step: Step | undefined;
appId: string;
partitionKey: string;
projectID: string;
}) => {
const cmd =
'burr-test-case create \\\n' +
` --project-name "${props.projectID}" \\\n` +
` --partition-key "${props.partitionKey}" \\\n` +
` --app-id "${props.appId}" \\\n` +
` --sequence-id ${props.step ? props.step.step_start_log.sequence_id : '?'} \\\n` +
' --target-file-name YOUR_FIXTURE_FILE.json \n';

const [isFlashVisible, setIsFlashVisible] = useState(false);

return (
<div className="pt-2 flex flex-col gap-4">
{isFlashVisible && (
<FlashMessage
message="Copied to clipboard!"
duration={2000}
onClose={() => setIsFlashVisible(false)}
/>
)}
<div className="flex flex-row justify-between">
<p>
To generate a test case for this step, run the following command.
<a
href="https://burr.dagworks.io/examples/creating_tests/"
target="_blank"
rel="noreferrer"
className="hover:underline text-dwlightblue"
>
{' '}
Further reading
</a>
.
</p>{' '}
<ClipboardIcon
className="h-5 w-5 min-h-5 min-w-5 cursor-pointer hover:scale-110"
onClick={() => {
navigator.clipboard.writeText(cmd);
setIsFlashVisible(true);
}}
/>
</div>
<pre className="text-white bg-gray-800 p-2 rounded-md text-sm">{cmd}</pre>;
</div>
);
// <span
// className="cursor-pointer"
// onClick={() => {
// navigator.clipboard.writeText(cmd);
// setIsFlashVisible(true);
// // alert(`Copied ${cmd} to clipboard`);
// }}>
// Step {step ? step.step_start_log.sequence_id : '?'} Test Case 📋
// </span>;
};
37 changes: 32 additions & 5 deletions telemetry/ui/src/components/routes/app/StateMachine.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ import { DataView } from './DataView';
import { ActionView } from './ActionView';
import { GraphView } from './GraphView';
import { InsightsView } from './InsightsView';
import { ReproduceView } from './ReproduceView';
import { useParams } from 'react-router-dom';

const NoStepSelected = () => {
return (
<div className="flex flex-col items-center justify-center h-full">
<p className="text-xl text-gray-400">Please select a step from the table on the left</p>
</div>
);
};

export const AppStateView = (props: {
steps: Step[];
Expand All @@ -26,9 +36,11 @@ export const AppStateView = (props: {
const actionModel = props.stateMachine.actions.find(
(action) => action.name === currentStep?.step_start_log.action
);
const { projectId, appId, partitionKey } = useParams();
const tabs = [
{ id: 'data', displayName: 'Data' },
{ id: 'action', displayName: 'Action' },
{ id: 'code', displayName: 'Code' },
{ id: 'reproduce', displayName: 'Reproduce' },
{ id: 'insights', displayName: 'Insights' }
];
if (props.displayGraphAsTab) {
Expand All @@ -38,10 +50,14 @@ export const AppStateView = (props: {
<>
<Tabs tabs={tabs} currentTab={currentTab} setCurrentTab={setCurrentTab} />
<div className="px-4 h-full w-full hide-scrollbar overflow-y-auto">
{currentTab === 'data' && currentStep && (
<DataView currentStep={currentStep} priorStep={priorStep} />
)}
{currentTab === 'action' && currentStep && <ActionView currentAction={actionModel} />}
{currentTab === 'data' &&
(currentStep ? (
<DataView currentStep={currentStep} priorStep={priorStep} />
) : (
<NoStepSelected />
))}
{currentTab === 'code' &&
(currentStep ? <ActionView currentAction={actionModel} /> : <NoStepSelected />)}
{currentTab === 'graph' && (
<GraphView
stateMachine={props.stateMachine}
Expand All @@ -51,6 +67,17 @@ export const AppStateView = (props: {
/>
)}
{currentTab === 'insights' && <InsightsView steps={props.steps} />}
{currentTab === 'reproduce' &&
(currentStep ? (
<ReproduceView
step={currentStep}
appId={appId as string}
partitionKey={partitionKey as string}
projectID={projectId as string}
/>
) : (
<NoStepSelected />
))}
</div>
</>
);
Expand Down

0 comments on commit 5d0bdce

Please sign in to comment.