Skip to content

Commit a4d2683

Browse files
authored
Build out sorting functionality feature to conformance page (#151)
* Add sort option and misc adjustments * Fix mobile responsiveness on nav * Rebase + add sort options * Fix least ignored tests * Fix: persist sortOption in setter methods
1 parent 6bf2754 commit a4d2683

File tree

8 files changed

+231
-32
lines changed

8 files changed

+231
-32
lines changed

src/components/conformance/ResultsDisplay/components/SuiteDataContainer/styles.module.css

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
display: flex;
33
flex-direction: column;
44
width: 85%;
5-
height: 70vh;
5+
height: 75vh;
6+
padding: 0.5rem;
67
}
78

89
@media screen and (max-width: 996px) {

src/components/conformance/ResultsDisplay/components/SuiteDisplay/index.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ export default function SuiteDisplay(props: SuiteDisplayProps): JSX.Element {
2121
<div className={styles.suiteDisplay}>
2222
{props.currentSuite.suites ? (
2323
<SuiteSelector
24+
state={props.state}
2425
suites={props.currentSuite.suites}
25-
esFlag={props.state.ecmaScriptVersion}
2626
navigateToSuite={props.navigateToSuite}
2727
/>
2828
) : null}

src/components/conformance/ResultsDisplay/components/SuiteSelector/index.tsx

+14-5
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,39 @@
11
import React from "react";
2-
import { SuiteResult, TestStats } from "@site/src/components/conformance/types";
2+
import {
3+
ConformanceState,
4+
SortOption,
5+
SuiteResult,
6+
TestStats,
7+
} from "@site/src/components/conformance/types";
38

49
import styles from "./styles.module.css";
10+
import { availableSortingOptions } from "../../../utils";
511

612
type SelectorProps = {
13+
state: ConformanceState;
714
suites: SuiteResult[];
8-
esFlag: string | null;
915
navigateToSuite: (string) => void;
1016
};
1117

1218
export default function SuiteSelector(props: SelectorProps): JSX.Element {
19+
const option: SortOption[] = availableSortingOptions.filter(
20+
(v) => v.id === props.state.sortOption,
21+
);
1322
return (
1423
<div className={styles.suiteSelector}>
1524
{props.suites
16-
.sort((a, b) => a.name.localeCompare(b.name))
25+
.sort(option[0].callback)
1726
.filter((suite) => {
1827
const stats: TestStats =
19-
suite.versionedStats[props.esFlag] ?? suite.stats;
28+
suite.versionedStats[props.state.ecmaScriptVersion] ?? suite.stats;
2029
return stats.total !== 0;
2130
})
2231
.map((suite) => {
2332
return (
2433
<SuiteItem
2534
key={suite.name}
2635
suite={suite}
27-
esFlag={props.esFlag}
36+
esFlag={props.state.ecmaScriptVersion}
2837
navigateToSuite={props.navigateToSuite}
2938
/>
3039
);

src/components/conformance/ResultsDisplay/index.tsx

+24-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
VersionItem,
66
SuiteResult,
77
ConformanceState,
8+
SortOption,
89
} from "@site/src/components/conformance/types";
910
import ResultNavigation from "./nav";
1011
import {
@@ -89,6 +90,7 @@ export default function ResultsDisplay(props: ResultsProps): JSX.Element {
8990
props.state.version,
9091
newPath,
9192
props.state.ecmaScriptVersion,
93+
props.state.sortOption,
9294
),
9395
});
9496
};
@@ -104,6 +106,7 @@ export default function ResultsDisplay(props: ResultsProps): JSX.Element {
104106
props.state.version,
105107
slicedPath,
106108
props.state.ecmaScriptVersion,
109+
props.state.sortOption,
107110
),
108111
});
109112
};
@@ -113,7 +116,25 @@ export default function ResultsDisplay(props: ResultsProps): JSX.Element {
113116
const nulledFlag = flag ? flag : undefined;
114117
history.push({
115118
pathname: "/conformance",
116-
state: createState(props.state.version, props.state.testPath, nulledFlag),
119+
state: createState(
120+
props.state.version,
121+
props.state.testPath,
122+
nulledFlag,
123+
props.state.sortOption,
124+
),
125+
});
126+
};
127+
128+
// Sets the sorting option
129+
const setSortOption = (option: string) => {
130+
history.push({
131+
pathname: "/conformance",
132+
state: createState(
133+
props.state.version,
134+
props.state.testPath,
135+
props.state.ecmaScriptVersion,
136+
option,
137+
),
117138
});
118139
};
119140

@@ -125,6 +146,7 @@ export default function ResultsDisplay(props: ResultsProps): JSX.Element {
125146
props.state.version,
126147
props.state.testPath,
127148
props.state.ecmaScriptVersion,
149+
props.state.sortOption,
128150
test,
129151
),
130152
});
@@ -146,6 +168,7 @@ export default function ResultsDisplay(props: ResultsProps): JSX.Element {
146168
state={props.state}
147169
sliceNavToIndex={sliceNavToIndex}
148170
setEcmaScriptFlag={setEcmaScriptFlag}
171+
setSortOption={setSortOption}
149172
/>
150173
{currentSuite ? (
151174
<SuiteDisplay

src/components/conformance/ResultsDisplay/nav.tsx

+60-13
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,36 @@
11
import React from "react";
2-
import { ConformanceState, SpecEdition } from "../types";
2+
import { ConformanceState, SortOption, SpecEdition } from "../types";
33

44
import styles from "./styles.module.css";
55
import Link from "@docusaurus/Link";
6+
import { availableSortingOptions } from "../utils";
67

78
type ResultsNavProps = {
89
state: ConformanceState;
910
sliceNavToIndex: (number) => void;
1011
setEcmaScriptFlag: (string) => void;
12+
setSortOption: (string) => void;
1113
};
1214

1315
export default function ResultNavigation(props: ResultsNavProps): JSX.Element {
1416
return (
1517
<div className={styles.resultsNav}>
16-
<EcmaScriptVersionDropdown
17-
setEcmaScriptFlag={props.setEcmaScriptFlag}
18-
esVersionValue={props.state.ecmaScriptVersion}
19-
/>
20-
<NavBreadCrumbs
21-
navPath={props.state.testPath}
22-
sliceNavToIndex={props.sliceNavToIndex}
23-
/>
18+
<div className={styles.navSection}>
19+
<EcmaScriptVersionDropdown
20+
setEcmaScriptFlag={props.setEcmaScriptFlag}
21+
esVersionValue={props.state.ecmaScriptVersion}
22+
/>
23+
<SortingDropdown
24+
sortValue={props.state.sortOption}
25+
setSortOption={props.setSortOption}
26+
/>
27+
</div>
28+
<div className={styles.navSection}>
29+
<NavBreadCrumbs
30+
navPath={props.state.testPath}
31+
sliceNavToIndex={props.sliceNavToIndex}
32+
/>
33+
</div>
2434
</div>
2535
);
2636
}
@@ -32,11 +42,11 @@ type BreadCrumbProps = {
3242

3343
function NavBreadCrumbs(props: BreadCrumbProps) {
3444
return (
35-
<nav aria-label="breadcrumbs" style={{ padding: "0.25em" }}>
45+
<nav aria-label="breadcrumbs" style={{ padding: "0.5em" }}>
3646
<ul className="breadcrumbs">
3747
{props.navPath.map((pathItem, idx, arr) => {
3848
return (
39-
<NavItem
49+
<BreadCrumbItem
4050
key={pathItem}
4151
itemName={pathItem}
4252
index={idx}
@@ -54,14 +64,14 @@ function NavBreadCrumbs(props: BreadCrumbProps) {
5464
);
5565
}
5666

57-
type NavItemProps = {
67+
type BreadCrumbItemProps = {
5868
itemName: string;
5969
index: number;
6070
breadcrumbValue: string;
6171
sliceNavToIndex: (number) => void;
6272
};
6373

64-
function NavItem(props: NavItemProps): JSX.Element {
74+
function BreadCrumbItem(props: BreadCrumbItemProps): JSX.Element {
6575
return (
6676
<li className={props.breadcrumbValue}>
6777
<Link
@@ -99,6 +109,7 @@ function EcmaScriptVersionDropdown(props: DropDownProps): JSX.Element {
99109

100110
return (
101111
<div className={styles.dropdownContainer}>
112+
<h4 style={{ padding: "0.125rem 0.5rem", height: "5" }}>ES Version:</h4>
102113
<select value={dropdownValue} onChange={handleVersionSelection}>
103114
<option value={""}>All</option>
104115
{Object.keys(SpecEdition)
@@ -114,3 +125,39 @@ function EcmaScriptVersionDropdown(props: DropDownProps): JSX.Element {
114125
</div>
115126
);
116127
}
128+
129+
type SortProps = {
130+
sortValue: string;
131+
setSortOption: (string) => void;
132+
};
133+
134+
function SortingDropdown(props: SortProps): JSX.Element {
135+
const [sortValue, setSortValue] = React.useState<string>(props.sortValue ? props.sortValue : "alpha");
136+
137+
React.useEffect(() => {
138+
setSortValue(props.sortValue);
139+
}, [props.sortValue]);
140+
141+
const handleSortSelection = (e) => {
142+
setSortValue(e.target.value);
143+
const option = availableSortingOptions.filter(
144+
(v) => v.id === e.target.value,
145+
);
146+
props.setSortOption(option[0].id);
147+
};
148+
149+
return (
150+
<div className={styles.dropdownContainer}>
151+
<h4 style={{ padding: "0.125rem 0.5rem", height: "5" }}>Sort:</h4>
152+
<select value={sortValue} onChange={handleSortSelection}>
153+
{availableSortingOptions.map((key) => {
154+
return (
155+
<option key={key.id} value={key.id}>
156+
{key.name}
157+
</option>
158+
);
159+
})}
160+
</select>
161+
</div>
162+
);
163+
}

src/components/conformance/ResultsDisplay/styles.module.css

+26-6
Original file line numberDiff line numberDiff line change
@@ -10,31 +10,51 @@
1010
.resultsNav {
1111
display: flex;
1212
flex-direction: row;
13-
height: 5vh;
13+
height: 3.5rem;
1414
width: 100%;
1515
padding: 0.75em;
1616
}
1717

18+
.navSection {
19+
display: flex;
20+
flex-direction: row;
21+
}
22+
1823
.navLink:hover {
1924
cursor: pointer;
2025
}
2126

2227
.dropdownContainer {
23-
width: 6em;
24-
padding: 0.25em;
28+
display: flex;
29+
flex-direction: row;
30+
width: 12rem;
31+
height: 2.5rem;
32+
padding: 0.5rem 0;
2533
}
2634

27-
@media screen and (max-height: 996px) {
35+
@media screen and (max-width: 996px) {
2836
.resultsDisplay {
2937
height: auto;
3038
width: calc(100vw-12px);
3139
overflow-y: auto;
3240
}
3341

42+
.navSection {
43+
min-height: 2.5rem;
44+
height: auto;
45+
width: 100vw;
46+
}
47+
3448
.resultsNav {
35-
min-height: 3.5rem;
3649
height: auto;
50+
flex-direction: column;
3751
width: 100vw;
38-
padding: 1rem auto;
52+
padding: 0;
53+
}
54+
55+
.dropdownContainer {
56+
padding: 0.25rem 0;
57+
width: 10.5rem;
58+
height: 2rem;
3959
}
4060
}

src/components/conformance/types.ts

+14-5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export type ConformanceState = {
66
version: VersionItem;
77
testPath: string[];
88
ecmaScriptVersion: string | undefined;
9+
sortOption: string;
910
selectedTest: string | undefined;
1011
};
1112

@@ -14,13 +15,14 @@ export type VersionItem = {
1415
fetchUrl: string;
1516
};
1617

17-
export type TestStats = {
18-
total: number;
19-
passed: number;
20-
ignored: number;
21-
panic: number;
18+
export type SortOption = {
19+
id: string;
20+
name: string;
21+
callback: (a: SuiteResult, b: SuiteResult) => number;
2222
};
2323

24+
// The below types are specific to test result types.
25+
2426
export type ResultInfo = {
2527
version: string;
2628
commit: string;
@@ -49,6 +51,13 @@ export type VersionedStats = {
4951
es13: TestStats;
5052
};
5153

54+
export type TestStats = {
55+
total: number;
56+
passed: number;
57+
ignored: number;
58+
panic: number;
59+
};
60+
5261
export type TestResult = {
5362
name: string;
5463
edition: SpecEdition;

0 commit comments

Comments
 (0)