Skip to content

Commit 7bac418

Browse files
committed
cleanup levelUI & stepUI typings
Signed-off-by: shmck <[email protected]>
1 parent daaea85 commit 7bac418

File tree

8 files changed

+80
-54
lines changed

8 files changed

+80
-54
lines changed

Diff for: typings/index.d.ts

+22
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,28 @@
11
import * as E from './error'
22
import * as TT from './tutorial'
33

4+
export type LevelUI = {
5+
id: string
6+
title: string
7+
/** A summary of the level */
8+
summary: string
9+
/** The lesson content of the level, parsed as markdown */
10+
content: string
11+
/** A set of tasks for users linked to unit tests */
12+
steps: StepUI[]
13+
status: ProgressStatus
14+
}
15+
16+
export type StepUI = {
17+
id: string
18+
content: string
19+
status: ProgressStatus
20+
hints?: string[]
21+
subtasks?: SubtaskUI[]
22+
}
23+
24+
export type SubtaskUI = { name: string; status: ProgressStatus }
25+
426
export type ProgressStatus = 'ACTIVE' | 'COMPLETE' | 'INCOMPLETE' | 'FAIL'
527

628
export interface Progress {

Diff for: typings/tutorial.d.ts

-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ export type Step = {
3232
solution: Maybe<StepActions>
3333
hints?: string[]
3434
subtasks?: string[]
35-
status?: ProgressStatus
3635
}
3736

3837
/** A tutorial for use in VSCode CodeRoad */

Diff for: web-app/src/containers/Tutorial/components/Level.tsx

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import * as React from 'react'
22
import * as T from 'typings'
3-
import * as TT from 'typings/tutorial'
43
import { css, jsx } from '@emotion/core'
54
import Content from './Content'
65
import Steps from './Steps'
@@ -35,8 +34,8 @@ const styles = {
3534
},
3635
}
3736

38-
interface Props {
39-
level: TT.Level
37+
type Props = {
38+
level: T.LevelUI
4039
}
4140

4241
const Level = ({ level }: Props) => {

Diff for: web-app/src/containers/Tutorial/components/Step.tsx

+2-9
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import Markdown from '../../../components/Markdown'
77
interface Props {
88
content: string
99
status: T.ProgressStatus
10-
subtasks: { name: string; pass: boolean }[] | null
10+
subtasks?: T.SubtaskUI[]
1111
displayAll: boolean
1212
}
1313

@@ -60,16 +60,9 @@ const Step = (props: Props) => {
6060
{props.subtasks ? (
6161
<ul css={styles.subtasks}>
6262
{props.subtasks.map((subtask) => {
63-
let subtaskStatus: 'COMPLETE' | 'ACTIVE'
64-
if (props.status === 'COMPLETE') {
65-
subtaskStatus = 'COMPLETE'
66-
} else {
67-
subtaskStatus = subtask.pass ? 'COMPLETE' : 'ACTIVE'
68-
}
69-
7063
return (
7164
<li key={subtask.name} css={styles.subtask}>
72-
<TestStatusIcon size="xs" status={subtaskStatus} />
65+
<TestStatusIcon size="xs" status={subtask.status} />
7366
<span style={{ marginLeft: '0.5rem' }}>{subtask.name}</span>
7467
</li>
7568
)

Diff for: web-app/src/containers/Tutorial/components/Steps.tsx

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import * as React from 'react'
22
import * as T from 'typings'
3-
import * as TT from 'typings/tutorial'
43
import Step from './Step'
54
import Hints from './Hints'
65

76
interface Props {
8-
steps: TT.Step[]
9-
displayAll: boolean
7+
steps: T.StepUI[]
8+
displayAll?: boolean
109
}
1110

1211
const styles = {
@@ -22,16 +21,16 @@ const Steps = (props: Props) => {
2221
return (
2322
<div css={styles.steps}>
2423
{/* @ts-ignore typings are different between UI & data */}
25-
{props.steps.map((step: TT.Step & { subtasks: null | { name: string; pass: boolean }[] }) => {
24+
{props.steps.map((step: T.StepUI) => {
2625
if (!step) {
2726
return null
2827
}
2928
return (
3029
<div key={step.id}>
3130
<Step
3231
key={step.id}
33-
status={step.status || 'INCOMPLETE'}
34-
displayAll={props.displayAll}
32+
status={step.status}
33+
displayAll={props.displayAll || false}
3534
content={step.content}
3635
subtasks={step.subtasks}
3736
/>

Diff for: web-app/src/containers/Tutorial/formatLevels.ts

+42-33
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,69 @@
11
import * as T from 'typings'
22
import * as TT from 'typings/tutorial'
33

4-
interface Props {
4+
interface Input {
55
progress: T.Progress
66
position: T.Position
77
levels: TT.Level[]
88
testStatus: T.TestStatus | null
99
}
1010

11+
type Output = {
12+
level: T.LevelUI
13+
stepIndex: number
14+
}
15+
1116
/*
1217
* Format levels to include:
1318
* - level.status = 'ACTIVE' | 'COMPLETE' | 'INCOMPLETE'
1419
* - step.status = 'ACTIVE' | 'COMPLETE' | 'INCOMPLETE' | 'FAIL'
15-
* - step.subtasks as { name: string, pass: boolean }[]
20+
* - step.subtasks as { name: string, status: 'ACTIVE' | 'COMPLETE' | 'INCOMPLETE' }[]
1621
*/
17-
const formatLevels = ({
18-
progress,
19-
position,
20-
levels,
21-
testStatus,
22-
}: Props): { levels: TT.Level[]; level: TT.Level; stepIndex: number } => {
22+
const formatLevels = ({ progress, position, levels, testStatus }: Input): Output => {
2323
// clone levels
24-
const formattedLevels = [...levels]
2524

26-
const level = formattedLevels.find((l: TT.Level) => l.id === position.levelId)
25+
const level: TT.Level | undefined = levels.find((l: TT.Level) => l.id === position.levelId)
2726

2827
if (!level) {
29-
throw new Error(`Level "${position.levelId}" not found`)
28+
throw new Error(`Level ${position.levelId} not found`)
3029
}
3130

32-
// add level status
33-
level.status = progress.levels[position.levelId] ? 'COMPLETE' : 'ACTIVE'
34-
35-
// add step status
36-
level.steps = level.steps.map((step: TT.Step) => {
37-
// label step status for step component
38-
let status: T.ProgressStatus = 'INCOMPLETE'
39-
if (progress.steps[step.id]) {
40-
status = 'COMPLETE'
41-
} else if (step.id === position.stepId) {
42-
status = 'ACTIVE'
43-
if (step.subtasks && step.subtasks) {
44-
step.subtasks.map((subtask: string, subtaskIndex: number) => ({
45-
name: subtask,
46-
pass: !!(testStatus?.summary ? testStatus.summary[subtaskIndex] : false),
47-
}))
31+
const levelUI: T.LevelUI = {
32+
...level,
33+
status: progress.levels[position.levelId] ? 'COMPLETE' : 'ACTIVE',
34+
steps: level.steps.map((step: TT.Step) => {
35+
// label step status for step component
36+
let status: T.ProgressStatus = 'INCOMPLETE'
37+
let subtasks
38+
if (progress.steps[step.id]) {
39+
status = 'COMPLETE'
40+
} else if (step.id === position.stepId) {
41+
status = 'ACTIVE'
42+
if (step.subtasks && step.subtasks) {
43+
subtasks = step.subtasks.map((subtask: string, subtaskIndex: number) => {
44+
let subtaskStatus: T.ProgressStatus = 'INCOMPLETE'
45+
// task is complete, subtasks must be complete
46+
if (status === 'COMPLETE') {
47+
subtaskStatus = 'COMPLETE'
48+
// task is active, check which are complete from test results
49+
} else if (status === 'ACTIVE') {
50+
subtaskStatus = !!(testStatus?.summary && testStatus.summary[subtaskIndex]) ? 'COMPLETE' : 'ACTIVE'
51+
}
52+
return {
53+
name: subtask,
54+
status: subtaskStatus,
55+
}
56+
})
57+
}
4858
}
49-
}
50-
return { ...step, status }
51-
})
52-
53-
let stepIndex = level.steps.findIndex((s: TT.Step) => s.status === 'ACTIVE')
59+
return { ...step, status, subtasks }
60+
}),
61+
}
62+
let stepIndex = levelUI.steps.findIndex((s: T.StepUI) => s.status === 'ACTIVE')
5463
if (stepIndex === -1) {
5564
stepIndex = level.steps.length
5665
}
57-
return { levels: formattedLevels, level, stepIndex }
66+
return { level: levelUI, stepIndex }
5867
}
5968

6069
export default formatLevels

Diff for: web-app/src/containers/Tutorial/index.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as React from 'react'
22
import * as T from 'typings'
3+
import './style.css'
34
import * as selectors from '../../services/selectors'
45
import SideMenu from './components/SideMenu'
56
import Level from './components/Level'
@@ -104,7 +105,7 @@ const TutorialPage = (props: PageProps) => {
104105

105106
const [page, setPage] = React.useState<'level' | 'settings' | 'review'>('level')
106107

107-
const { level, levels, stepIndex } = formatLevels({
108+
const { level, stepIndex } = formatLevels({
108109
progress,
109110
position,
110111
levels: tutorial.levels,
@@ -122,7 +123,7 @@ const TutorialPage = (props: PageProps) => {
122123
</div>
123124

124125
{page === 'level' && <Level level={level} />}
125-
{page === 'review' && <ReviewPage levels={levels} />}
126+
{page === 'review' && <ReviewPage levels={tutorial.levels} />}
126127
{/* {page === 'settings' && <SettingsPage />} */}
127128
</div>
128129
<div css={styles.footer}>

Diff for: web-app/src/containers/Tutorial/style.css

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/* remove visited styles from menu button */
2+
i.next-icon:visited {
3+
text-decoration: none;
4+
}

0 commit comments

Comments
 (0)