Skip to content

Commit 0bca734

Browse files
committed
Separated most edge case handling in solution display components
1 parent 0878225 commit 0bca734

6 files changed

Lines changed: 77 additions & 59 deletions

File tree

solves/base-template/src/components/ResultDisplay/DisplayDoubleGrouped.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
}
1515

1616
.display-double-grouped-title {
17+
font-family: monospace;
1718
font-weight: bold;
1819
text-decoration: underline;
1920
}

solves/base-template/src/components/ResultDisplay/DisplayDoubleGrouped.tsx

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
/*
22
* This is a prototype module. The goal is to generate this in a better way.
3+
* TODO: Immutability at the type-level?
34
*/
45

56
import React from "react";
67

7-
import {type ParsedSolutionSpecialCode} from "../../runSolver";
88
import {
99
warnIfNotString,
1010
arrayGroupAdjacent,
@@ -24,7 +24,7 @@ interface GroupDisplayProps {
2424

2525
function GroupDisplay(props: GroupDisplayProps) {
2626
// TODO: How to splice multiple arbitrary indices in a simple manner?
27-
const modifiedData: string[][] = props.data.map(x => x.splice(2));
27+
const modifiedData: string[][] = props.data.map(x => [...x].splice(2));
2828
return <table className="display-double-grouped-table">
2929
<thead>
3030
<tr><th>Group {props.groupName}</th></tr>
@@ -74,23 +74,14 @@ function RoundDisplay(props: RoundDisplayProps) {
7474

7575
interface Props {
7676
fieldLabels: string[];
77-
solutionData: string[][] | ParsedSolutionSpecialCode | "not-initialized";
77+
solutionData: string[][];
7878
}
7979

8080
export function DisplayDoubleGrouped(props: Props) {
81-
switch (props.solutionData) {
82-
case "not-initialized":
83-
return <>Loading...</>;
84-
case "no-solution":
85-
return <>No solution.</>;
86-
case "invalid-input":
87-
return <>Invalid input.</>;
88-
case "error":
89-
return <>An error has occurred.</>;
90-
default: // Fallthrough
91-
}
9281
if (props.solutionData.length === 0) {
93-
return <>There is a solution, but it has no values.</>;
82+
return <div className="output-table-wrapper">
83+
There is a solution, but it has no values.
84+
</div>;
9485
}
9586

9687
const groupedData: GroupedSolution = arrayGroupAdjacent(
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import React from "react";
2+
3+
import {type ParsedSolutionSpecialCode} from "../../runSolver";
4+
5+
import "./DisplaySpecialMessage.css";
6+
7+
type SpecialCode = ParsedSolutionSpecialCode | "not-initialized";
8+
9+
function getText(specialCode: SpecialCode): string {
10+
switch (specialCode) {
11+
case "not-initialized":
12+
return "Loading...";
13+
case "no-solution":
14+
return "No solution.";
15+
case "invalid-input":
16+
return "Invalid input.";
17+
default:
18+
console.error("Invalid special code.");
19+
// Fallthrough
20+
case "error":
21+
return "An error has occurred.";
22+
}
23+
}
24+
25+
/*** ***/
26+
27+
interface Props {
28+
specialCode: SpecialCode;
29+
}
30+
31+
export function DisplaySpecialMessage(props: Props) {
32+
return <div className="output-table-wrapper">
33+
{getText(props.specialCode)}
34+
</div>;
35+
}
36+
Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import React from "react";
22

3-
import {type ParsedSolutionSpecialCode} from "../../runSolver";
4-
53
import "./DisplayTable.css";
64

75
function renderRow(strs: string[], i: number) {
@@ -16,36 +14,29 @@ function renderRow(strs: string[], i: number) {
1614

1715
interface Props {
1816
fieldLabels: string[];
19-
solutionData: string[][] | ParsedSolutionSpecialCode | "not-initialized";
17+
solutionData: string[][];
2018
}
2119

2220
export function DisplayTable(props: Props) {
23-
switch (props.solutionData) {
24-
case "not-initialized":
25-
return <>Loading...</>;
26-
case "no-solution":
27-
return <>No solution.</>;
28-
case "invalid-input":
29-
return <>Invalid input.</>;
30-
case "error":
31-
return <>An error has occurred.</>;
32-
default: // Fallthrough
33-
}
3421
if (props.solutionData.length === 0) {
35-
return <>There is a solution, but it has no values.</>;
22+
return <div className="output-table-wrapper">
23+
There is a solution, but it has no values.
24+
</div>;
3625
}
3726

38-
return <table className="result-satisfiable">
39-
<thead>
40-
<tr key={0}>
41-
{props.fieldLabels.map((x: string, i: number) =>
42-
<th key={i}>{x}</th>
43-
)}
44-
</tr>
45-
</thead>
46-
<tbody>
47-
{props.solutionData.map(renderRow)}
48-
</tbody>
49-
</table>;
27+
return <div className="output-table-wrapper">
28+
<table className="result-satisfiable">
29+
<thead>
30+
<tr key={0}>
31+
{props.fieldLabels.map((x: string, i: number) =>
32+
<th key={i}>{x}</th>
33+
)}
34+
</tr>
35+
</thead>
36+
<tbody>
37+
{props.solutionData.map(renderRow)}
38+
</tbody>
39+
</table>
40+
</div>;
5041
}
5142

solves/base-template/src/components/ResultDisplay/index.tsx.ejs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from "react";
22

33
import {type ParsedSolution} from "../../runSolver";
44

5+
import {DisplaySpecialMessage} from "./DisplaySpecialMessage";
56
import {DisplayTable} from "./DisplayTable";
67
import {DisplayDoubleGrouped} from "./DisplayDoubleGrouped";
78
DisplayTable;
@@ -14,28 +15,25 @@ interface Props {
1415
}
1516

1617
export function ResultDisplay(props: Props) {
18+
if (typeof props.solutionData === "string") {
19+
// If it's a string, an edge case has occurred (such as "no solution found").
20+
return <DisplaySpecialMessage
21+
specialCode={props.solutionData}
22+
/>;
23+
}
24+
1725
return <>
1826
<DisplayDoubleGrouped
1927
fieldLabels={["Round", "Group", "Players"]}
20-
solutionData={
21-
(typeof props.solutionData === "string")
22-
? props.solutionData
23-
: props.solutionData.assign
24-
}
28+
solutionData={props.solutionData.assign}
2529
/>
2630
<% for (const [outputID, partialSpec] of Object.entries(output)) { -%>
27-
<div className="output-table-wrapper">
28-
<DisplayTable
29-
fieldLabels={[<%-
30-
partialSpec.fields.map(y => safeString(y.label)).join(", ")
31-
%>]}
32-
solutionData={
33-
(typeof props.solutionData === "string")
34-
? props.solutionData
35-
: props.solutionData.<%- outputID %>
36-
}
37-
/>
38-
</div>
31+
<DisplayTable
32+
fieldLabels={[<%-
33+
partialSpec.fields.map(y => safeString(y.label)).join(", ")
34+
%>]}
35+
solutionData={props.solutionData.<%- outputID %>}
36+
/>
3937
<% } -%>
4038
</>;
4139
}

0 commit comments

Comments
 (0)