Skip to content

Commit 30eb1cd

Browse files
geshumingmartin-henz
authored andcommitted
Add template reset feature (#526)
* Added Template Reset Feature * Revert "Added Template Reset Feature" This reverts commit 3c1457e. * Revert "Revert "Added Template Reset Feature"" This reverts commit d59f4c9. * Resolved merge conflicts
1 parent 244cfe6 commit 30eb1cd

File tree

4 files changed

+127
-14
lines changed

4 files changed

+127
-14
lines changed

src/components/assessment/AssessmentWorkspace.tsx

100755100644
Lines changed: 70 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
1-
import { Button, Card, Dialog, NonIdealState, Spinner } from '@blueprintjs/core';
1+
import {
2+
Button,
3+
ButtonGroup,
4+
Card,
5+
Classes,
6+
Dialog,
7+
Intent,
8+
NonIdealState,
9+
Spinner
10+
} from '@blueprintjs/core';
211
import { IconNames } from '@blueprintjs/icons';
312
import * as React from 'react';
413

514
import { InterpreterOutput, IWorkspaceState } from '../../reducers/states';
615
import { beforeNow } from '../../utils/dateHelpers';
716
import { history } from '../../utils/history';
817
import { assessmentCategoryLink } from '../../utils/paramParseHelpers';
18+
import { controlButton } from '../commons';
919
import Markdown from '../commons/Markdown';
1020
import Workspace, { WorkspaceProps } from '../workspace';
1121
import { ControlBarProps } from '../workspace/ControlBar';
@@ -67,13 +77,15 @@ export type DispatchProps = {
6777

6878
class AssessmentWorkspace extends React.Component<
6979
AssessmentWorkspaceProps,
70-
{ showOverlay: boolean }
80+
{ showOverlay: boolean; showResetOverlay: boolean }
7181
> {
7282
public constructor(props: AssessmentWorkspaceProps) {
7383
super(props);
7484
this.state = {
75-
showOverlay: false
85+
showOverlay: false,
86+
showResetOverlay: false
7687
};
88+
this.props.handleEditorValueChange('');
7789
}
7890

7991
/**
@@ -86,6 +98,20 @@ class AssessmentWorkspace extends React.Component<
8698
if (this.props.questionId === 0 && this.props.notAttempted) {
8799
this.setState({ showOverlay: true });
88100
}
101+
if (this.props.assessment) {
102+
const question: IQuestion = this.props.assessment.questions[
103+
this.props.questionId >= this.props.assessment.questions.length
104+
? this.props.assessment.questions.length - 1
105+
: this.props.questionId
106+
];
107+
this.props.handleEditorValueChange(
108+
question.type === QuestionTypes.programming
109+
? question.answer !== null
110+
? ((question as IProgrammingQuestion).answer as string)
111+
: (question as IProgrammingQuestion).solutionTemplate
112+
: ''
113+
);
114+
}
89115
}
90116

91117
/**
@@ -119,24 +145,53 @@ class AssessmentWorkspace extends React.Component<
119145
</Card>
120146
</Dialog>
121147
);
148+
149+
const resetOverlay = (
150+
<Dialog
151+
className="assessment-reset"
152+
icon={IconNames.ERROR}
153+
isCloseButtonShown={false}
154+
isOpen={this.state.showResetOverlay}
155+
title="Confirmation: Reset editor?"
156+
>
157+
<div className={Classes.DIALOG_BODY}>
158+
<Markdown content="Are you sure you want to reset the template?" />
159+
<Markdown content="*Note this will not affect the saved copy of your code, unless you save over it.*" />
160+
</div>
161+
<div className={Classes.DIALOG_FOOTER}>
162+
<ButtonGroup>
163+
{controlButton('Cancel', null, () => this.setState({ showResetOverlay: false }), {
164+
minimal: false
165+
})}
166+
{controlButton(
167+
'Confirm',
168+
null,
169+
() => {
170+
this.setState({ showResetOverlay: false });
171+
this.props.handleEditorValueChange(
172+
(this.props.assessment!.questions[questionId] as IProgrammingQuestion)
173+
.solutionTemplate
174+
);
175+
this.props.handleUpdateHasUnsavedChanges(true);
176+
},
177+
{ minimal: false, intent: Intent.DANGER }
178+
)}
179+
</ButtonGroup>
180+
</div>
181+
</Dialog>
182+
);
122183
/* If questionId is out of bounds, set it to the max. */
123184
const questionId =
124185
this.props.questionId >= this.props.assessment.questions.length
125186
? this.props.assessment.questions.length - 1
126187
: this.props.questionId;
127188
const question: IQuestion = this.props.assessment.questions[questionId];
128-
const editorValue =
129-
question.type === QuestionTypes.programming
130-
? question.answer !== null
131-
? ((question as IProgrammingQuestion).answer as string)
132-
: (question as IProgrammingQuestion).solutionTemplate
133-
: null;
134189
const workspaceProps: WorkspaceProps = {
135190
controlBarProps: this.controlBarProps(this.props, questionId),
136191
editorProps:
137192
question.type === QuestionTypes.programming
138193
? {
139-
editorValue: editorValue!,
194+
editorValue: this.props.editorValue!,
140195
handleEditorEval: this.props.handleEditorEval,
141196
handleEditorValueChange: this.props.handleEditorValueChange,
142197
handleUpdateHasUnsavedChanges: this.props.handleUpdateHasUnsavedChanges
@@ -165,6 +220,7 @@ class AssessmentWorkspace extends React.Component<
165220
return (
166221
<div className="WorkspaceParent pt-dark">
167222
{overlay}
223+
{resetOverlay}
168224
<Workspace {...workspaceProps} />
169225
</div>
170226
);
@@ -194,7 +250,7 @@ class AssessmentWorkspace extends React.Component<
194250
? question.answer !== null
195251
? ((question as IProgrammingQuestion).answer as string)
196252
: (question as IProgrammingQuestion).solutionTemplate
197-
: null;
253+
: '';
198254
this.props.handleUpdateCurrentAssessmentId(assessmentId, questionId);
199255
this.props.handleResetWorkspace({ editorValue });
200256
this.props.handleClearContext(question.library);
@@ -286,6 +342,9 @@ class AssessmentWorkspace extends React.Component<
286342
this.props.assessment!.questions[questionId].id,
287343
this.props.editorValue!
288344
),
345+
onClickReset: () => {
346+
this.setState({ showResetOverlay: true });
347+
},
289348
questionProgress: [questionId + 1, this.props.assessment!.questions.length],
290349
sourceChapter: this.props.assessment!.questions[questionId].library.chapter
291350
};

src/components/assessment/__tests__/__snapshots__/AssessmentWorkspace.tsx.snap

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,22 @@ exports[`AssessmentWorkspace page with MCQ question renders correctly 1`] = `
1010
<Blueprint2.Button className=\\"assessment-briefing-button\\" onClick={[Function: onClick]} text=\\"Continue\\" />
1111
</Blueprint2.Card>
1212
</Blueprint2.Dialog>
13+
<Blueprint2.Dialog className=\\"assessment-reset\\" icon=\\"error\\" isCloseButtonShown={false} isOpen={false} title=\\"Confirmation: Reset editor?\\" canOutsideClickClose={true}>
14+
<div className=\\"pt-dialog-body\\">
15+
<Markdown content=\\"Are you sure you want to reset the template?\\" />
16+
<Markdown content=\\"*Note this will not affect the saved copy of your code, unless you save over it.*\\" />
17+
</div>
18+
<div className=\\"pt-dialog-footer\\">
19+
<Blueprint2.ButtonGroup>
20+
<Blueprint2.Button disabled={false} fill={false} intent=\\"none\\" minimal={false} className=\\"\\" onClick={[Function]}>
21+
Cancel
22+
</Blueprint2.Button>
23+
<Blueprint2.Button disabled={false} fill={false} intent=\\"danger\\" minimal={false} className=\\"\\" onClick={[Function]}>
24+
Confirm
25+
</Blueprint2.Button>
26+
</Blueprint2.ButtonGroup>
27+
</div>
28+
</Blueprint2.Dialog>
1329
<Workspace controlBarProps={{...}} editorProps={[undefined]} editorWidth=\\"50%\\" handleEditorWidthChange={[Function: handleEditorWidthChange]} handleSideContentHeightChange={[Function: handleSideContentHeightChange]} hasUnsavedChanges={false} mcqProps={{...}} sideContentHeight={[undefined]} sideContentProps={{...}} replProps={{...}} />
1430
</div>"
1531
`;
@@ -22,6 +38,22 @@ exports[`AssessmentWorkspace page with overdue assessment renders correctly 1`]
2238
<Blueprint2.Button className=\\"assessment-briefing-button\\" onClick={[Function: onClick]} text=\\"Continue\\" />
2339
</Blueprint2.Card>
2440
</Blueprint2.Dialog>
41+
<Blueprint2.Dialog className=\\"assessment-reset\\" icon=\\"error\\" isCloseButtonShown={false} isOpen={false} title=\\"Confirmation: Reset editor?\\" canOutsideClickClose={true}>
42+
<div className=\\"pt-dialog-body\\">
43+
<Markdown content=\\"Are you sure you want to reset the template?\\" />
44+
<Markdown content=\\"*Note this will not affect the saved copy of your code, unless you save over it.*\\" />
45+
</div>
46+
<div className=\\"pt-dialog-footer\\">
47+
<Blueprint2.ButtonGroup>
48+
<Blueprint2.Button disabled={false} fill={false} intent=\\"none\\" minimal={false} className=\\"\\" onClick={[Function]}>
49+
Cancel
50+
</Blueprint2.Button>
51+
<Blueprint2.Button disabled={false} fill={false} intent=\\"danger\\" minimal={false} className=\\"\\" onClick={[Function]}>
52+
Confirm
53+
</Blueprint2.Button>
54+
</Blueprint2.ButtonGroup>
55+
</div>
56+
</Blueprint2.Dialog>
2557
<Workspace controlBarProps={{...}} editorProps={{...}} editorWidth=\\"50%\\" handleEditorWidthChange={[Function: handleEditorWidthChange]} handleSideContentHeightChange={[Function: handleSideContentHeightChange]} hasUnsavedChanges={false} mcqProps={{...}} sideContentHeight={[undefined]} sideContentProps={{...}} replProps={{...}} />
2658
</div>"
2759
`;
@@ -34,6 +66,22 @@ exports[`AssessmentWorkspace page with programming question renders correctly 1`
3466
<Blueprint2.Button className=\\"assessment-briefing-button\\" onClick={[Function: onClick]} text=\\"Continue\\" />
3567
</Blueprint2.Card>
3668
</Blueprint2.Dialog>
69+
<Blueprint2.Dialog className=\\"assessment-reset\\" icon=\\"error\\" isCloseButtonShown={false} isOpen={false} title=\\"Confirmation: Reset editor?\\" canOutsideClickClose={true}>
70+
<div className=\\"pt-dialog-body\\">
71+
<Markdown content=\\"Are you sure you want to reset the template?\\" />
72+
<Markdown content=\\"*Note this will not affect the saved copy of your code, unless you save over it.*\\" />
73+
</div>
74+
<div className=\\"pt-dialog-footer\\">
75+
<Blueprint2.ButtonGroup>
76+
<Blueprint2.Button disabled={false} fill={false} intent=\\"none\\" minimal={false} className=\\"\\" onClick={[Function]}>
77+
Cancel
78+
</Blueprint2.Button>
79+
<Blueprint2.Button disabled={false} fill={false} intent=\\"danger\\" minimal={false} className=\\"\\" onClick={[Function]}>
80+
Confirm
81+
</Blueprint2.Button>
82+
</Blueprint2.ButtonGroup>
83+
</div>
84+
</Blueprint2.Dialog>
3785
<Workspace controlBarProps={{...}} editorProps={{...}} editorWidth=\\"50%\\" handleEditorWidthChange={[Function: handleEditorWidthChange]} handleSideContentHeightChange={[Function: handleSideContentHeightChange]} hasUnsavedChanges={false} mcqProps={{...}} sideContentHeight={[undefined]} sideContentProps={{...}} replProps={{...}} />
3886
</div>"
3987
`;

src/components/workspace/ControlBar.tsx

100755100644
Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export type ControlBarProps = {
3737
onClickPrevious?(): any;
3838
onClickReturn?(): any;
3939
onClickSave?(): any;
40+
onClickReset?(): any;
4041
};
4142

4243
interface IChapter {
@@ -62,7 +63,8 @@ class ControlBar extends React.PureComponent<ControlBarProps, {}> {
6263
hasShareButton: true,
6364
onClickNext: () => {},
6465
onClickPrevious: () => {},
65-
onClickSave: () => {}
66+
onClickSave: () => {},
67+
onClickReset: () => {}
6668
};
6769

6870
private shareInputElem: HTMLInputElement;
@@ -130,6 +132,9 @@ class ControlBar extends React.PureComponent<ControlBarProps, {}> {
130132
this.props.hasChapterSelect && this.props.externalLibraryName !== undefined
131133
? externalSelect(this.props.externalLibraryName, this.props.handleExternalSelect!)
132134
: undefined;
135+
const resetButton = this.props.hasSaveButton
136+
? controlButton('Reset', IconNames.REPEAT, this.props.onClickReset)
137+
: undefined;
133138
const startAutorunButton = this.props.hasEditorAutorunButton
134139
? controlButton('Autorun', IconNames.PLAY, this.props.handleToggleEditorAutorun)
135140
: undefined;
@@ -140,7 +145,7 @@ class ControlBar extends React.PureComponent<ControlBarProps, {}> {
140145
<div className="ControlBar_editor pt-button-group">
141146
{this.props.isEditorAutorun ? undefined : this.props.isRunning ? stopButton : runButton}
142147
{saveButton}
143-
{shareButton} {chapterSelectButton} {externalSelectButton}
148+
{shareButton} {chapterSelectButton} {externalSelectButton} {resetButton}
144149
{this.props.isEditorAutorun ? stopAutorunButton : startAutorunButton}
145150
</div>
146151
);

src/styles/_academy.scss

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@
129129
}
130130
}
131131

132-
.betcha-dialog {
132+
.betcha-dialog,
133+
.assessment-reset {
133134
span.warning {
134135
font-weight: bold;
135136
color: firebrick;

0 commit comments

Comments
 (0)