Skip to content

Game: Allow consistent, automatic switching between Game and Assessments #3105

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Apr 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions public/assets/mockChapter0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ objectives
finish

gameStartActions
// replace 173 with assessment id
show_dialogue(welcome) if userstate.assessments.173
show_dialogue(unwelcome) if !userstate.assessments.173
// replace S0 with assessment number
show_dialogue(welcome) if userstate.assessments.S0
show_dialogue(unwelcome) if !userstate.assessments.S0

checkpointCompleteActions
show_dialogue(done)
Expand Down Expand Up @@ -96,8 +96,8 @@ dialogues
1
@scottie, sad
You haven't finished assessment
Finish assessment 173 first and come back?
navigate_to_assessment(173)
Finish assessment S0 first and come back?
navigate_to_assessment(S0)
goto 2
2
@scottie
Expand All @@ -113,7 +113,7 @@ dialogues
Hmmm
update_assessment_status*()
Let me check
goto 1 if !userstate.assessments.173 else 3
goto 1 if !userstate.assessments.S0 else 3

what, What should I do now, Scottie?
@you
Expand Down
10 changes: 10 additions & 0 deletions src/commons/application/actions/__tests__/SessionActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ test('setAssessmentConfigurations generates correct action object', () => {
isManuallyGraded: true,
isGradingAutoPublished: false,
displayInDashboard: true,
isMinigame: false,
hasTokenCounter: false,
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 48,
Expand All @@ -275,6 +276,7 @@ test('setAssessmentConfigurations generates correct action object', () => {
isManuallyGraded: true,
isGradingAutoPublished: false,
displayInDashboard: true,
isMinigame: false,
hasTokenCounter: false,
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 48,
Expand All @@ -286,6 +288,7 @@ test('setAssessmentConfigurations generates correct action object', () => {
isManuallyGraded: true,
isGradingAutoPublished: false,
displayInDashboard: true,
isMinigame: false,
hasTokenCounter: false,
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 48,
Expand Down Expand Up @@ -714,6 +717,7 @@ test('updateAssessmentTypes generates correct action object', () => {
isManuallyGraded: true,
isGradingAutoPublished: false,
displayInDashboard: true,
isMinigame: false,
hasTokenCounter: false,
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 48,
Expand All @@ -725,6 +729,7 @@ test('updateAssessmentTypes generates correct action object', () => {
isManuallyGraded: true,
isGradingAutoPublished: false,
displayInDashboard: true,
isMinigame: false,
hasTokenCounter: false,
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 48,
Expand All @@ -736,6 +741,7 @@ test('updateAssessmentTypes generates correct action object', () => {
isManuallyGraded: false,
isGradingAutoPublished: true,
displayInDashboard: true,
isMinigame: false,
hasTokenCounter: false,
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 48,
Expand All @@ -747,6 +753,7 @@ test('updateAssessmentTypes generates correct action object', () => {
isManuallyGraded: true,
isGradingAutoPublished: false,
displayInDashboard: true,
isMinigame: false,
hasTokenCounter: false,
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 48,
Expand All @@ -758,6 +765,7 @@ test('updateAssessmentTypes generates correct action object', () => {
isManuallyGraded: false,
isGradingAutoPublished: false,
displayInDashboard: true,
isMinigame: false,
hasTokenCounter: false,
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 0,
Expand All @@ -769,6 +777,7 @@ test('updateAssessmentTypes generates correct action object', () => {
isManuallyGraded: true,
isGradingAutoPublished: false,
displayInDashboard: true,
isMinigame: false,
hasTokenCounter: false,
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 48,
Expand All @@ -789,6 +798,7 @@ test('deleteAssessmentConfig generates correct action object', () => {
isManuallyGraded: true,
isGradingAutoPublished: false,
displayInDashboard: true,
isMinigame: false,
hasTokenCounter: false,
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 48,
Expand Down
3 changes: 3 additions & 0 deletions src/commons/application/reducers/__tests__/SessionReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ test('SET_ASSESSMENT_CONFIGURATIONS works correctly', () => {
isManuallyGraded: false,
isGradingAutoPublished: false,
displayInDashboard: true,
isMinigame: false,
hasTokenCounter: false,
hasVotingFeatures: false
},
Expand All @@ -161,6 +162,7 @@ test('SET_ASSESSMENT_CONFIGURATIONS works correctly', () => {
isManuallyGraded: false,
isGradingAutoPublished: false,
displayInDashboard: true,
isMinigame: false,
hasTokenCounter: false,
hasVotingFeatures: false
},
Expand All @@ -175,6 +177,7 @@ test('SET_ASSESSMENT_CONFIGURATIONS works correctly', () => {
isManuallyGraded: false,
isGradingAutoPublished: false,
displayInDashboard: true,
isMinigame: false,
hasTokenCounter: false,
hasVotingFeatures: false
}
Expand Down
2 changes: 2 additions & 0 deletions src/commons/assessment/AssessmentTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ export type Assessment = {
globalDeployment?: Library; // For mission control
graderDeployment?: Library; // For mission control
hasTokenCounter?: boolean;
isMinigame?: boolean;
id: number;
longSummary: string;
missionPDF: string;
Expand All @@ -105,6 +106,7 @@ export type AssessmentConfiguration = {
isManuallyGraded: boolean;
isGradingAutoPublished: boolean;
displayInDashboard: boolean;
isMinigame: boolean;
hoursBeforeEarlyXpDecay: number;
earlySubmissionXp: number;
hasTokenCounter: boolean;
Expand Down
1 change: 1 addition & 0 deletions src/commons/assessment/__tests__/Assessment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const mockAssessmentConfig: AssessmentConfiguration = {
isManuallyGraded: true,
isGradingAutoPublished: false,
displayInDashboard: true,
isMinigame: false,
hasTokenCounter: false,
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 48,
Expand Down
24 changes: 24 additions & 0 deletions src/commons/assessmentWorkspace/AssessmentWorkspace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ const AssessmentWorkspace: React.FC<AssessmentWorkspaceProps> = props => {
const [isSaving, setIsSaving] = useState(false);
const [showResetTemplateOverlay, setShowResetTemplateOverlay] = useState(false);
const [sessionId, setSessionId] = useState('');
const [isSubmitted, setIsSubmitted] = useState(false);
const { isMobileBreakpoint } = useResponsive();

const assessment = useTypedSelector(state => state.session.assessments[props.assessmentId]);
Expand Down Expand Up @@ -600,6 +601,10 @@ const AssessmentWorkspace: React.FC<AssessmentWorkspaceProps> = props => {
setSelectedTab(SideContentType.questionOverview);
};
const onClickReturn = () => navigate(listingPath);
const onClickSubmit = () => {
dispatch(SessionActions.submitAssessment(assessment.id));
setIsSubmitted(true);
};

const onClickSave = () => {
if (isSaving) return;
Expand Down Expand Up @@ -664,8 +669,14 @@ const AssessmentWorkspace: React.FC<AssessmentWorkspaceProps> = props => {
? onClickProgress(onClickReturn, question, editorTestcases, isBlocked)
: onClickReturn
}
onClickSubmit={
question.blocking
? onClickProgress(onClickSubmit, question, editorTestcases, isBlocked)
: onClickSubmit
}
questionProgress={questionProgress}
key="next_question"
submitOnFinish={assessment.isMinigame}
/>
);

Expand Down Expand Up @@ -834,6 +845,18 @@ const AssessmentWorkspace: React.FC<AssessmentWorkspaceProps> = props => {
</Dialog>
);

const submissionOverlay = (
<Dialog className="assessment-briefing" isOpen={isSubmitted}>
<Card>
<Markdown
content={`## ${assessment.type.substring(0, assessment.type.length - 1)} complete!
You've successfully submitted this ${assessment.type.substring(0, assessment.type.length - 1)}!
It is safe to close this window.`}
/>
</Card>
</Dialog>
);

const closeOverlay = () => setShowResetTemplateOverlay(false);
const resetTemplateOverlay = (
<Dialog
Expand Down Expand Up @@ -942,6 +965,7 @@ const AssessmentWorkspace: React.FC<AssessmentWorkspaceProps> = props => {
};
return (
<div className={classNames('WorkspaceParent', Classes.DARK)}>
{submissionOverlay}
{overlay}
{resetTemplateOverlay}
{!isMobileBreakpoint ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const defaultProps = assertType<AssessmentWorkspaceProps>()({
isManuallyGraded: true,
isGradingAutoPublished: false,
displayInDashboard: true,
isMinigame: false,
hasTokenCounter: false,
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 48,
Expand Down
9 changes: 8 additions & 1 deletion src/commons/controlBar/ControlBarNextButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,29 @@ import React from 'react';

import ControlButton from '../ControlButton';
import { ControlBarReturnToAcademyButton } from './ControlBarReturnToAcademyButton';
import { ControlBarSubmit } from './ControlBarSubmit';

type ControlBarNextButtonProps = DispatchProps & StateProps;

type DispatchProps = {
onClickNext?(): any;
onClickReturn?(): any;
onClickSubmit?(): any;
};

type StateProps = {
key: string;
questionProgress: [number, number] | null;
submitOnFinish?: boolean;
};

export const ControlBarNextButton: React.FC<ControlBarNextButtonProps> = props => {
return props.questionProgress![0] === props.questionProgress![1] ? (
<ControlBarReturnToAcademyButton onClick={props.onClickReturn} key="return_to_academy" />
props.submitOnFinish ? (
<ControlBarSubmit onClick={props.onClickSubmit} />
) : (
<ControlBarReturnToAcademyButton onClick={props.onClickReturn} key="return_to_academy" />
)
) : (
<ControlButton
label="Next"
Expand Down
19 changes: 19 additions & 0 deletions src/commons/controlBar/ControlBarSubmit.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { IconNames } from '@blueprintjs/icons';
import React from 'react';

import ControlButton from '../ControlButton';

type Props = {
onClick?(): any;
};

export const ControlBarSubmit: React.FC<Props> = ({ onClick }) => {
return (
<ControlButton
label="Submit"
icon={IconNames.ARROW_RIGHT}
onClick={onClick}
options={{ iconOnRight: true }}
/>
);
};
8 changes: 8 additions & 0 deletions src/commons/mocks/AssessmentMocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const mockAssessmentConfigurations: AssessmentConfiguration[][] = [
isManuallyGraded: true,
isGradingAutoPublished: false,
displayInDashboard: true,
isMinigame: false,
hoursBeforeEarlyXpDecay: 48,
hasTokenCounter: false,
hasVotingFeatures: false,
Expand All @@ -32,6 +33,7 @@ export const mockAssessmentConfigurations: AssessmentConfiguration[][] = [
isManuallyGraded: true,
isGradingAutoPublished: false,
displayInDashboard: true,
isMinigame: false,
hoursBeforeEarlyXpDecay: 48,
hasTokenCounter: false,
hasVotingFeatures: false,
Expand All @@ -43,6 +45,7 @@ export const mockAssessmentConfigurations: AssessmentConfiguration[][] = [
isManuallyGraded: false,
isGradingAutoPublished: true,
displayInDashboard: true,
isMinigame: false,
hoursBeforeEarlyXpDecay: 48,
hasTokenCounter: false,
hasVotingFeatures: false,
Expand All @@ -54,6 +57,7 @@ export const mockAssessmentConfigurations: AssessmentConfiguration[][] = [
isManuallyGraded: true,
isGradingAutoPublished: false,
displayInDashboard: true,
isMinigame: false,
hoursBeforeEarlyXpDecay: 48,
hasTokenCounter: false,
hasVotingFeatures: true,
Expand All @@ -65,6 +69,7 @@ export const mockAssessmentConfigurations: AssessmentConfiguration[][] = [
isManuallyGraded: true,
isGradingAutoPublished: false,
displayInDashboard: true,
isMinigame: false,
hoursBeforeEarlyXpDecay: 48,
hasTokenCounter: false,
hasVotingFeatures: false,
Expand All @@ -78,6 +83,7 @@ export const mockAssessmentConfigurations: AssessmentConfiguration[][] = [
isManuallyGraded: true,
isGradingAutoPublished: false,
displayInDashboard: true,
isMinigame: false,
hoursBeforeEarlyXpDecay: 48,
hasTokenCounter: false,
hasVotingFeatures: false,
Expand All @@ -89,6 +95,7 @@ export const mockAssessmentConfigurations: AssessmentConfiguration[][] = [
isManuallyGraded: true,
isGradingAutoPublished: false,
displayInDashboard: true,
isMinigame: false,
hoursBeforeEarlyXpDecay: 48,
hasTokenCounter: false,
hasVotingFeatures: false,
Expand All @@ -100,6 +107,7 @@ export const mockAssessmentConfigurations: AssessmentConfiguration[][] = [
isManuallyGraded: true,
isGradingAutoPublished: false,
displayInDashboard: true,
isMinigame: false,
hoursBeforeEarlyXpDecay: 48,
hasTokenCounter: false,
hasVotingFeatures: false,
Expand Down
1 change: 1 addition & 0 deletions src/commons/profile/__tests__/Profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const assessmentConfigurations: AssessmentConfiguration[] = [
isManuallyGraded: false,
isGradingAutoPublished: false,
displayInDashboard: false,
isMinigame: false,
hasTokenCounter: false,
hasVotingFeatures: false,
hoursBeforeEarlyXpDecay: 0,
Expand Down
1 change: 1 addition & 0 deletions src/commons/sagas/BackendSaga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -957,6 +957,7 @@ const newBackendSagaTwo = combineSagaHandlers(sagaActions, {
isManuallyGraded: true,
isGradingAutoPublished: false,
displayInDashboard: true,
isMinigame: false,
hoursBeforeEarlyXpDecay: 0,
hasTokenCounter: false,
hasVotingFeatures: false,
Expand Down
Loading
Loading