diff --git a/src/assets/wise5/authoringTool/project-authoring-step/project-authoring-step.component.ts b/src/assets/wise5/authoringTool/project-authoring-step/project-authoring-step.component.ts index e842eec3900..03c92052a8e 100644 --- a/src/assets/wise5/authoringTool/project-authoring-step/project-authoring-step.component.ts +++ b/src/assets/wise5/authoringTool/project-authoring-step/project-authoring-step.component.ts @@ -8,6 +8,7 @@ import { DeleteNodeService } from '../../services/deleteNodeService'; import { CopyNodesService } from '../../services/copyNodesService'; import { DeleteTranslationsService } from '../../services/deleteTranslationsService'; import { CopyTranslationsService } from '../../services/copyTranslationsService'; +import { ConstraintService } from '../../services/constraintService'; @Component({ selector: 'project-authoring-step', @@ -24,6 +25,7 @@ export class ProjectAuthoringStepComponent { constructor( private copyNodesService: CopyNodesService, private copyTranslationsService: CopyTranslationsService, + private constraintService: ConstraintService, private dataService: TeacherDataService, private deleteNodeService: DeleteNodeService, private deleteTranslationsService: DeleteTranslationsService, @@ -66,11 +68,11 @@ export class ProjectAuthoringStepComponent { } protected nodeHasConstraint(nodeId: string): boolean { - return this.projectService.nodeHasConstraint(nodeId); + return this.getNumberOfConstraintsOnNode(nodeId) > 0; } protected getNumberOfConstraintsOnNode(nodeId: string): number { - return this.projectService.getConstraintsOnNode(nodeId).length; + return this.projectService.getNode(nodeId).getConstraints().length; } protected nodeHasRubric(nodeId: string): boolean { @@ -78,14 +80,7 @@ export class ProjectAuthoringStepComponent { } protected getConstraintDescriptions(nodeId: string): string { - let constraintDescriptions = ''; - const constraints = this.projectService.getConstraintsOnNode(nodeId); - for (let c = 0; c < constraints.length; c++) { - let constraint = constraints[c]; - let description = this.projectService.getConstraintDescription(constraint); - constraintDescriptions += c + 1 + ' - ' + description + '\n'; - } - return constraintDescriptions; + return this.constraintService.getConstraintDescriptions(nodeId); } protected constraintIconClicked(nodeId: string): void { diff --git a/src/assets/wise5/common/Node.ts b/src/assets/wise5/common/Node.ts index 30519776246..6976bd0655d 100644 --- a/src/assets/wise5/common/Node.ts +++ b/src/assets/wise5/common/Node.ts @@ -196,4 +196,8 @@ export class Node { componentContent.connectedComponents.length !== 0 ); } + + getConstraints(): any[] { + return this.constraints; + } } diff --git a/src/assets/wise5/services/constraintService.ts b/src/assets/wise5/services/constraintService.ts index b7ebd4a3faf..5954069f182 100644 --- a/src/assets/wise5/services/constraintService.ts +++ b/src/assets/wise5/services/constraintService.ts @@ -270,4 +270,183 @@ export class ConstraintService { hasActiveConstraints(): boolean { return this.activeConstraints.length > 0; } + + getConstraintDescriptions(nodeId: string): string { + let constraintDescriptions = ''; + const constraints = this.projectService.getNode(nodeId).getConstraints(); + for (let c = 0; c < constraints.length; c++) { + const constraint = constraints[c]; + const description = this.getConstraintDescription(constraint); + constraintDescriptions += c + 1 + ' - ' + description + '\n'; + } + return constraintDescriptions; + } + + /** + * Get the human readable description of the constraint. + * @param constraint The constraint object. + * @returns A human readable text string that describes the constraint. + * example + * 'All steps after this one will not be visitable until the student completes + * "3.7 Revise Your Bowls Explanation"' + */ + private getConstraintDescription(constraint: any): string { + let message = ''; + for (const singleRemovalCriteria of constraint.removalCriteria) { + if (message != '') { + // this constraint has multiple removal criteria + if (constraint.removalConditional === 'any') { + message += ' or '; + } else if (constraint.removalConditional === 'all') { + message += ' and '; + } + } + message += this.getCriteriaMessage(singleRemovalCriteria); + } + return this.getActionMessage(constraint.action) + message; + } + + /** + * Get the message that describes how to satisfy the criteria + * TODO: check if the criteria is satisfied + * @param criteria the criteria object that needs to be satisfied + * @returns the message to display to the student that describes how to + * satisfy the criteria + */ + getCriteriaMessage(criteria: any): string { + let message = ''; + const name = criteria.name; + const params = criteria.params; + + if (name === 'isCompleted') { + const nodeId = params.nodeId; + if (nodeId != null) { + const nodeTitle = this.projectService.getNodePositionAndTitle(nodeId); + message += $localize`Complete ${nodeTitle}`; + } + } else if (name === 'isVisited') { + const nodeId = params.nodeId; + if (nodeId != null) { + const nodeTitle = this.projectService.getNodePositionAndTitle(nodeId); + message += $localize`Visit ${nodeTitle}`; + } + } else if (name === 'isCorrect') { + const nodeId = params.nodeId; + if (nodeId != null) { + const nodeTitle = this.projectService.getNodePositionAndTitle(nodeId); + message += $localize`Correctly answer ${nodeTitle}`; + } + } else if (name === 'score') { + const nodeId = params.nodeId; + let nodeTitle = ''; + let scoresString = ''; + + if (nodeId != null) { + nodeTitle = this.projectService.getNodePositionAndTitle(nodeId); + } + + const scores = params.scores; + if (scores != null) { + scoresString = scores.join(', '); + } + message += $localize`Obtain a score of ${scoresString} on ${nodeTitle}`; + } else if (name === 'choiceChosen') { + const nodeId = params.nodeId; + const componentId = params.componentId; + const choiceIds = params.choiceIds; + let nodeTitle = this.projectService.getNodePositionAndTitle(nodeId); + let choices = this.projectService.getChoiceText(nodeId, componentId, choiceIds); + let choiceText = choices.join(', '); + message += $localize`You must choose "${choiceText}" on "${nodeTitle}"`; + } else if (name === 'usedXSubmits') { + const nodeId = params.nodeId; + let nodeTitle = ''; + + const requiredSubmitCount = params.requiredSubmitCount; + + if (nodeId != null) { + nodeTitle = this.projectService.getNodePositionAndTitle(nodeId); + } + + if (requiredSubmitCount == 1) { + message += $localize`Submit ${requiredSubmitCount} time on ${nodeTitle}`; + } else { + message += $localize`Submit ${requiredSubmitCount} times on ${nodeTitle}`; + } + } else if (name === 'branchPathTaken') { + const fromNodeId = params.fromNodeId; + const fromNodeTitle = this.projectService.getNodePositionAndTitle(fromNodeId); + const toNodeId = params.toNodeId; + const toNodeTitle = this.projectService.getNodePositionAndTitle(toNodeId); + message += $localize`Take the branch path from ${fromNodeTitle} to ${toNodeTitle}`; + } else if (name === 'wroteXNumberOfWords') { + const nodeId = params.nodeId; + if (nodeId != null) { + const requiredNumberOfWords = params.requiredNumberOfWords; + const nodeTitle = this.projectService.getNodePositionAndTitle(nodeId); + message += $localize`Write ${requiredNumberOfWords} words on ${nodeTitle}`; + } + } else if (name === 'isVisible') { + const nodeId = params.nodeId; + if (nodeId != null) { + const nodeTitle = this.projectService.getNodePositionAndTitle(nodeId); + message += $localize`"${nodeTitle}" is visible`; + } + } else if (name === 'isVisitable') { + const nodeId = params.nodeId; + if (nodeId != null) { + const nodeTitle = this.projectService.getNodePositionAndTitle(nodeId); + message += $localize`"${nodeTitle}" is visitable`; + } + } else if (name === 'addXNumberOfNotesOnThisStep') { + const nodeId = params.nodeId; + const requiredNumberOfNotes = params.requiredNumberOfNotes; + const nodeTitle = this.projectService.getNodePositionAndTitle(nodeId); + if (requiredNumberOfNotes == 1) { + message += $localize`Add ${requiredNumberOfNotes} note on ${nodeTitle}`; + } else { + message += $localize`Add ${requiredNumberOfNotes} notes on ${nodeTitle}`; + } + } else if (name === 'fillXNumberOfRows') { + const requiredNumberOfFilledRows = params.requiredNumberOfFilledRows; + const nodeId = params.nodeId; + const nodeTitle = this.projectService.getNodePositionAndTitle(nodeId); + if (requiredNumberOfFilledRows == 1) { + message += $localize`You must fill in ${requiredNumberOfFilledRows} row in the Table on ${nodeTitle}`; + } else { + message += $localize`You must fill in ${requiredNumberOfFilledRows} rows in the Table on ${nodeTitle}`; + } + } else if (name === 'teacherRemoval') { + message += $localize`Wait for your teacher to unlock the item`; + } + return message; + } + + /** + * Get the constraint action as human readable text. + * @param action A constraint action. + * @return A human readable text string that describes the action + * example + * 'All steps after this one will not be visitable until ' + */ + private getActionMessage(action: string): string { + if (action === 'makeAllNodesAfterThisNotVisitable') { + return $localize`All steps after this one will not be visitable until `; + } + if (action === 'makeAllNodesAfterThisNotVisible') { + return $localize`All steps after this one will not be visible until `; + } + if (action === 'makeAllOtherNodesNotVisitable') { + return $localize`All other steps will not be visitable until `; + } + if (action === 'makeAllOtherNodesNotVisible') { + return $localize`All other steps will not be visible until `; + } + if (action === 'makeThisNodeNotVisitable') { + return $localize`This step will not be visitable until `; + } + if (action === 'makeThisNodeNotVisible') { + return $localize`This step will not be visible until `; + } + } } diff --git a/src/assets/wise5/services/projectService.ts b/src/assets/wise5/services/projectService.ts index 47509f82bb0..8b6c0ceba50 100644 --- a/src/assets/wise5/services/projectService.ts +++ b/src/assets/wise5/services/projectService.ts @@ -1191,125 +1191,6 @@ export class ProjectService { return null; } - /** - * Get the message that describes how to satisfy the criteria - * TODO: check if the criteria is satisfied - * @param criteria the criteria object that needs to be satisfied - * @returns the message to display to the student that describes how to - * satisfy the criteria - */ - getCriteriaMessage(criteria: any): string { - let message = ''; - - if (criteria != null) { - const name = criteria.name; - const params = criteria.params; - - if (name === 'isCompleted') { - const nodeId = params.nodeId; - if (nodeId != null) { - const nodeTitle = this.getNodePositionAndTitle(nodeId); - message += $localize`Complete ${nodeTitle}`; - } - } else if (name === 'isVisited') { - const nodeId = params.nodeId; - if (nodeId != null) { - const nodeTitle = this.getNodePositionAndTitle(nodeId); - message += $localize`Visit ${nodeTitle}`; - } - } else if (name === 'isCorrect') { - const nodeId = params.nodeId; - if (nodeId != null) { - const nodeTitle = this.getNodePositionAndTitle(nodeId); - message += $localize`Correctly answer ${nodeTitle}`; - } - } else if (name === 'score') { - const nodeId = params.nodeId; - let nodeTitle = ''; - let scoresString = ''; - - if (nodeId != null) { - nodeTitle = this.getNodePositionAndTitle(nodeId); - } - - const scores = params.scores; - if (scores != null) { - scoresString = scores.join(', '); - } - message += $localize`Obtain a score of ${scoresString} on ${nodeTitle}`; - } else if (name === 'choiceChosen') { - const nodeId = params.nodeId; - const componentId = params.componentId; - const choiceIds = params.choiceIds; - let nodeTitle = this.getNodePositionAndTitle(nodeId); - let choices = this.getChoiceText(nodeId, componentId, choiceIds); - let choiceText = choices.join(', '); - message += $localize`You must choose "${choiceText}" on "${nodeTitle}"`; - } else if (name === 'usedXSubmits') { - const nodeId = params.nodeId; - let nodeTitle = ''; - - const requiredSubmitCount = params.requiredSubmitCount; - - if (nodeId != null) { - nodeTitle = this.getNodePositionAndTitle(nodeId); - } - - if (requiredSubmitCount == 1) { - message += $localize`Submit ${requiredSubmitCount} time on ${nodeTitle}`; - } else { - message += $localize`Submit ${requiredSubmitCount} times on ${nodeTitle}`; - } - } else if (name === 'branchPathTaken') { - const fromNodeId = params.fromNodeId; - const fromNodeTitle = this.getNodePositionAndTitle(fromNodeId); - const toNodeId = params.toNodeId; - const toNodeTitle = this.getNodePositionAndTitle(toNodeId); - message += $localize`Take the branch path from ${fromNodeTitle} to ${toNodeTitle}`; - } else if (name === 'wroteXNumberOfWords') { - const nodeId = params.nodeId; - if (nodeId != null) { - const requiredNumberOfWords = params.requiredNumberOfWords; - const nodeTitle = this.getNodePositionAndTitle(nodeId); - message += $localize`Write ${requiredNumberOfWords} words on ${nodeTitle}`; - } - } else if (name === 'isVisible') { - const nodeId = params.nodeId; - if (nodeId != null) { - const nodeTitle = this.getNodePositionAndTitle(nodeId); - message += $localize`"${nodeTitle}" is visible`; - } - } else if (name === 'isVisitable') { - const nodeId = params.nodeId; - if (nodeId != null) { - const nodeTitle = this.getNodePositionAndTitle(nodeId); - message += $localize`"${nodeTitle}" is visitable`; - } - } else if (name === 'addXNumberOfNotesOnThisStep') { - const nodeId = params.nodeId; - const requiredNumberOfNotes = params.requiredNumberOfNotes; - const nodeTitle = this.getNodePositionAndTitle(nodeId); - if (requiredNumberOfNotes == 1) { - message += $localize`Add ${requiredNumberOfNotes} note on ${nodeTitle}`; - } else { - message += $localize`Add ${requiredNumberOfNotes} notes on ${nodeTitle}`; - } - } else if (name === 'fillXNumberOfRows') { - const requiredNumberOfFilledRows = params.requiredNumberOfFilledRows; - const nodeId = params.nodeId; - const nodeTitle = this.getNodePositionAndTitle(nodeId); - if (requiredNumberOfFilledRows == 1) { - message += $localize`You must fill in ${requiredNumberOfFilledRows} row in the Table on ${nodeTitle}`; - } else { - message += $localize`You must fill in ${requiredNumberOfFilledRows} rows in the Table on ${nodeTitle}`; - } - } else if (name === 'teacherRemoval') { - message += $localize`Wait for your teacher to unlock the item`; - } - } - return message; - } - /** * Get the choices of a Multiple Choice component. * @param nodeId The node id. @@ -1417,9 +1298,7 @@ export class ProjectService { return componentService.componentHasWork(component); } - calculateComponentIdToHasWork( - components: ComponentContent[] - ): { + calculateComponentIdToHasWork(components: ComponentContent[]): { [componentId: string]: boolean; } { const componentIdToHasWork: { [componentId: string]: boolean } = {}; diff --git a/src/assets/wise5/services/studentNodeService.ts b/src/assets/wise5/services/studentNodeService.ts index a7865291041..3c44617235e 100644 --- a/src/assets/wise5/services/studentNodeService.ts +++ b/src/assets/wise5/services/studentNodeService.ts @@ -66,7 +66,7 @@ export class StudentNodeService extends NodeService { */ private getConstraintMessage(constraint: Constraint): string { return constraint.removalCriteria - .map((criterion) => this.projectService.getCriteriaMessage(criterion)) + .map((criterion) => this.constraintService.getCriteriaMessage(criterion)) .filter((message) => message != '') .join('
'); } @@ -82,9 +82,8 @@ export class StudentNodeService extends NodeService { return new Promise((resolve, reject) => { const currentNodeId = currentId ?? this.DataService.getCurrentNodeId(); const transitionLogic = this.ProjectService.getTransitionLogicByFromNodeId(currentNodeId); - const branchPathTakenEvents = this.DataService.getBranchPathTakenEventsByNodeId( - currentNodeId - ); + const branchPathTakenEvents = + this.DataService.getBranchPathTakenEventsByNodeId(currentNodeId); if (this.hasPreviouslyBranchedAndCannotChange(branchPathTakenEvents, transitionLogic)) { resolve(branchPathTakenEvents.at(-1).data.toNodeId); } else { @@ -114,9 +113,8 @@ export class StudentNodeService extends NodeService { private getNextNodeIdFromParent(resolve: any, currentNodeId: string): void { const parentGroupId = this.ProjectService.getParentGroupId(currentNodeId); if (parentGroupId != null) { - const parentTransitionLogic = this.ProjectService.getTransitionLogicByFromNodeId( - parentGroupId - ); + const parentTransitionLogic = + this.ProjectService.getTransitionLogicByFromNodeId(parentGroupId); this.chooseTransition(parentGroupId, parentTransitionLogic).then((transition: any) => { const transitionToNodeId = transition.to; const startId = this.ProjectService.isGroupNode(transitionToNodeId) diff --git a/src/assets/wise5/services/teacherProjectService.ts b/src/assets/wise5/services/teacherProjectService.ts index ce9eb60b0c8..7cd6fe6c573 100644 --- a/src/assets/wise5/services/teacherProjectService.ts +++ b/src/assets/wise5/services/teacherProjectService.ts @@ -741,68 +741,6 @@ export class TeacherProjectService extends ProjectService { this.refreshProjectSource.next(); } - nodeHasConstraint(nodeId: string): boolean { - const constraints = this.getConstraintsOnNode(nodeId); - return constraints.length > 0; - } - - getConstraintsOnNode(nodeId: string): any { - const node = this.getNodeById(nodeId); - return node.constraints ?? []; - } - - /** - * Get the human readable description of the constraint. - * @param constraint The constraint object. - * @returns A human readable text string that describes the constraint. - * example - * 'All steps after this one will not be visitable until the student completes - * "3.7 Revise Your Bowls Explanation"' - */ - getConstraintDescription(constraint: any): string { - let message = ''; - for (const singleRemovalCriteria of constraint.removalCriteria) { - if (message != '') { - // this constraint has multiple removal criteria - if (constraint.removalConditional === 'any') { - message += ' or '; - } else if (constraint.removalConditional === 'all') { - message += ' and '; - } - } - message += this.getCriteriaMessage(singleRemovalCriteria); - } - return this.getActionMessage(constraint.action) + message; - } - - /** - * Get the constraint action as human readable text. - * @param action A constraint action. - * @return A human readable text string that describes the action - * example - * 'All steps after this one will not be visitable until ' - */ - private getActionMessage(action: string): string { - if (action === 'makeAllNodesAfterThisNotVisitable') { - return $localize`All steps after this one will not be visitable until `; - } - if (action === 'makeAllNodesAfterThisNotVisible') { - return $localize`All steps after this one will not be visible until `; - } - if (action === 'makeAllOtherNodesNotVisitable') { - return $localize`All other steps will not be visitable until `; - } - if (action === 'makeAllOtherNodesNotVisible') { - return $localize`All other steps will not be visible until `; - } - if (action === 'makeThisNodeNotVisitable') { - return $localize`This step will not be visitable until `; - } - if (action === 'makeThisNodeNotVisible') { - return $localize`This step will not be visible until `; - } - } - addTeacherRemovalConstraint(node: any, periodId: number) { const lockConstraint = { id: generateRandomKey(), diff --git a/src/messages.xlf b/src/messages.xlf index 66758880d47..880c5422d20 100644 --- a/src/messages.xlf +++ b/src/messages.xlf @@ -12813,7 +12813,7 @@ Click "Cancel" to keep the invalid JSON open so you can fix it.Are you sure you want to delete this step? src/assets/wise5/authoringTool/project-authoring-step/project-authoring-step.component.ts - 117 + 112 @@ -21741,158 +21741,200 @@ If this problem continues, let your teacher know and move on to the next activit 560 - - Manage Notes - - src/assets/wise5/services/notebookService.ts - 33 - - - - You have new replies to your discussion post! - - src/assets/wise5/services/notificationService.ts - 132 - - - - You have new feedback from your teacher! - - src/assets/wise5/services/notificationService.ts - 134 - - - - You have new feedback! - - src/assets/wise5/services/notificationService.ts - 149 - - - - Your teacher has paused all the screens in the class. - - src/assets/wise5/services/pauseScreenService.ts - 39 - - - - Screen Paused - - src/assets/wise5/services/pauseScreenService.ts - 40 - - Complete <b></b> - src/assets/wise5/services/projectService.ts - 1212 + src/assets/wise5/services/constraintService.ts + 325 Visit <b></b> - src/assets/wise5/services/projectService.ts - 1218 + src/assets/wise5/services/constraintService.ts + 331 Correctly answer <b></b> - src/assets/wise5/services/projectService.ts - 1224 + src/assets/wise5/services/constraintService.ts + 337 Obtain a score of <b></b> on <b></b> - src/assets/wise5/services/projectService.ts - 1239 + src/assets/wise5/services/constraintService.ts + 352 You must choose "" on "" - src/assets/wise5/services/projectService.ts - 1247 + src/assets/wise5/services/constraintService.ts + 360 Submit <b></b> time on <b></b> - src/assets/wise5/services/projectService.ts - 1259 + src/assets/wise5/services/constraintService.ts + 372 Submit <b></b> times on <b></b> - src/assets/wise5/services/projectService.ts - 1261 + src/assets/wise5/services/constraintService.ts + 374 Take the branch path from <b></b> to <b></b> - src/assets/wise5/services/projectService.ts - 1268 + src/assets/wise5/services/constraintService.ts + 381 Write <b></b> words on <b></b> - src/assets/wise5/services/projectService.ts - 1274 + src/assets/wise5/services/constraintService.ts + 387 "" is visible - src/assets/wise5/services/projectService.ts - 1280 + src/assets/wise5/services/constraintService.ts + 393 "" is visitable - src/assets/wise5/services/projectService.ts - 1286 + src/assets/wise5/services/constraintService.ts + 399 Add <b></b> note on <b></b> - src/assets/wise5/services/projectService.ts - 1293 + src/assets/wise5/services/constraintService.ts + 406 Add <b></b> notes on <b></b> - src/assets/wise5/services/projectService.ts - 1295 + src/assets/wise5/services/constraintService.ts + 408 You must fill in <b></b> row in the <b>Table</b> on <b></b> - src/assets/wise5/services/projectService.ts - 1302 + src/assets/wise5/services/constraintService.ts + 415 You must fill in <b></b> rows in the <b>Table</b> on <b></b> - src/assets/wise5/services/projectService.ts - 1304 + src/assets/wise5/services/constraintService.ts + 417 Wait for your teacher to unlock the item - src/assets/wise5/services/projectService.ts - 1307 + src/assets/wise5/services/constraintService.ts + 420 + + + + All steps after this one will not be visitable until + + src/assets/wise5/services/constraintService.ts + 434 + + + + All steps after this one will not be visible until + + src/assets/wise5/services/constraintService.ts + 437 + + + + All other steps will not be visitable until + + src/assets/wise5/services/constraintService.ts + 440 + + + + All other steps will not be visible until + + src/assets/wise5/services/constraintService.ts + 443 + + + + This step will not be visitable until + + src/assets/wise5/services/constraintService.ts + 446 + + + + This step will not be visible until + + src/assets/wise5/services/constraintService.ts + 449 + + + + Manage Notes + + src/assets/wise5/services/notebookService.ts + 33 + + + + You have new replies to your discussion post! + + src/assets/wise5/services/notificationService.ts + 132 + + + + You have new feedback from your teacher! + + src/assets/wise5/services/notificationService.ts + 134 + + + + You have new feedback! + + src/assets/wise5/services/notificationService.ts + 149 + + + + Your teacher has paused all the screens in the class. + + src/assets/wise5/services/pauseScreenService.ts + 39 + + + + Screen Paused + + src/assets/wise5/services/pauseScreenService.ts + 40 @@ -21958,48 +22000,6 @@ If this problem continues, let your teacher know and move on to the next activit 51 - - All steps after this one will not be visitable until - - src/assets/wise5/services/teacherProjectService.ts - 787 - - - - All steps after this one will not be visible until - - src/assets/wise5/services/teacherProjectService.ts - 790 - - - - All other steps will not be visitable until - - src/assets/wise5/services/teacherProjectService.ts - 793 - - - - All other steps will not be visible until - - src/assets/wise5/services/teacherProjectService.ts - 796 - - - - This step will not be visitable until - - src/assets/wise5/services/teacherProjectService.ts - 799 - - - - This step will not be visible until - - src/assets/wise5/services/teacherProjectService.ts - 802 - - Error saving translation. Please try again later.