Skip to content

Commit

Permalink
Refactored Scenario component
Browse files Browse the repository at this point in the history
- moved all Accordion controls to the Scenario component
- unified syntax for component properties
- Put sub-components into dedicated files
- Removed (currently) unnecessary properties to avoid confusion
  • Loading branch information
Robert Schüler committed May 3, 2024
1 parent 559f6ce commit 556e47f
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 99 deletions.
106 changes: 43 additions & 63 deletions new/src/components/Scenarios/Scenario.tsx
Original file line number Diff line number Diff line change
@@ -1,62 +1,80 @@
import type {ScenarioCaseModel, ScenarioModel, StepModel} from "../../reportModel";
import {Accordion, AccordionDetails, Box, Link, Typography} from "@mui/material";
import type {ScenarioModel} from "../../reportModel";
import {Accordion, AccordionDetails} from "@mui/material";
import {useCallback, useEffect, useState} from "react";
import {processWords} from "../../wordProcessor";
import {ExpansionState} from "./ScenarioOverview";
import {ScenarioHead} from "./ScenarioHead";
import {ScenarioCaption} from "./ScenarioCaption";
import {addRuntimeInSeconds} from "../utils";
import {ScenarioCase} from "./ScenarioCase";
import {styled} from "@mui/material/styles";
import MuiAccordionSummary, {AccordionSummaryProps} from "@mui/material/AccordionSummary";
import ArrowForwardIosSharpIcon from "@mui/icons-material/ArrowForwardIosSharp";

export interface ScenarioProps {
scenario: ScenarioModel;
globalExpansionState: ExpansionState;
onExpansionCallback: () => void;
onCollapsionCallback: () => void;
reportName?: string;
}

export function Scenario(props: ScenarioProps) {
const AccordionSummary = styled((props: AccordionSummaryProps) => (
<MuiAccordionSummary
expandIcon={<ArrowForwardIosSharpIcon sx={{ fontSize: "0.9rem" }} />}
{...props}
/>
))(({ theme }) => ({
backgroundColor:
theme.palette.mode === "dark" ? "rgba(255, 255, 255, .05)" : "rgba(0, 0, 0, .03)",
flexDirection: "row-reverse",
"& .MuiAccordionSummary-expandIconWrapper.Mui-expanded": {
transform: "rotate(90deg)"
},
"& .MuiAccordionSummary-content": {
marginLeft: theme.spacing(1)
}
}));

export function Scenario({ scenario, onExpansionCallback, onCollapsionCallback, globalExpansionState}: ScenarioProps) {
const [expanded, setExpanded] = useState(false);

useEffect(() => {
if (props.globalExpansionState === ExpansionState.COLLAPSED) {
if (globalExpansionState === ExpansionState.COLLAPSED) {
setExpanded(false);
}
if (props.globalExpansionState === ExpansionState.EXPANDED) {
if (globalExpansionState === ExpansionState.EXPANDED) {
setExpanded(true);
}
}, [props.globalExpansionState]);
}, [globalExpansionState]);

const onExpansionChanged = useCallback(
(isExpansion: boolean) => {
setExpanded(isExpansion);
isExpansion ? props.onExpansionCallback() : props.onCollapsionCallback();
isExpansion ? onExpansionCallback() : onCollapsionCallback();
},
[expanded]
);

return (
<div
id={`${props.scenario.className}#${props.scenario.testMethodName}`}
aria-label={`Scenario ${props.scenario.description}`}
id={`${scenario.className}#${scenario.testMethodName}`}
aria-label={`Scenario ${scenario.description}`}
>
<Accordion expanded={expanded}>
<ScenarioHead
scenario={props.scenario}
expanded={expanded}
setExpanded={onExpansionChanged}
/>
<AccordionSummary
aria-label="Scenario Overview"
onClick={() => {
onExpansionChanged(!expanded);
}}
>
<ScenarioHead
scenario={scenario}
/>
</AccordionSummary>

<AccordionDetails aria-label="Scenario Steps">
{
props.scenario.scenarioCases.map((scenarioCase) => {
return <SingleCaseScenario
scenario.scenarioCases.map((scenarioCase) => {
return <ScenarioCase
scenarioCase={scenarioCase}
reportName={props.reportName}
summary={props.scenario.description}
expanded={expanded}
setExpanded={onExpansionChanged}
className={props.scenario.className}
className={scenario.className}
/>
}
)
Expand All @@ -66,41 +84,3 @@ export function Scenario(props: ScenarioProps) {
</div>
);
}

function SingleCaseScenario(props: {
scenarioCase: ScenarioCaseModel;
expanded: boolean;
setExpanded: (expanded: boolean) => void;
reportName?: string;
summary: string;
className: string;
}) {
return (
<Box sx={{marginLeft: "2em"}}>
{props.scenarioCase.steps.map((step: StepModel, index) => (
<ScenarioStep key={index} step={step}></ScenarioStep>
))}
<Typography align="right" variant="body2">
<Link
href={`#class/${props.className}`}
variant="inherit"
color="inherit"
underline="none"
>
{props.className}
</Link>
</Typography>
</Box>
);
}

function ScenarioStep(props: { step: StepModel }) {
const stepDescription = processWords(props.step.words);
return (
<Typography align={"left"}>
{stepDescription} <ScenarioCaption>{addRuntimeInSeconds(props.step.durationInNanos)}</ScenarioCaption>
</Typography>
);
}


30 changes: 30 additions & 0 deletions new/src/components/Scenarios/ScenarioCase.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {Box, Link, Typography} from "@mui/material";
import { ScenarioCaseModel, StepModel } from "../../reportModel";
import {ScenarioStep} from "./ScenarioStep";

export interface ScenarioCaseProps {
className: string,
scenarioCase: ScenarioCaseModel,
}
export function ScenarioCase({
scenarioCase,
className,
} : ScenarioCaseProps) {
return (
<Box sx={{marginLeft: "2em"}}>
{scenarioCase.steps.map((step: StepModel, index) => (
<ScenarioStep key={index} step={step}></ScenarioStep>
))}
<Typography align="right" variant="body2">
<Link
href={`#class/${className}`}
variant="inherit"
color="inherit"
underline="none"
>
{className}
</Link>
</Typography>
</Box>
);
}
47 changes: 12 additions & 35 deletions new/src/components/Scenarios/ScenarioHead.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,54 +2,31 @@ import {Grid, Typography} from "@mui/material";
import {ScenarioModel} from "../../reportModel";
import {processWords} from "../../wordProcessor";
import {StatusIcon} from "../StatusIconSelector";
import {styled} from "@mui/material/styles";
import MuiAccordionSummary, {AccordionSummaryProps} from "@mui/material/AccordionSummary";
import ArrowForwardIosSharpIcon from "@mui/icons-material/ArrowForwardIosSharp";
import {ScenarioCaption} from "./ScenarioCaption";
import {addRuntimeInMilliseconds} from "../utils";

export function ScenarioHead(props: {

export interface ScenarioHeadProps {
scenario: ScenarioModel;
expanded: boolean;
setExpanded: (expanded: boolean) => void;
reportName?: string;
}) {
const AccordionSummary = styled((props: AccordionSummaryProps) => (
<MuiAccordionSummary
expandIcon={<ArrowForwardIosSharpIcon sx={{ fontSize: "0.9rem" }} />}
{...props}
/>
))(({ theme }) => ({
backgroundColor:
theme.palette.mode === "dark" ? "rgba(255, 255, 255, .05)" : "rgba(0, 0, 0, .03)",
flexDirection: "row-reverse",
"& .MuiAccordionSummary-expandIconWrapper.Mui-expanded": {
transform: "rotate(90deg)"
},
"& .MuiAccordionSummary-content": {
marginLeft: theme.spacing(1)
}
}));
}

return <AccordionSummary
aria-label="Scenario Overview"
onClick={() => {
props.setExpanded(!props.expanded);
}}
>
export function ScenarioHead({
scenario,
} : ScenarioHeadProps) {
return (
<Grid container columnSpacing={1}>
<Grid item>
<Typography color={"grey"}>{props.scenario.classTitle}</Typography>
<Typography color={"grey"}>{scenario.classTitle}</Typography>
</Grid>
<Grid item>
<Typography>{processWords(props.scenario.description)}</Typography>
<Typography>{processWords(scenario.description)}</Typography>
</Grid>
<Grid>
<StatusIcon executionStatus={props.scenario.executionStatus} />
<StatusIcon executionStatus={scenario.executionStatus} />
</Grid>
<Grid>
<ScenarioCaption>{addRuntimeInMilliseconds(props.scenario.scenarioCases[0].durationInNanos)}</ScenarioCaption>
<ScenarioCaption>{addRuntimeInMilliseconds(scenario.scenarioCases[0].durationInNanos)}</ScenarioCaption>
</Grid>
</Grid>
</AccordionSummary>
);
}
1 change: 0 additions & 1 deletion new/src/components/Scenarios/ScenarioOverview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ export function ScenarioOverview(props: {
.sort(compareByClassTitleAndDescriptionFn)
.map(scenario => (
<Scenario
reportName={props.reportName}
scenario={scenario}
globalExpansionState={allExpanded}
onCollapsionCallback={() => {
Expand Down
18 changes: 18 additions & 0 deletions new/src/components/Scenarios/ScenarioStep.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {processWords} from "../../wordProcessor";
import {Typography} from "@mui/material";
import {ScenarioCaption} from "./ScenarioCaption";
import {addRuntimeInSeconds} from "../utils";
import { StepModel } from "../../reportModel";

export interface ScenarioStepProps {
step: StepModel;
}

export function ScenarioStep({ step }: ScenarioStepProps) {
const stepDescription = processWords(step.words);
return (
<Typography align={"left"}>
{stepDescription} <ScenarioCaption>{addRuntimeInSeconds(step.durationInNanos)}</ScenarioCaption>
</Typography>
);
}

0 comments on commit 556e47f

Please sign in to comment.