Skip to content

Commit 319ad02

Browse files
authored
Mission editing slang (#503)
* Removed previous button on first question, added divider * Yarn format * Changeded help description * fix import for firefox * max width for globals * symbols aligned * increase abstraction removed numberRange from textArea Reduced save frequency of solutionTemplate * manage questions give warning * UI change for deployment tab * fixed maxGrade and maxXP calculation * added local/global switch * adjust mcq options * split question template tab added suggested answer editing * swap answer and solutionTemplate internal change * add reading * add grading deployment * clone question shift question added * fixed symbol formating
1 parent c5c99e2 commit 319ad02

File tree

5 files changed

+82
-37
lines changed

5 files changed

+82
-37
lines changed

src/components/incubator/EditingWorkspace.tsx

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import * as React from 'react';
44

55
import { InterpreterOutput, IWorkspaceState } from '../../reducers/states';
66
import { history } from '../../utils/history';
7-
import { assessmentCategoryLink } from '../../utils/paramParseHelpers';
87
import {
98
retrieveLocalAssessment,
109
storeLocalAssessment,
@@ -55,7 +54,6 @@ export type OwnProps = {
5554
questionId: number;
5655
assessmentOverview: IAssessmentOverview;
5756
updateAssessmentOverview: (overview: IAssessmentOverview) => void;
58-
listingPath?: string;
5957
notAttempted: boolean;
6058
closeDate: string;
6159
};
@@ -110,12 +108,7 @@ class AssessmentWorkspace extends React.Component<AssessmentWorkspaceProps, ISta
110108
*/
111109
public componentDidMount() {
112110
if (this.props.assessment) {
113-
const question: IQuestion = this.props.assessment.questions[this.formatedQuestionId()];
114-
const editorValue =
115-
question.type === QuestionTypes.programming
116-
? ((question as IProgrammingQuestion).solutionTemplate as string)
117-
: '//If you see this, this is a bug. Please report bug.';
118-
this.props.handleEditorValueChange(editorValue);
111+
this.resetEditorValue();
119112
this.setState({
120113
originalMaxGrade: this.getMaxMarks('maxGrade'),
121114
originalMaxXp: this.getMaxMarks('maxXp')
@@ -295,6 +288,15 @@ class AssessmentWorkspace extends React.Component<AssessmentWorkspaceProps, ISta
295288
this.props.handleClearContext(library);
296289
};
297290

291+
private resetEditorValue = () => {
292+
const question: IQuestion = this.state.assessment!.questions[this.formatedQuestionId()];
293+
const editorValue =
294+
question.type === QuestionTypes.programming
295+
? ((question as IProgrammingQuestion).solutionTemplate as string)
296+
: '//If you see this, this is a bug. Please report bug.';
297+
this.props.handleEditorValueChange(editorValue);
298+
};
299+
298300
private handleSave = () => {
299301
this.setState({
300302
hasUnsavedChanges: false
@@ -345,7 +347,9 @@ class AssessmentWorkspace extends React.Component<AssessmentWorkspaceProps, ISta
345347
this.setState({
346348
assessment: assessmentVal
347349
});
350+
this.handleRefreshLibrary();
348351
this.handleSave();
352+
this.resetEditorValue();
349353
};
350354

351355
private handleChangeActiveTab = (tab: number) => {
@@ -522,9 +526,7 @@ class AssessmentWorkspace extends React.Component<AssessmentWorkspaceProps, ISta
522526
props: AssessmentWorkspaceProps,
523527
questionId: number
524528
) => {
525-
const listingPath =
526-
this.props.listingPath ||
527-
`/academy/${assessmentCategoryLink(this.state.assessment!.category)}`;
529+
const listingPath = '/incubator';
528530
const assessmentWorkspacePath = listingPath + `/${this.state.assessment!.id.toString()}`;
529531
return {
530532
handleEditorEval: this.props.handleEditorEval,

src/components/incubator/assessmentTemplates.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ export const mcqTemplate = (): IMCQQuestion => {
9797
],
9898
id: 2,
9999
library: emptyLibrary(),
100+
graderLibrary: emptyLibrary(),
100101
type: 'mcq',
101102
solution: 0,
102103
grader: {

src/components/incubator/editingWorkspaceSideContent/DeploymentTab.tsx

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ export class DeploymentTab extends React.Component<IProps, { activeTab: number }
4848
{this.props.label + ' Deployment'}
4949
<br />
5050
{this.deploymentTab()}
51-
}
5251
</div>
5352
);
5453
} else {
@@ -71,26 +70,20 @@ export class DeploymentTab extends React.Component<IProps, { activeTab: number }
7170
// const deploymentDisp = this.props.isGlobalDeployment ? 'Global Deployment' : 'Local Deployment';
7271
const symbols = deployment.external.symbols.map((symbol, i) => (
7372
<tr key={i}>
74-
<td style={{ width: '520px' }}>
75-
{this.textareaContent(deploymentPath.concat(['external', 'symbols', i]))}
73+
<td>{this.textareaContent(deploymentPath.concat(['external', 'symbols', i]))}</td>
74+
<td style={{ width: '100px' }}>
75+
{controlButton('Delete', IconNames.MINUS, this.handleSymbolDelete(i))}
7676
</td>
77-
<td>{controlButton('Delete', IconNames.MINUS, this.handleSymbolDelete(i))}</td>
7877
</tr>
7978
));
8079

8180
const globals = deployment.globals.map((symbol, i) => (
8281
<tr key={i}>
83-
<td className="col-xs-3" style={{ height: '2rem', width: '10rem', overflow: 'auto' }}>
84-
<div style={{ height: '2rem', width: '10rem', overflow: 'auto' }}>
85-
{this.textareaContent(deploymentPath.concat(['globals', i, 0]))}
86-
</div>
82+
<td style={{ width: '170px' }}>
83+
{this.textareaContent(deploymentPath.concat(['globals', i, 0]))}
8784
</td>
88-
<td className="col-xs-7" style={{ height: '2rem', width: '20rem', overflow: 'auto' }}>
89-
<div style={{ height: '2rem', width: '20rem', overflow: 'auto' }}>
90-
{this.globalValueTextareaContent(i)}
91-
</div>
92-
</td>
93-
<td className="col-xs-2">
85+
<td>{this.globalValueTextareaContent(i)}</td>
86+
<td style={{ width: '90px' }}>
9487
{controlButton('Delete', IconNames.MINUS, this.handleGlobalDelete(i))}
9588
</td>
9689
</tr>
@@ -109,7 +102,9 @@ export class DeploymentTab extends React.Component<IProps, { activeTab: number }
109102
<br />
110103
<div>Symbols:</div>
111104
<br />
112-
<table style={{ width: '100%' }}>{symbols}</table>
105+
<table style={{ width: '100%' }}>
106+
<tbody>{symbols}</tbody>
107+
</table>
113108
{controlButton('New Symbol', IconNames.PLUS, this.handleNewSymbol)}
114109
</React.Fragment>
115110
);
@@ -118,7 +113,9 @@ export class DeploymentTab extends React.Component<IProps, { activeTab: number }
118113
<React.Fragment>
119114
<div>Globals:</div>
120115
<br />
121-
<table style={{ width: '100%' }}>{globals}</table>
116+
<table style={{ width: '100%', borderSpacing: '5px' }}>
117+
<tbody>{globals}</tbody>
118+
</table>
122119
{controlButton('New Global', IconNames.PLUS, this.handleNewGlobal)}
123120
</React.Fragment>
124121
);
@@ -191,7 +188,7 @@ export class DeploymentTab extends React.Component<IProps, { activeTab: number }
191188
global[1] = altEval(global[2]!);
192189
this.props.updateAssessment(assessment);
193190
} catch (e) {
194-
global[2] = 'Invalid Expression';
191+
global[2] = '"Invalid Expression"';
195192
}
196193
};
197194

src/components/incubator/editingWorkspaceSideContent/ManageQuestionTab.tsx

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { ButtonGroup, Classes, Dialog, Intent } from '@blueprintjs/core';
22
import { IconNames } from '@blueprintjs/icons';
33
import * as React from 'react';
44

5+
import { history } from '../../../utils/history';
56
import { IAssessment } from '../../assessment/assessmentShape';
67
import { controlButton } from '../../commons';
78
import Markdown from '../../commons/Markdown';
@@ -38,8 +39,19 @@ export class ManageQuestionTab extends React.Component<IProps, IState> {
3839
}
3940

4041
private manageQuestionTab = () => {
42+
const index = this.props.questionId;
4143
return (
4244
<div>
45+
{controlButton(
46+
'Clone Current Question',
47+
IconNames.DOCUMENT,
48+
this.confirmSave(
49+
this.makeQuestion(() =>
50+
deepCopy(this.props.assessment.questions[this.props.questionId])
51+
)
52+
)
53+
)}
54+
<br />
4355
{controlButton(
4456
'Insert Programming Question',
4557
IconNames.FONT,
@@ -50,28 +62,57 @@ export class ManageQuestionTab extends React.Component<IProps, IState> {
5062
IconNames.CONFIRM,
5163
this.confirmSave(this.makeQuestion(mcqTemplate))
5264
)}
65+
<br />
5366
{controlButton(
5467
'Delete Current Question',
5568
IconNames.REMOVE,
56-
this.confirmSave(this.deleteQn)
69+
this.confirmSave(this.deleteQuestion)
5770
)}
71+
<br />
72+
{index > 0
73+
? controlButton(
74+
'Shift Question Left',
75+
IconNames.CARET_LEFT,
76+
this.confirmSave(this.shiftQuestion(-1))
77+
)
78+
: undefined}
79+
{index < this.props.assessment.questions.length - 1
80+
? controlButton(
81+
'Shift Question Right',
82+
IconNames.CARET_RIGHT,
83+
this.confirmSave(this.shiftQuestion(1))
84+
)
85+
: undefined}
5886
</div>
5987
);
6088
};
6189

62-
private makeQuestion = (template: () => any) => () => {
90+
private shiftQuestion = (dir: number) => () => {
6391
const assessment = this.props.assessment;
6492
const index = this.props.questionId;
65-
let questions = assessment.questions;
66-
questions = questions
67-
.slice(0, index)
68-
.concat([template()])
69-
.concat(questions.slice(index));
93+
const newIndex = index + dir;
94+
if (newIndex >= 0 && newIndex < assessment.questions.length) {
95+
const question = assessment.questions[index];
96+
const questions = assessment.questions;
97+
questions[index] = questions[newIndex];
98+
questions[newIndex] = question;
99+
assessment.questions = questions;
100+
this.props.updateAssessment(assessment);
101+
history.push('/incubator/-1/' + newIndex.toString());
102+
}
103+
};
104+
105+
private makeQuestion = (template: () => any) => () => {
106+
const assessment = this.props.assessment;
107+
const index = this.props.questionId + 1;
108+
const questions = assessment.questions;
109+
questions.splice(index, 0, template());
70110
assessment.questions = questions;
71111
this.props.updateAssessment(assessment);
112+
history.push('/incubator/-1/' + index.toString());
72113
};
73114

74-
private deleteQn = () => {
115+
private deleteQuestion = () => {
75116
const assessment = this.props.assessment;
76117
let questions = assessment.questions;
77118
const index = this.props.questionId;
@@ -129,4 +170,8 @@ export class ManageQuestionTab extends React.Component<IProps, IState> {
129170
);
130171
}
131172

173+
const deepCopy = (arr: any) => {
174+
return JSON.parse(JSON.stringify(arr));
175+
};
176+
132177
export default ManageQuestionTab;

src/components/incubator/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class Assessment extends React.Component<IAssessmentProps, State> {
6767
};
6868
return (
6969
<div className="Academy">
70-
<EditingWorkspaceContainer {...assessmentProps} listingPath="/incubator" />
70+
<EditingWorkspaceContainer {...assessmentProps} />
7171
</div>
7272
);
7373
}

0 commit comments

Comments
 (0)