From 46d82e87a5fd7e5f37c61cbd7f6bb2798d9b10eb Mon Sep 17 00:00:00 2001 From: Jonathan Lim-Breitbart Date: Mon, 5 Oct 2026 15:04:24 -0700 Subject: [PATCH 1/5] feat(VLE): Remove unit plan --- .../navigation/navigation.component.html | 14 -- .../navigation/navigation.component.scss | 19 --- .../navigation/navigation.component.spec.ts | 29 ---- .../navigation/navigation.component.ts | 36 ---- .../stepTools/step-tools.component.html | 58 +++---- .../stepTools/step-tools.component.ts | 1 - .../vle/nav-item/nav-item.component.html | 110 ------------- .../vle/nav-item/nav-item.component.scss | 74 --------- .../wise5/vle/nav-item/nav-item.component.ts | 154 ------------------ src/assets/wise5/vle/vle.component.html | 24 +-- src/assets/wise5/vle/vle.component.scss | 2 +- src/assets/wise5/vle/vle.component.ts | 28 ---- 12 files changed, 27 insertions(+), 522 deletions(-) delete mode 100644 src/assets/wise5/themes/default/navigation/navigation.component.html delete mode 100644 src/assets/wise5/themes/default/navigation/navigation.component.scss delete mode 100644 src/assets/wise5/themes/default/navigation/navigation.component.spec.ts delete mode 100644 src/assets/wise5/themes/default/navigation/navigation.component.ts delete mode 100644 src/assets/wise5/vle/nav-item/nav-item.component.html delete mode 100644 src/assets/wise5/vle/nav-item/nav-item.component.scss delete mode 100644 src/assets/wise5/vle/nav-item/nav-item.component.ts diff --git a/src/assets/wise5/themes/default/navigation/navigation.component.html b/src/assets/wise5/themes/default/navigation/navigation.component.html deleted file mode 100644 index 5fa6ec40d6e..00000000000 --- a/src/assets/wise5/themes/default/navigation/navigation.component.html +++ /dev/null @@ -1,14 +0,0 @@ - diff --git a/src/assets/wise5/themes/default/navigation/navigation.component.scss b/src/assets/wise5/themes/default/navigation/navigation.component.scss deleted file mode 100644 index b3cda6a6c3c..00000000000 --- a/src/assets/wise5/themes/default/navigation/navigation.component.scss +++ /dev/null @@ -1,19 +0,0 @@ -@use 'style/abstracts/functions'; - -.nav { - margin: 0 auto 16px; - width: functions.breakpoint('md.min'); - max-width: 100%; -} - -.nav-header { - margin: 0 16px 16px 16px; -} - -.lesson { - transition: box-shadow .25s; -} - -.expanded { - margin: 4px -8px 4px 0; -} diff --git a/src/assets/wise5/themes/default/navigation/navigation.component.spec.ts b/src/assets/wise5/themes/default/navigation/navigation.component.spec.ts deleted file mode 100644 index d25ec4e9b12..00000000000 --- a/src/assets/wise5/themes/default/navigation/navigation.component.spec.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { StudentTeacherCommonServicesModule } from '../../../../../app/student-teacher-common-services.module'; -import { VLEProjectService } from '../../../vle/vleProjectService'; -import { NavigationComponent } from './navigation.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; - -describe('NavigationComponent', () => { - let component: NavigationComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [NavigationComponent, StudentTeacherCommonServicesModule], - providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] - }); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(NavigationComponent); - component = fixture.componentInstance; - spyOn(TestBed.inject(VLEProjectService), 'getProjectRootNode').and.returnValue({ ids: [] }); - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/assets/wise5/themes/default/navigation/navigation.component.ts b/src/assets/wise5/themes/default/navigation/navigation.component.ts deleted file mode 100644 index bc48f144f25..00000000000 --- a/src/assets/wise5/themes/default/navigation/navigation.component.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { Subscription } from 'rxjs'; -import { StudentDataService } from '../../../services/studentDataService'; -import { VLEProjectService } from '../../../vle/vleProjectService'; -import { CommonModule } from '@angular/common'; -import { NavItemComponent } from '../../../vle/nav-item/nav-item.component'; - -@Component({ - imports: [CommonModule, NavItemComponent], - selector: 'navigation', - styleUrl: './navigation.component.scss', - templateUrl: './navigation.component.html' -}) -export class NavigationComponent implements OnInit { - protected navItemIsExpanded: { [nodeId: string]: boolean } = {}; - private navItemIsExpandedSubscription: Subscription; - protected rootNode: any; - - constructor( - private dataService: StudentDataService, - private projectService: VLEProjectService - ) {} - - ngOnInit(): void { - this.rootNode = this.projectService.getProjectRootNode(); - this.navItemIsExpandedSubscription = this.dataService.navItemIsExpanded$.subscribe( - ({ nodeId, isExpanded }) => { - this.navItemIsExpanded[nodeId] = isExpanded; - } - ); - } - - ngOnDestroy(): void { - this.navItemIsExpandedSubscription.unsubscribe(); - } -} diff --git a/src/assets/wise5/themes/default/themeComponents/stepTools/step-tools.component.html b/src/assets/wise5/themes/default/themeComponents/stepTools/step-tools.component.html index fbd1f66ac89..79c2a8308fb 100644 --- a/src/assets/wise5/themes/default/themeComponents/stepTools/step-tools.component.html +++ b/src/assets/wise5/themes/default/themeComponents/stepTools/step-tools.component.html @@ -1,44 +1,28 @@
- @if (stepView) { - - - - } @else { - Unit Plan - } + + +
- @if (stepView) { - - } @if (notebookConfig.itemTypes.note.enabled) { } diff --git a/src/assets/wise5/themes/default/themeComponents/stepTools/step-tools.component.ts b/src/assets/wise5/themes/default/themeComponents/stepTools/step-tools.component.ts index 30f90b1bf14..f1ecff13085 100644 --- a/src/assets/wise5/themes/default/themeComponents/stepTools/step-tools.component.ts +++ b/src/assets/wise5/themes/default/themeComponents/stepTools/step-tools.component.ts @@ -31,7 +31,6 @@ export class StepToolsComponent implements OnInit, OnDestroy { protected nextId: string; @Input() notebookConfig: any; protected prevId: string; - @Input() stepView: boolean; private subscriptions: Subscription = new Subscription(); @Output() toggleChatbot = new EventEmitter(); diff --git a/src/assets/wise5/vle/nav-item/nav-item.component.html b/src/assets/wise5/vle/nav-item/nav-item.component.html deleted file mode 100644 index cc1a1cc7b47..00000000000 --- a/src/assets/wise5/vle/nav-item/nav-item.component.html +++ /dev/null @@ -1,110 +0,0 @@ -@if (nodeStatus.isVisible) { - - @switch (type) { - @case ('card') { - - - - - {{ nodeTitle }} - - - @if (isGroup && expanded) { - remove - } - - @if (isGroup && expanded) { - - - @for (childId of item.ids; track childId) { - - - } - - - } - - @if (isGroup) { - - - {{ nodeStatus.progress.completedItems }}/{{ nodeStatus.progress.totalItems }} items - - } - -
- - - @if (!nodeStatus.isVisitable) { - - lock - - } -
-
-
- } - @case ('list') { - - } - } -} diff --git a/src/assets/wise5/vle/nav-item/nav-item.component.scss b/src/assets/wise5/vle/nav-item/nav-item.component.scss deleted file mode 100644 index 8de218be9bf..00000000000 --- a/src/assets/wise5/vle/nav-item/nav-item.component.scss +++ /dev/null @@ -1,74 +0,0 @@ -@use '@angular/material' as mat; - -.nav-item { - &.mat-mdc-card { - margin: 8px; - padding-top: 0; - } - - .mat-mdc-card-content { - padding: 16px; - } - - .mat-mdc-card-header { - cursor: pointer; - - &:focus, &:hover { - outline: none; - - .title { - text-decoration-line: underline; - text-decoration-style: dashed; - text-decoration-color: inherit; - text-decoration-thickness: from-font; - } - } - } - - .mat-mdc-card-actions { - border-top: 1px solid #dddddd; - padding-top: 8px; - padding-bottom: 8px; - min-height: 0; - } - - .mat-mdc-list-base { - padding-top: 0; - padding-bottom: 0; - } - - .mat-mdc-list-item { - padding-top: 8px; - padding-bottom: 8px; - min-height: 56px; - } - - .mat-caption { - font-weight: 500; - } - - .group-icon { - height: auto; - width: auto; - } - - .title { - font-weight: normal; - } - - .collapse-icon { - margin: 0; - } - - .progress { - width: 48px; - } - - .mat-mdc-card .mat-divider-horizontal { - position: relative; - } - - &.expanded, .expanded { - @include mat.elevation(3); - } -} diff --git a/src/assets/wise5/vle/nav-item/nav-item.component.ts b/src/assets/wise5/vle/nav-item/nav-item.component.ts deleted file mode 100644 index 4164e8a45d7..00000000000 --- a/src/assets/wise5/vle/nav-item/nav-item.component.ts +++ /dev/null @@ -1,154 +0,0 @@ -import { Component, Input, ViewEncapsulation } from '@angular/core'; -import { Subscription } from 'rxjs'; -import { ProjectService } from '../../services/projectService'; -import { StudentDataService } from '../../services/studentDataService'; -import { NodeService } from '../../services/nodeService'; -import { CommonModule } from '@angular/common'; -import { MatCardModule } from '@angular/material/card'; -import { NodeIconComponent } from '../node-icon/node-icon.component'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { NodeStatusIconComponent } from '../../themes/default/themeComponents/nodeStatusIcon/node-status-icon.component'; -import { MatIconModule } from '@angular/material/icon'; -import { MatTooltipModule } from '@angular/material/tooltip'; -import { MatListModule } from '@angular/material/list'; - -@Component({ - encapsulation: ViewEncapsulation.None, - imports: [ - CommonModule, - MatCardModule, - MatIconModule, - MatListModule, - MatProgressBarModule, - MatTooltipModule, - NodeIconComponent, - NodeStatusIconComponent - ], - selector: 'nav-item', - styleUrl: 'nav-item.component.scss', - templateUrl: 'nav-item.component.html' -}) -export class NavItemComponent { - private currentNode: any; - protected expanded: boolean; - private isCurrentNode: boolean; - protected isGroup: boolean; - protected isPrevStep: boolean; - protected item: any; - @Input() nodeId: string; - protected nodeStatus: any; - protected nodeTitle: string; - @Input() showPosition: any; - private subscriptions: Subscription = new Subscription(); - @Input() type: string; - - constructor( - private dataService: StudentDataService, - private nodeService: NodeService, - private projectService: ProjectService - ) {} - - ngOnInit(): void { - this.item = this.projectService.idToNode[this.nodeId]; - this.isGroup = this.projectService.isGroupNode(this.nodeId); - this.nodeStatus = this.dataService.nodeStatuses[this.nodeId]; - this.setNodeTitle(); - this.currentNode = this.dataService.currentNode; - this.isCurrentNode = this.currentNode.id === this.nodeId; - if (this.isGroup && this.isCurrentNode) { - this.setExpanded(); - this.zoomToElement(); - } - if (this.dataService.previousStep) { - this.isPrevStep = this.nodeId === this.dataService.previousStep.id; - } - this.subscriptions.add(this.projectService.projectParsed$.subscribe(() => this.setNodeTitle())); - this.subscriptions.add( - this.dataService.navItemIsExpanded$.subscribe(({ nodeId, isExpanded }) => { - if (nodeId === this.nodeId) { - this.expanded = isExpanded; - } - }) - ); - this.subscriptions.add( - this.dataService.currentNodeChanged$.subscribe( - ({ previousNode: oldNode, currentNode: newNode }) => { - this.currentNode = newNode; - this.isCurrentNode = this.nodeId === newNode.id; - let isPrev = false; - if (this.projectService.isApplicationNode(newNode.id)) { - return; - } - if (oldNode) { - isPrev = this.nodeId === oldNode.id; - if (this.dataService.previousStep) { - this.isPrevStep = this.nodeId === this.dataService.previousStep.id; - } - } - if (this.isGroup) { - let prevNodeisGroup = !oldNode || this.projectService.isGroupNode(oldNode.id); - let prevNodeIsDescendant = this.projectService.isNodeDescendentOfGroup( - oldNode, - this.item - ); - if (this.isCurrentNode) { - this.setExpanded(); - if (prevNodeisGroup || !prevNodeIsDescendant) { - this.zoomToElement(); - } - } else { - if (!prevNodeisGroup) { - if (prevNodeIsDescendant) { - this.expanded = true; - } else { - this.expanded = false; - } - } - } - } else { - if (isPrev && this.projectService.isNodeDescendentOfGroup(this.item, newNode)) { - this.zoomToElement(); - } - } - } - ) - ); - } - - private setNodeTitle(): void { - this.nodeTitle = this.showPosition - ? this.projectService.getNodePositionAndTitle(this.nodeId) - : this.projectService.getNodeTitle(this.nodeId); - } - - ngOnDestroy(): void { - this.subscriptions.unsubscribe(); - } - - private setExpanded(): void { - this.expanded = true; - this.dataService.setNavItemExpanded(this.nodeId, this.expanded); - } - - private zoomToElement(): void { - setTimeout(() => { - document.getElementById(`nav-item-${this.nodeId}`).scrollIntoView({ behavior: 'smooth' }); - }, 500); - } - - protected itemClicked(): void { - if (this.isGroup) { - this.expanded = !this.expanded; - if (this.expanded) { - if (this.isCurrentNode) { - this.zoomToElement(); - } else { - this.nodeService.setCurrentNode(this.nodeId); - } - } - this.dataService.setNavItemExpanded(this.nodeId, this.expanded); - } else { - this.nodeService.setCurrentNode(this.nodeId); - } - } -} diff --git a/src/assets/wise5/vle/vle.component.html b/src/assets/wise5/vle/vle.component.html index b947059e891..df6b5397d99 100644 --- a/src/assets/wise5/vle/vle.component.html +++ b/src/assets/wise5/vle/vle.component.html @@ -36,30 +36,22 @@
@if (runEndedAndLocked) { } - @if (layoutState === 'node') { - - - } - @if (layoutState === 'nav') { - - } + +
@@ -70,18 +62,12 @@ (toggleChatbot)="chatbotVisible = !chatbotVisible" class="app-bg-bg mat-elevation-z1" /> -
+
@if (runEndedAndLocked) { } - @if (layoutState === 'node') { - - } +
diff --git a/src/assets/wise5/vle/vle.component.scss b/src/assets/wise5/vle/vle.component.scss index 005fc67db78..d82bdef8135 100644 --- a/src/assets/wise5/vle/vle.component.scss +++ b/src/assets/wise5/vle/vle.component.scss @@ -30,7 +30,7 @@ step-tools, group-tabs { overflow: auto; } -.node-view, .nav-view { +.node-view { top: variables.$toolbar-height + variables.$secondary-toolbar-height; } diff --git a/src/assets/wise5/vle/vle.component.ts b/src/assets/wise5/vle/vle.component.ts index 3aa8c874133..7494a5b9e16 100644 --- a/src/assets/wise5/vle/vle.component.ts +++ b/src/assets/wise5/vle/vle.component.ts @@ -16,7 +16,6 @@ import { GroupTabsComponent } from '../directives/group-tabs/group-tabs.componen import { InitializeVLEService } from '../services/initializeVLEService'; import { MatDialog } from '@angular/material/dialog'; import { MatSidenavModule } from '@angular/material/sidenav'; -import { NavigationComponent } from '../themes/default/navigation/navigation.component'; import { Node } from '../common/Node'; import { NodeComponent } from './node/node.component'; import { NodeNavigationComponent } from '../directives/node-navigation/node-navigation.component'; @@ -45,7 +44,6 @@ import { BreakpointObserver } from '@angular/cdk/layout'; CommonModule, GroupTabsComponent, MatSidenavModule, - NavigationComponent, NodeComponent, NodeNavigationComponent, NotebookReportComponent, @@ -156,7 +154,6 @@ export class VLEComponent implements AfterViewInit { // TODO: set these variables dynamically from theme settings this.notebookConfig = this.notebookService.getNotebookConfig(); - this.setLayoutState(); this.initializeSubscriptions(); this.saveNodeEnteredEvent(); this.initializeChatbot(); @@ -256,7 +253,6 @@ export class VLEComponent implements AfterViewInit { this.scrollToTop(); } this.router.navigate([currentNodeId], { relativeTo: this.route.parent }); - this.setLayoutState(); }) ); } @@ -291,30 +287,6 @@ export class VLEComponent implements AfterViewInit { }); } - /** - * Set the layout state of the vle - * @param state string specifying state (e.g. 'notebook'; optional) - */ - private setLayoutState(state: string = null) { - let layoutState = 'nav'; // default layout state - if (state) { - layoutState = state; - } else { - // no state was sent, so set based on current node - if (this.currentNode) { - var id = this.currentNode.id; - if (this.projectService.isApplicationNode(id)) { - // currently viewing step, so show step view - layoutState = 'node'; - } else if (this.projectService.isGroupNode(id)) { - // currently viewing group node, so show navigation view - layoutState = 'nav'; - } - } - } - this.layoutState = layoutState; - } - private scrollToTop() { document.querySelector('.top').scrollIntoView(); } From 5b0213562083852a3728a1f6fceae8f777ffee5c Mon Sep 17 00:00:00 2001 From: Jonathan Lim-Breitbart Date: Mon, 5 Oct 2026 15:15:49 -0700 Subject: [PATCH 2/5] Clean up starting node logic in VLE - If requested starting node id isn't in unit, load unit start node - If requested starting node id is a group, load group start node - If group doesn't have a start node, load unit start node --- .../wise5/vle/vle-parent/vle-parent.component.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/assets/wise5/vle/vle-parent/vle-parent.component.ts b/src/assets/wise5/vle/vle-parent/vle-parent.component.ts index b9f7d0de91f..20a039f9805 100644 --- a/src/assets/wise5/vle/vle-parent/vle-parent.component.ts +++ b/src/assets/wise5/vle/vle-parent/vle-parent.component.ts @@ -34,10 +34,13 @@ export class VLEParentComponent implements OnInit { } private getStartingNodeId(): string { - const urlMatch = this.router.url.match(/unit\/[0-9]*\/([^?]*)/); - return urlMatch != null - ? urlMatch[1] - : (this.getLastNodeEnteredEvent()?.nodeId ?? this.projectService.getStartNodeId()); + const nodeId = this.router.url.match(/unit\/[0-9]*\/([^?]+)/)?.[1]; + if (nodeId && this.projectService.isNodeActive(nodeId)) { + return this.projectService.isGroupNode(nodeId) + ? (this.projectService.getGroupStartId(nodeId) ?? this.projectService.getStartNodeId()) + : nodeId; + } + return this.getLastNodeEnteredEvent()?.nodeId ?? this.projectService.getStartNodeId(); } /** From 446b5c81008bdfb5a1ca5d9cc27f9c99d11800f9 Mon Sep 17 00:00:00 2001 From: Jonathan Lim-Breitbart Date: Mon, 5 Oct 2026 16:55:30 -0700 Subject: [PATCH 3/5] Fix and add tests --- .../vle-parent/vle-parent.component.spec.ts | 62 +++++++++++++++++-- 1 file changed, 56 insertions(+), 6 deletions(-) diff --git a/src/assets/wise5/vle/vle-parent/vle-parent.component.spec.ts b/src/assets/wise5/vle/vle-parent/vle-parent.component.spec.ts index 8e292ea3f28..7d21c9a4f54 100644 --- a/src/assets/wise5/vle/vle-parent/vle-parent.component.spec.ts +++ b/src/assets/wise5/vle/vle-parent/vle-parent.component.spec.ts @@ -13,6 +13,7 @@ let fixture: ComponentFixture; let initializeVLEService: InitializeVLEService; let dataService: StudentDataService; let projectService: VLEProjectService; +const groupId1: string = 'group1'; const nodeId1: string = 'node1'; let router: Router; const runId1: string = '1'; @@ -45,6 +46,8 @@ function ngOnInit() { describe('ngOnInit()', () => { initialize(); previewConstraints(); + groupNode(); + inactiveNode(); initializeStudent(); }); } @@ -67,13 +70,60 @@ function expectInitialize(functionName: any, runId: string): void { } function previewConstraints() { - it('should set the starting node id when constraints are enabled', () => { - setRouterUrl(`/preview/unit/${runId1}/${nodeId1}`); - expectSetCurrentNode(nodeId1, true); + describe('previewConstraints', () => { + beforeEach(() => { + spyOn(projectService, 'isNodeActive').and.returnValue(true); + spyOn(projectService, 'isGroupNode').and.returnValue(false); + }); + it('should set the starting node id when constraints are enabled', () => { + setRouterUrl(`/preview/unit/${runId1}/${nodeId1}`); + expectSetCurrentNode(nodeId1, true); + }); + it('should set the starting node id when constraints are disabled', () => { + setRouterUrl(`/preview/unit/${runId1}/${nodeId1}?constraints=false`); + expectSetCurrentNode(nodeId1, true); + }); }); - it('should set the starting node id when constraints are disabled', () => { - setRouterUrl(`/preview/unit/${runId1}/${nodeId1}?constraints=false`); - expectSetCurrentNode(nodeId1, true); +} + +function groupNode() { + describe('when requested url is a group node', () => { + beforeEach(() => { + spyOn(projectService, 'isNodeActive').and.returnValue(true); + spyOn(projectService, 'isGroupNode').and.returnValue(true); + }); + it('should set the starting node id to group start id', () => { + setRouterUrl(`/preview/unit/${runId1}/${groupId1}`); + spyOn(projectService, 'getGroupStartId').and.returnValue(nodeId1); + expectSetCurrentNode(nodeId1, true); + }); + it('should set the starting node id to project start node id when group has no start id', () => { + setRouterUrl(`/preview/unit/${runId1}/${groupId1}`); + spyOn(projectService, 'getGroupStartId').and.returnValue(null); + spyOn(projectService, 'getStartNodeId').and.returnValue('node2'); + expectSetCurrentNode('node2', true); + }); + }); +} + +function inactiveNode() { + describe('when requested url is not an active node', () => { + beforeEach(() => { + spyOn(projectService, 'isNodeActive').and.returnValue(false); + }); + it('should set the starting node id when there is no last NodeEntered event', () => { + setRouterUrl(`/preview/unit/${runId1}/${nodeId1}`); + spyOn(dataService, 'getEvents').and.returnValue([]); + spyOn(projectService, 'getStartNodeId').and.returnValue('node2'); + expectSetCurrentNode('node2', true); + }); + it('should set the starting node id when there is last NodeEntered event', () => { + setRouterUrl(`/preview/unit/${runId1}/${nodeId1}`); + spyOn(dataService, 'getEvents').and.returnValue([{ event: 'nodeEntered', nodeId: 'node32' }]); + spyOn(projectService, 'getNodeById').and.returnValue({}); + spyOn(projectService, 'isActive').and.returnValue(true); + expectSetCurrentNode('node32', true); + }); }); } From 7857c8c519beec417c845cec1541a1ffa1568c20 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 6 Oct 2026 00:00:11 +0000 Subject: [PATCH 4/5] Updated messages --- src/messages.xlf | 67 ++++++++---------------------------------------- 1 file changed, 11 insertions(+), 56 deletions(-) diff --git a/src/messages.xlf b/src/messages.xlf index 368fb66b8f6..2b905f5ffeb 100644 --- a/src/messages.xlf +++ b/src/messages.xlf @@ -2069,10 +2069,6 @@ src/assets/wise5/classroomMonitor/classroomMonitorComponents/component-completion/component-completion.component.html 4,5 - - src/assets/wise5/vle/nav-item/nav-item.component.html - 54,55 - Detectable ideas @@ -10993,7 +10989,7 @@ Click "Cancel" to keep the invalid JSON open so you can fix it. src/assets/wise5/vle/vle.component.ts - 224 + 221 @@ -11008,7 +11004,7 @@ Click "Cancel" to keep the invalid JSON open so you can fix it. src/assets/wise5/vle/vle.component.ts - 225 + 222 @@ -15610,10 +15606,6 @@ The branches will be removed but the steps will remain in the unit. src/assets/wise5/classroomMonitor/classroomMonitorComponents/shared/notifications-menu/notifications-menu.component.html 36,37 - - src/assets/wise5/vle/nav-item/nav-item.component.html - 86,87 - Are you sure you want to clear all your alerts? @@ -16651,7 +16643,7 @@ Are you sure you want to proceed? src/assets/wise5/themes/default/themeComponents/stepTools/step-tools.component.html - 9,13 + 8,12 @@ -16692,7 +16684,7 @@ Are you sure you want to proceed? src/assets/wise5/themes/default/themeComponents/stepTools/step-tools.component.html - 19,23 + 18,22 @@ -23941,10 +23933,6 @@ If this problem continues, let your teacher know and move on to the next activit src/assets/wise5/themes/default/themeComponents/stepSelect/step-select.component.html 131,134 - - src/assets/wise5/vle/nav-item/nav-item.component.html - 99,102 - % completed (/ steps) @@ -23953,21 +23941,6 @@ If this problem continues, let your teacher know and move on to the next activit 143 - - Unit Plan - - src/assets/wise5/themes/default/themeComponents/stepTools/step-tools.component.html - 26,31 - - - src/assets/wise5/themes/default/themeComponents/stepTools/step-tools.component.html - 34,37 - - - src/assets/wise5/themes/default/themeComponents/stepTools/step-tools.component.html - 36,39 - - Choose Your : @@ -24024,31 +23997,6 @@ If this problem continues, let your teacher know and move on to the next activit 49 - - Expand or collapse lesson content - - src/assets/wise5/vle/nav-item/nav-item.component.html - 14,18 - - - - / items - - src/assets/wise5/vle/nav-item/nav-item.component.html - 58,59 - - - src/assets/wise5/vle/student-account-menu/student-account-menu.component.html - 18,20 - - - - Lesson is locked - - src/assets/wise5/vle/nav-item/nav-item.component.html - 69,72 - - Choose an icon @@ -24102,6 +24050,13 @@ If this problem continues, let your teacher know and move on to the next activit 16,18 + + / items + + src/assets/wise5/vle/student-account-menu/student-account-menu.component.html + 18,20 + + / points From 3041c2ea8ea73619098f7f0d1d4d070e8861689a Mon Sep 17 00:00:00 2001 From: Jonathan Lim-Breitbart Date: Wed, 7 Oct 2026 12:13:50 -0700 Subject: [PATCH 5/5] Fix logic for group node with empty string for start node id --- .../wise5/vle/vle-parent/vle-parent.component.spec.ts | 2 +- src/assets/wise5/vle/vle-parent/vle-parent.component.ts | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/assets/wise5/vle/vle-parent/vle-parent.component.spec.ts b/src/assets/wise5/vle/vle-parent/vle-parent.component.spec.ts index 7d21c9a4f54..e0c6ec2c2e6 100644 --- a/src/assets/wise5/vle/vle-parent/vle-parent.component.spec.ts +++ b/src/assets/wise5/vle/vle-parent/vle-parent.component.spec.ts @@ -99,7 +99,7 @@ function groupNode() { }); it('should set the starting node id to project start node id when group has no start id', () => { setRouterUrl(`/preview/unit/${runId1}/${groupId1}`); - spyOn(projectService, 'getGroupStartId').and.returnValue(null); + spyOn(projectService, 'getGroupStartId').and.returnValue(''); spyOn(projectService, 'getStartNodeId').and.returnValue('node2'); expectSetCurrentNode('node2', true); }); diff --git a/src/assets/wise5/vle/vle-parent/vle-parent.component.ts b/src/assets/wise5/vle/vle-parent/vle-parent.component.ts index 20a039f9805..8e09ae0e3f6 100644 --- a/src/assets/wise5/vle/vle-parent/vle-parent.component.ts +++ b/src/assets/wise5/vle/vle-parent/vle-parent.component.ts @@ -37,12 +37,17 @@ export class VLEParentComponent implements OnInit { const nodeId = this.router.url.match(/unit\/[0-9]*\/([^?]+)/)?.[1]; if (nodeId && this.projectService.isNodeActive(nodeId)) { return this.projectService.isGroupNode(nodeId) - ? (this.projectService.getGroupStartId(nodeId) ?? this.projectService.getStartNodeId()) + ? (this.getGroupStartNodeId(nodeId) ?? this.projectService.getStartNodeId()) : nodeId; } return this.getLastNodeEnteredEvent()?.nodeId ?? this.projectService.getStartNodeId(); } + private getGroupStartNodeId(nodeId: string): string { + const startNodeId = this.projectService.getGroupStartId(nodeId); + return startNodeId ? startNodeId : null; + } + /** * Get the last node entered event for an active node that exists in the project. * We need to check if the node exists in the project in case the node has been deleted