From 4f607eaececa9a4e80dac57c64d0826c845a2cac Mon Sep 17 00:00:00 2001 From: Hiroki Terashima <honchikun@gmail.com> Date: Thu, 21 Sep 2023 09:54:52 -0700 Subject: [PATCH] refactor(ProjectAuthoringCompoonent): Extract ProjectAuthoringParentComponent (#1427) --- src/app/teacher/authoring-routing.module.ts | 4 +- src/app/teacher/authoring-tool.module.ts | 2 + .../project-authoring-parent.component.html | 13 + .../project-authoring-parent.component.scss | 17 + .../project-authoring-parent.component.ts | 25 + .../project-authoring.component.html | 601 +++++++++--------- .../project-authoring.component.scss | 18 - .../project-authoring.component.spec.ts | 14 +- .../project-authoring.component.ts | 48 +- src/messages.xlf | 56 +- 10 files changed, 392 insertions(+), 406 deletions(-) create mode 100644 src/assets/wise5/authoringTool/project-authoring-parent/project-authoring-parent.component.html create mode 100644 src/assets/wise5/authoringTool/project-authoring-parent/project-authoring-parent.component.scss create mode 100644 src/assets/wise5/authoringTool/project-authoring-parent/project-authoring-parent.component.ts diff --git a/src/app/teacher/authoring-routing.module.ts b/src/app/teacher/authoring-routing.module.ts index 74663110805..636da4da99a 100644 --- a/src/app/teacher/authoring-routing.module.ts +++ b/src/app/teacher/authoring-routing.module.ts @@ -34,6 +34,7 @@ import { RecoveryAuthoringComponent } from '../../assets/wise5/authoringTool/rec import { ChooseImportComponentComponent } from '../../assets/wise5/authoringTool/importComponent/choose-import-component/choose-import-component.component'; import { ChooseMoveNodeLocationComponent } from '../../assets/wise5/authoringTool/choose-node-location/choose-move-node-location/choose-move-node-location.component'; import { ChooseCopyNodeLocationComponent } from '../../assets/wise5/authoringTool/choose-node-location/choose-copy-node-location/choose-copy-node-location.component'; +import { ProjectAuthoringParentComponent } from '../../assets/wise5/authoringTool/project-authoring-parent/project-authoring-parent.component'; const routes: Routes = [ { @@ -46,9 +47,10 @@ const routes: Routes = [ { path: 'new-unit', component: AddProjectComponent }, { path: 'unit/:unitId', - component: ProjectAuthoringComponent, + component: ProjectAuthoringParentComponent, resolve: { project: AuthoringProjectResolver }, children: [ + { path: '', component: ProjectAuthoringComponent }, { path: 'add-lesson', children: [ diff --git a/src/app/teacher/authoring-tool.module.ts b/src/app/teacher/authoring-tool.module.ts index cc7f3d66ea0..ead2aea6ae9 100644 --- a/src/app/teacher/authoring-tool.module.ts +++ b/src/app/teacher/authoring-tool.module.ts @@ -48,6 +48,7 @@ import { InsertNodeAfterButtonComponent } from '../../assets/wise5/authoringTool import { InsertNodeInsideButtonComponent } from '../../assets/wise5/authoringTool/choose-node-location/insert-node-inside-button/insert-node-inside-button.component'; import { NodeIconAndTitleComponent } from '../../assets/wise5/authoringTool/choose-node-location/node-icon-and-title/node-icon-and-title.component'; import { NodeWithMoveAfterButtonComponent } from '../../assets/wise5/authoringTool/choose-node-location/node-with-move-after-button/node-with-move-after-button.component'; +import { ProjectAuthoringParentComponent } from '../../assets/wise5/authoringTool/project-authoring-parent/project-authoring-parent.component'; @NgModule({ declarations: [ @@ -81,6 +82,7 @@ import { NodeWithMoveAfterButtonComponent } from '../../assets/wise5/authoringTo NotebookAuthoringComponent, ProjectInfoAuthoringComponent, ProjectAuthoringComponent, + ProjectAuthoringParentComponent, RecoveryAuthoringComponent, RequiredErrorLabelComponent, RubricAuthoringComponent, diff --git a/src/assets/wise5/authoringTool/project-authoring-parent/project-authoring-parent.component.html b/src/assets/wise5/authoringTool/project-authoring-parent/project-authoring-parent.component.html new file mode 100644 index 00000000000..68e7f7f4451 --- /dev/null +++ b/src/assets/wise5/authoringTool/project-authoring-parent/project-authoring-parent.component.html @@ -0,0 +1,13 @@ +<div id="top" class="view-content view-content--with-sidemenu"> + <div class="l-constrained" fxLayout="column"> + <div class="node-content md-whiteframe-1dp" fxLayout="row wrap"> + <div class="main-content"> + <concurrent-authors-message + [projectId]="projectId" + class="concurrent-authors-message center app-background" + ></concurrent-authors-message> + <router-outlet></router-outlet> + </div> + </div> + </div> +</div> diff --git a/src/assets/wise5/authoringTool/project-authoring-parent/project-authoring-parent.component.scss b/src/assets/wise5/authoringTool/project-authoring-parent/project-authoring-parent.component.scss new file mode 100644 index 00000000000..7155e961a66 --- /dev/null +++ b/src/assets/wise5/authoringTool/project-authoring-parent/project-authoring-parent.component.scss @@ -0,0 +1,17 @@ +.node-content { + padding: 0px 16px; + position: relative; +} + +.main-content { + margin-bottom: 20px; + width: 100%; +} + +.concurrent-authors-message { + position: sticky; + top: 1px; + padding: 4px 0; + display: block; + z-index: 3; +} diff --git a/src/assets/wise5/authoringTool/project-authoring-parent/project-authoring-parent.component.ts b/src/assets/wise5/authoringTool/project-authoring-parent/project-authoring-parent.component.ts new file mode 100644 index 00000000000..08a74051b27 --- /dev/null +++ b/src/assets/wise5/authoringTool/project-authoring-parent/project-authoring-parent.component.ts @@ -0,0 +1,25 @@ +import { Component } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { TeacherProjectService } from '../../services/teacherProjectService'; + +@Component({ + templateUrl: './project-authoring-parent.component.html', + styleUrls: ['./project-authoring-parent.component.scss'] +}) +export class ProjectAuthoringParentComponent { + protected projectId: number; + + constructor(private projectService: TeacherProjectService, private route: ActivatedRoute) {} + + ngOnInit(): void { + this.projectId = Number(this.route.snapshot.paramMap.get('unitId')); + this.projectService.notifyAuthorProjectBegin(this.projectId); + window.onbeforeunload = (event) => { + this.projectService.notifyAuthorProjectEnd(this.projectId); + }; + } + + ngOnDestroy(): void { + this.projectService.notifyAuthorProjectEnd(this.projectId); + } +} diff --git a/src/assets/wise5/authoringTool/project-authoring/project-authoring.component.html b/src/assets/wise5/authoringTool/project-authoring/project-authoring.component.html index 0c723a9751b..1622181667d 100644 --- a/src/assets/wise5/authoringTool/project-authoring/project-authoring.component.html +++ b/src/assets/wise5/authoringTool/project-authoring/project-authoring.component.html @@ -1,338 +1,305 @@ -<div id="top" class="view-content view-content--with-sidemenu"> - <div class="l-constrained" fxLayout="column"> - <div class="node-content md-whiteframe-1dp" fxLayout="row wrap"> - <div class="main-content"> - <concurrent-authors-message - [projectId]="projectId" - class="concurrent-authors-message center app-background" - ></concurrent-authors-message> - <router-outlet></router-outlet> - <div *ngIf="showProjectView"> - <div class="project-content"> - <div fxLayout="row wrap" fxLayoutGap="15px"> - <button - mat-raised-button - color="primary" - (click)="goBackToProjectList()" - matTooltip="Back to Unit List" - matTooltipPosition="above" - i18n-matTooltip - > - <mat-icon>arrow_back</mat-icon> - </button> - <button - mat-raised-button - color="primary" - (click)="createNewLesson()" - [disabled]="stepNodeSelected || groupNodeSelected" - matTooltip="Create New Lesson" - matTooltipPosition="above" - i18n-matTooltip - > - <mat-icon>queue</mat-icon> - </button> - <button - mat-raised-button - color="primary" - (click)="createNewStep()" - [disabled]="stepNodeSelected || groupNodeSelected" - matTooltip="Create New Step" - matTooltipPosition="above" - i18n-matTooltip - > - <mat-icon>add_box</mat-icon> - </button> - <button - mat-raised-button - color="primary" - (click)="addStructure()" - [disabled]="stepNodeSelected || groupNodeSelected" - matTooltip="Add Lesson Structure" - matTooltipPosition="above" - i18n-matTooltip - > - <mat-icon>widgets</mat-icon> - </button> - <button - mat-raised-button - color="primary" - (click)="importStep()" - [disabled]="stepNodeSelected || groupNodeSelected" - matTooltip="Import Step" - matTooltipPosition="above" - i18n-matTooltip - > - <mat-icon>system_update_alt</mat-icon> - </button> - <button - mat-raised-button - color="primary" - (click)="chooseLocation(false)" - [disabled]="!hasSelectedNodes()" - matTooltip="Move" - matTooltipPosition="above" - i18n-matTooltip - > - <mat-icon>redo</mat-icon> - </button> - <button - mat-raised-button - color="primary" - (click)="chooseLocation(true)" - [disabled]="!hasSelectedStepsOnly()" - matTooltip="Copy" - matTooltipPosition="above" +<div class="project-content"> + <div fxLayout="row wrap" fxLayoutGap="15px"> + <button + mat-raised-button + color="primary" + (click)="goBackToProjectList()" + matTooltip="Back to Unit List" + matTooltipPosition="above" + i18n-matTooltip + > + <mat-icon>arrow_back</mat-icon> + </button> + <button + mat-raised-button + color="primary" + (click)="createNewLesson()" + [disabled]="stepNodeSelected || groupNodeSelected" + matTooltip="Create New Lesson" + matTooltipPosition="above" + i18n-matTooltip + > + <mat-icon>queue</mat-icon> + </button> + <button + mat-raised-button + color="primary" + (click)="createNewStep()" + [disabled]="stepNodeSelected || groupNodeSelected" + matTooltip="Create New Step" + matTooltipPosition="above" + i18n-matTooltip + > + <mat-icon>add_box</mat-icon> + </button> + <button + mat-raised-button + color="primary" + (click)="addStructure()" + [disabled]="stepNodeSelected || groupNodeSelected" + matTooltip="Add Lesson Structure" + matTooltipPosition="above" + i18n-matTooltip + > + <mat-icon>widgets</mat-icon> + </button> + <button + mat-raised-button + color="primary" + (click)="importStep()" + [disabled]="stepNodeSelected || groupNodeSelected" + matTooltip="Import Step" + matTooltipPosition="above" + i18n-matTooltip + > + <mat-icon>system_update_alt</mat-icon> + </button> + <button + mat-raised-button + color="primary" + (click)="chooseLocation(false)" + [disabled]="!hasSelectedNodes()" + matTooltip="Move" + matTooltipPosition="above" + i18n-matTooltip + > + <mat-icon>redo</mat-icon> + </button> + <button + mat-raised-button + color="primary" + (click)="chooseLocation(true)" + [disabled]="!hasSelectedStepsOnly()" + matTooltip="Copy" + matTooltipPosition="above" + i18n-matTooltip + > + <mat-icon>content_copy</mat-icon> + </button> + <button + mat-raised-button + color="primary" + (click)="deleteSelectedNodes()" + [disabled]="!hasSelectedNodes()" + matTooltip="Delete" + matTooltipPosition="above" + i18n-matTooltip + > + <mat-icon>delete</mat-icon> + </button> + <button + mat-raised-button + color="primary" + (click)="goToAdvancedAuthoring()" + [disabled]="stepNodeSelected || groupNodeSelected" + matTooltip="Advanced" + matTooltipPosition="above" + i18n-matTooltip + > + <mat-icon>build</mat-icon> + </button> + <span fxFlex></span> + <button + mat-raised-button + color="primary" + (click)="previewProject()" + matTooltip="Preview Unit" + matTooltipPosition="above" + i18n-matTooltip + > + <mat-icon>visibility</mat-icon> + </button> + </div> +</div> +<div class="all-nodes-div"> + <ng-container *ngFor="let item of items"> + <div *ngIf="item.order !== 0" class="projectItem"> + <div + id="{{ item.key }}" + fxLayout="row" + fxLayoutAlign="start center" + [ngClass]="{ + groupHeader: isGroupNode(item.key), + stepHeader: !isGroupNode(item.key), + branchPathStepHeader: isNodeInAnyBranchPath(item.key) && !isGroupNode(item.key) + }" + [ngStyle]="{ 'background-color': getStepBackgroundColor(item.key) }" + > + <div> + <mat-checkbox + color="primary" + [(ngModel)]="item.checked" + (ngModelChange)="selectNode()" + [disabled]=" + (isGroupNode(item.key) && stepNodeSelected) || + (!isGroupNode(item.key) && groupNodeSelected) + " + aria-label="{{ getNodePositionById(item.key) }} {{ getNodeTitle(item.key) }}" + > + </mat-checkbox> + </div> + <div class="projectItemTitleDiv" (click)="nodeClicked(item.key)"> + <div class="pointer" fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="10px"> + <node-icon [nodeId]="item.key" size="18"></node-icon> + <h6 *ngIf="isGroupNode(item.key)"> + {{ getNodePositionById(item.key) }}: + {{ getNodeTitle(item.key) }} + </h6> + <p *ngIf="!isGroupNode(item.key)" fxLayoutAlign="start center" fxLayoutGap="10px"> + <span>{{ getNodePositionById(item.key) }}: {{ getNodeTitle(item.key) }}</span> + <mat-icon + *ngIf="isBranchPoint(item.key)" + class="rotate-180" + (click)="branchIconClicked(item.key); $event.stopPropagation()" + matTooltip="Branch point with {{ + getNumberOfBranchPaths(item.key) + }} paths based on {{ getBranchCriteriaDescription(item.key) }}" + matTooltipPosition="right" i18n-matTooltip + >call_split</mat-icon > - <mat-icon>content_copy</mat-icon> - </button> - <button - mat-raised-button - color="primary" - (click)="deleteSelectedNodes()" - [disabled]="!hasSelectedNodes()" - matTooltip="Delete" - matTooltipPosition="above" + <mat-icon + *ngIf="nodeHasConstraint(item.key) && getNumberOfConstraintsOnNode(item.key) == 1" + (click)="constraintIconClicked(item.key); $event.stopPropagation()" + matTooltip="{{ getNumberOfConstraintsOnNode(item.key) }} Constraint\n\n{{ + getConstraintDescriptions(item.key) + }}" + matTooltipPosition="right" i18n-matTooltip + >block</mat-icon > - <mat-icon>delete</mat-icon> - </button> - <button - mat-raised-button - color="primary" - (click)="goToAdvancedAuthoring()" - [disabled]="stepNodeSelected || groupNodeSelected" - matTooltip="Advanced" - matTooltipPosition="above" + <mat-icon + *ngIf="nodeHasConstraint(item.key) && getNumberOfConstraintsOnNode(item.key) > 1" + (click)="constraintIconClicked(item.key); $event.stopPropagation()" + matTooltip="{{ getNumberOfConstraintsOnNode(item.key) }} Constraints\n\n{{ + getConstraintDescriptions(item.key) + }}" + matTooltipPosition="right" i18n-matTooltip + >block</mat-icon > - <mat-icon>build</mat-icon> - </button> - <span fxFlex></span> - <button - mat-raised-button - color="primary" - (click)="previewProject()" - matTooltip="Preview Unit" - matTooltipPosition="above" + <mat-icon + *ngIf="nodeHasRubric(item.key)" + matTooltip="Has Rubric" + matTooltipPosition="right" i18n-matTooltip + >message</mat-icon > - <mat-icon>visibility</mat-icon> - </button> + </p> + </div> + </div> + </div> + </div> + </ng-container> + <div> + <h6 class="unused-header">Unused Lessons</h6> + <div *ngIf="getNumberOfInactiveGroups() === 0" i18n>There are no Unused Lessons</div> + <ng-container *ngFor="let inactiveNode of inactiveGroupNodes"> + <div *ngIf="isGroupNode(inactiveNode.id)" id="{{ inactiveNode.id }}"> + <div + fxLayout="row" + fxLayoutAlign="start center" + [ngClass]="{ + groupHeader: isGroupNode(inactiveNode.id), + stepHeader: !isGroupNode(inactiveNode.id), + branchPathStepHeader: + isNodeInAnyBranchPath(inactiveNode.id) && !isGroupNode(inactiveNode.id) + }" + class="projectItem" + > + <div> + <mat-checkbox + color="primary" + [(ngModel)]="inactiveNode.checked" + (ngModelChange)="selectNode()" + [disabled]="stepNodeSelected" + aria-label="{{ getNodeTitle(inactiveNode.id) }}" + > + </mat-checkbox> + </div> + <div class="projectItemTitleDiv" (click)="nodeClicked(inactiveNode.id)"> + <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="10px"> + <node-icon [nodeId]="inactiveNode.id" size="18"></node-icon> + <h6 class="pointer"> + {{ getNodeTitle(inactiveNode.id) }} + </h6> </div> </div> - <div class="all-nodes-div"> - <ng-container *ngFor="let item of items"> - <div *ngIf="item.order !== 0" class="projectItem"> - <div - id="{{ item.key }}" - fxLayout="row" - fxLayoutAlign="start center" - [ngClass]="{ - groupHeader: isGroupNode(item.key), - stepHeader: !isGroupNode(item.key), - branchPathStepHeader: isNodeInAnyBranchPath(item.key) && !isGroupNode(item.key) - }" - [ngStyle]="{ 'background-color': getStepBackgroundColor(item.key) }" + </div> + <ng-container *ngFor="let inactiveChildId of inactiveNode.ids"> + <div class="projectItem" id="{{ inactiveChildId }}"> + <div + fxLayout="row" + [ngClass]="{ + groupHeader: isGroupNode(inactiveChildId.id), + stepHeader: !isGroupNode(inactiveChildId.id), + branchPathStepHeader: + isNodeInAnyBranchPath(inactiveChildId.id) && !isGroupNode(inactiveChildId.id) + }" + class="projectItem" + > + <div> + <mat-checkbox + color="primary" + [(ngModel)]="idToNode[inactiveChildId].checked" + (ngModelChange)="selectNode()" + [disabled]="groupNodeSelected" + aria-label="{{ getNodeTitle(inactiveChildId) }}" > - <div> - <mat-checkbox - color="primary" - [(ngModel)]="item.checked" - (ngModelChange)="selectNode()" - [disabled]=" - (isGroupNode(item.key) && stepNodeSelected) || - (!isGroupNode(item.key) && groupNodeSelected) - " - aria-label="{{ getNodePositionById(item.key) }} {{ getNodeTitle(item.key) }}" - > - </mat-checkbox> - </div> - <div class="projectItemTitleDiv" (click)="nodeClicked(item.key)"> - <div - class="pointer" - fxLayout="row" - fxLayoutAlign="start center" - fxLayoutGap="10px" - > - <node-icon [nodeId]="item.key" size="18"></node-icon> - <h6 *ngIf="isGroupNode(item.key)"> - {{ getNodePositionById(item.key) }}: - {{ getNodeTitle(item.key) }} - </h6> - <p - *ngIf="!isGroupNode(item.key)" - fxLayoutAlign="start center" - fxLayoutGap="10px" - > - <span - >{{ getNodePositionById(item.key) }}: {{ getNodeTitle(item.key) }}</span - > - <mat-icon - *ngIf="isBranchPoint(item.key)" - class="rotate-180" - (click)="branchIconClicked(item.key); $event.stopPropagation()" - matTooltip="Branch point with {{ - getNumberOfBranchPaths(item.key) - }} paths based on {{ getBranchCriteriaDescription(item.key) }}" - matTooltipPosition="right" - i18n-matTooltip - >call_split</mat-icon - > - <mat-icon - *ngIf=" - nodeHasConstraint(item.key) && - getNumberOfConstraintsOnNode(item.key) == 1 - " - (click)="constraintIconClicked(item.key); $event.stopPropagation()" - matTooltip="{{ getNumberOfConstraintsOnNode(item.key) }} Constraint\n\n{{ - getConstraintDescriptions(item.key) - }}" - matTooltipPosition="right" - i18n-matTooltip - >block</mat-icon - > - <mat-icon - *ngIf=" - nodeHasConstraint(item.key) && - getNumberOfConstraintsOnNode(item.key) > 1 - " - (click)="constraintIconClicked(item.key); $event.stopPropagation()" - matTooltip="{{ getNumberOfConstraintsOnNode(item.key) }} Constraints\n\n{{ - getConstraintDescriptions(item.key) - }}" - matTooltipPosition="right" - i18n-matTooltip - >block</mat-icon - > - <mat-icon - *ngIf="nodeHasRubric(item.key)" - matTooltip="Has Rubric" - matTooltipPosition="right" - i18n-matTooltip - >message</mat-icon - > - </p> - </div> - </div> + </mat-checkbox> + </div> + <div class="projectItemTitleDiv" (click)="nodeClicked(inactiveChildId)"> + <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="10px"> + <node-icon [nodeId]="inactiveChildId" size="18"></node-icon> + <p class="pointer"> + {{ getNodeTitle(inactiveChildId) }} + </p> </div> </div> - </ng-container> + </div> + </div> + </ng-container> + </div> + </ng-container> + <div> + <h6 class="unused-header" i18n>Unused Steps</h6> + <div *ngIf="getNumberOfInactiveSteps() === 0" i18n>There are no Unused Steps</div> + <ng-container *ngFor="let inactiveNode of inactiveStepNodes"> + <div + *ngIf="!isGroupNode(inactiveNode.id) && getParentGroup(inactiveNode.id) == null" + class="projectItem" + > + <div + fxLayout="row" + [ngClass]="{ + groupHeader: isGroupNode(inactiveNode.id), + stepHeader: !isGroupNode(inactiveNode.id), + branchPathStepHeader: + isNodeInAnyBranchPath(inactiveNode.id) && !isGroupNode(inactiveNode.id) + }" + > <div> - <h6 class="unused-header">Unused Lessons</h6> - <div *ngIf="getNumberOfInactiveGroups() === 0" i18n>There are no Unused Lessons</div> - <ng-container *ngFor="let inactiveNode of inactiveGroupNodes"> - <div *ngIf="isGroupNode(inactiveNode.id)" id="{{ inactiveNode.id }}"> - <div - fxLayout="row" - fxLayoutAlign="start center" - [ngClass]="{ - groupHeader: isGroupNode(inactiveNode.id), - stepHeader: !isGroupNode(inactiveNode.id), - branchPathStepHeader: - isNodeInAnyBranchPath(inactiveNode.id) && !isGroupNode(inactiveNode.id) - }" - class="projectItem" - > - <div> - <mat-checkbox - color="primary" - [(ngModel)]="inactiveNode.checked" - (ngModelChange)="selectNode()" - [disabled]="stepNodeSelected" - aria-label="{{ getNodeTitle(inactiveNode.id) }}" - > - </mat-checkbox> - </div> - <div class="projectItemTitleDiv" (click)="nodeClicked(inactiveNode.id)"> - <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="10px"> - <node-icon [nodeId]="inactiveNode.id" size="18"></node-icon> - <h6 class="pointer"> - {{ getNodeTitle(inactiveNode.id) }} - </h6> - </div> - </div> - </div> - <ng-container *ngFor="let inactiveChildId of inactiveNode.ids"> - <div class="projectItem" id="{{ inactiveChildId }}"> - <div - fxLayout="row" - [ngClass]="{ - groupHeader: isGroupNode(inactiveChildId.id), - stepHeader: !isGroupNode(inactiveChildId.id), - branchPathStepHeader: - isNodeInAnyBranchPath(inactiveChildId.id) && - !isGroupNode(inactiveChildId.id) - }" - class="projectItem" - > - <div> - <mat-checkbox - color="primary" - [(ngModel)]="idToNode[inactiveChildId].checked" - (ngModelChange)="selectNode()" - [disabled]="groupNodeSelected" - aria-label="{{ getNodeTitle(inactiveChildId) }}" - > - </mat-checkbox> - </div> - <div class="projectItemTitleDiv" (click)="nodeClicked(inactiveChildId)"> - <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="10px"> - <node-icon [nodeId]="inactiveChildId" size="18"></node-icon> - <p class="pointer"> - {{ getNodeTitle(inactiveChildId) }} - </p> - </div> - </div> - </div> - </div> - </ng-container> - </div> - </ng-container> - <div> - <h6 class="unused-header" i18n>Unused Steps</h6> - <div *ngIf="getNumberOfInactiveSteps() === 0" i18n>There are no Unused Steps</div> - <ng-container *ngFor="let inactiveNode of inactiveStepNodes"> - <div - *ngIf="!isGroupNode(inactiveNode.id) && getParentGroup(inactiveNode.id) == null" - class="projectItem" - > - <div - fxLayout="row" - [ngClass]="{ - groupHeader: isGroupNode(inactiveNode.id), - stepHeader: !isGroupNode(inactiveNode.id), - branchPathStepHeader: - isNodeInAnyBranchPath(inactiveNode.id) && !isGroupNode(inactiveNode.id) - }" - > - <div> - <mat-checkbox - color="primary" - [(ngModel)]="inactiveNode.checked" - (ngModelChange)="selectNode()" - [disabled]="groupNodeSelected" - aria-label="{{ getNodeTitle(inactiveNode.id) }}" - > - </mat-checkbox> - </div> - <div class="projectItemTitleDiv" (click)="nodeClicked(inactiveNode.id)"> - <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="10px"> - <node-icon [nodeId]="inactiveNode.id" size="18"></node-icon> - <p class="pointer"> - {{ getNodeTitle(inactiveNode.id) }} - </p> - </div> - </div> - </div> - </div> - </ng-container> + <mat-checkbox + color="primary" + [(ngModel)]="inactiveNode.checked" + (ngModelChange)="selectNode()" + [disabled]="groupNodeSelected" + aria-label="{{ getNodeTitle(inactiveNode.id) }}" + > + </mat-checkbox> + </div> + <div class="projectItemTitleDiv" (click)="nodeClicked(inactiveNode.id)"> + <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="10px"> + <node-icon [nodeId]="inactiveNode.id" size="18"></node-icon> + <p class="pointer"> + {{ getNodeTitle(inactiveNode.id) }} + </p> </div> </div> </div> - <div id="bottom"></div> </div> - </div> + </ng-container> </div> </div> </div> +<div id="bottom"></div> diff --git a/src/assets/wise5/authoringTool/project-authoring/project-authoring.component.scss b/src/assets/wise5/authoringTool/project-authoring/project-authoring.component.scss index 3b6df0840ba..13e78e75400 100644 --- a/src/assets/wise5/authoringTool/project-authoring/project-authoring.component.scss +++ b/src/assets/wise5/authoringTool/project-authoring/project-authoring.component.scss @@ -1,21 +1,3 @@ -.node-content { - padding: 0px 16px; - position: relative; -} - -.main-content { - margin-bottom: 20px; - width: 100%; -} - -.concurrent-authors-message { - position: sticky; - top: 1px; - padding: 4px 0; - display: block; - z-index: 3; -} - .project-content { background-color: white; margin-bottom: 15px; diff --git a/src/assets/wise5/authoringTool/project-authoring/project-authoring.component.spec.ts b/src/assets/wise5/authoringTool/project-authoring/project-authoring.component.spec.ts index 565aec5a104..ba220142239 100644 --- a/src/assets/wise5/authoringTool/project-authoring/project-authoring.component.spec.ts +++ b/src/assets/wise5/authoringTool/project-authoring/project-authoring.component.spec.ts @@ -23,6 +23,7 @@ import { RouterTestingModule } from '@angular/router/testing'; describe('ProjectAuthoringComponent', () => { let component: ProjectAuthoringComponent; let fixture: ComponentFixture<ProjectAuthoringComponent>; + let projectService: TeacherProjectService; beforeEach(async () => { await TestBed.configureTestingModule({ @@ -53,13 +54,12 @@ describe('ProjectAuthoringComponent', () => { TeacherWebSocketService ] }).compileComponents(); - spyOn(TestBed.inject(TeacherProjectService), 'getFlattenedProjectAsNodeIds').and.returnValue([ - 'node1' - ]); - spyOn(TestBed.inject(TeacherProjectService), 'getNodeById').and.returnValue({ - title: 'Step 1' - }); - spyOn(TestBed.inject(TeacherProjectService), 'getInactiveNodes').and.returnValue([]); + projectService = TestBed.inject(TeacherProjectService); + spyOn(projectService, 'parseProject').and.callFake(() => {}); + spyOn(projectService, 'getFlattenedProjectAsNodeIds').and.returnValue(['node1']); + spyOn(projectService, 'getNodeById').and.returnValue({ title: 'Step 1' }); + spyOn(projectService, 'getInactiveNodes').and.returnValue([]); + window.history.pushState({}, '', ''); fixture = TestBed.createComponent(ProjectAuthoringComponent); component = fixture.componentInstance; fixture.detectChanges(); diff --git a/src/assets/wise5/authoringTool/project-authoring/project-authoring.component.ts b/src/assets/wise5/authoringTool/project-authoring/project-authoring.component.ts index 3814e2de197..dffaa1fd4b4 100644 --- a/src/assets/wise5/authoringTool/project-authoring/project-authoring.component.ts +++ b/src/assets/wise5/authoringTool/project-authoring/project-authoring.component.ts @@ -4,9 +4,9 @@ import { DeleteNodeService } from '../../services/deleteNodeService'; import { TeacherProjectService } from '../../services/teacherProjectService'; import { TeacherDataService } from '../../services/teacherDataService'; import * as $ from 'jquery'; -import { Subscription, filter } from 'rxjs'; +import { Subscription } from 'rxjs'; import { temporarilyHighlightElement } from '../../common/dom/dom'; -import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; @Component({ selector: 'project-authoring', @@ -21,7 +21,6 @@ export class ProjectAuthoringComponent { protected inactiveStepNodes: any[]; protected items: any; protected projectId: number; - protected showProjectView: boolean = true; protected stepNodeSelected: boolean = false; private subscriptions: Subscription = new Subscription(); @@ -32,42 +31,31 @@ export class ProjectAuthoringComponent { private dataService: TeacherDataService, private route: ActivatedRoute, private router: Router - ) { - this.subscriptions.add( - this.router.events.pipe(filter((event) => event instanceof NavigationEnd)).subscribe(() => { - this.updateShowProjectView(); - this.temporarilyHighlightNewNodes(history.state.newNodes); - }) - ); - } + ) {} ngOnInit(): void { - this.updateShowProjectView(); this.projectId = Number(this.route.snapshot.paramMap.get('unitId')); - this.items = this.projectService.getNodesInOrder(); - this.inactiveGroupNodes = this.projectService.getInactiveGroupNodes(); - this.inactiveStepNodes = this.projectService.getInactiveStepNodes(); - this.inactiveNodes = this.projectService.getInactiveNodes(); - this.idToNode = this.projectService.getIdToNode(); - this.projectService.notifyAuthorProjectBegin(this.projectId); + this.refreshProject(); + this.temporarilyHighlightNewNodes(history.state.newNodes); this.subscriptions.add( this.projectService.refreshProject$.subscribe(() => { this.refreshProject(); }) ); - - window.onbeforeunload = (event) => { - this.projectService.notifyAuthorProjectEnd(this.projectId); - }; } ngOnDestroy(): void { - this.projectService.notifyAuthorProjectEnd(this.projectId); this.subscriptions.unsubscribe(); } - private updateShowProjectView(): void { - this.showProjectView = /\/teacher\/edit\/unit\/(\d*)$/.test(this.router.url); + private refreshProject(): void { + this.projectService.parseProject(); + this.items = this.projectService.getNodesInOrder(); + this.inactiveGroupNodes = this.projectService.getInactiveGroupNodes(); + this.inactiveStepNodes = this.projectService.getInactiveStepNodes(); + this.inactiveNodes = this.projectService.getInactiveNodes(); + this.idToNode = this.projectService.getIdToNode(); + this.unselectAllItems(); } protected previewProject(): void { @@ -164,16 +152,6 @@ export class ProjectAuthoringComponent { this.router.navigate([`/teacher/edit/unit/${this.projectId}/structure/choose`]); } - private refreshProject(): void { - this.projectService.parseProject(); - this.items = this.projectService.getNodesInOrder(); - this.inactiveGroupNodes = this.projectService.getInactiveGroupNodes(); - this.inactiveStepNodes = this.projectService.getInactiveStepNodes(); - this.inactiveNodes = this.projectService.getInactiveNodes(); - this.idToNode = this.projectService.getIdToNode(); - this.unselectAllItems(); - } - protected importStep(): void { this.router.navigate([`/teacher/edit/unit/${this.projectId}/import-step/choose-step`]); } diff --git a/src/messages.xlf b/src/messages.xlf index 75c26056447..b73a239a5cb 100644 --- a/src/messages.xlf +++ b/src/messages.xlf @@ -697,7 +697,7 @@ </context-group> <context-group purpose="location"> <context context-type="sourcefile">src/assets/wise5/authoringTool/project-authoring/project-authoring.component.html</context> - <context context-type="linenumber">94</context> + <context context-type="linenumber">84</context> </context-group> <context-group purpose="location"> <context context-type="sourcefile">src/assets/wise5/components/animation/animation-authoring/animation-authoring.component.html</context> @@ -1479,7 +1479,7 @@ Click "Cancel" to keep the invalid JSON open so you can fix it.</sourc </context-group> <context-group purpose="location"> <context context-type="sourcefile">src/assets/wise5/authoringTool/project-authoring/project-authoring.component.html</context> - <context context-type="linenumber">116</context> + <context context-type="linenumber">106</context> </context-group> <context-group purpose="location"> <context context-type="sourcefile">src/assets/wise5/classroomMonitor/classroomMonitorComponents/shared/top-bar/top-bar.component.html</context> @@ -5309,7 +5309,7 @@ Click "Cancel" to keep the invalid JSON open so you can fix it.</sourc </context-group> <context-group purpose="location"> <context context-type="sourcefile">src/assets/wise5/authoringTool/project-authoring/project-authoring.component.html</context> - <context context-type="linenumber">83</context> + <context context-type="linenumber">73</context> </context-group> <context-group purpose="location"> <context context-type="sourcefile">src/assets/wise5/authoringTool/project-list/project-list.component.html</context> @@ -9700,7 +9700,7 @@ Click "Cancel" to keep the invalid JSON open so you can fix it.</sourc </context-group> <context-group purpose="location"> <context context-type="sourcefile">src/assets/wise5/authoringTool/project-authoring/project-authoring.component.html</context> - <context context-type="linenumber">223</context> + <context context-type="linenumber">196</context> </context-group> </trans-unit> <trans-unit id="a10dba8eb1f22a5f90f90e79b8305963eec3ee38" datatype="html"> @@ -9715,7 +9715,7 @@ Click "Cancel" to keep the invalid JSON open so you can fix it.</sourc </context-group> <context-group purpose="location"> <context context-type="sourcefile">src/assets/wise5/authoringTool/project-authoring/project-authoring.component.html</context> - <context context-type="linenumber">293</context> + <context context-type="linenumber">265</context> </context-group> </trans-unit> <trans-unit id="0217500199a3e48a7b95762b14b79dad49e76beb" datatype="html"> @@ -9730,7 +9730,7 @@ Click "Cancel" to keep the invalid JSON open so you can fix it.</sourc </context-group> <context-group purpose="location"> <context context-type="sourcefile">src/assets/wise5/authoringTool/project-authoring/project-authoring.component.html</context> - <context context-type="linenumber">294</context> + <context context-type="linenumber">266</context> </context-group> </trans-unit> <trans-unit id="f951d80b53d5536f79142285e8ba09f190a3c723" datatype="html"> @@ -11486,7 +11486,7 @@ Click "Cancel" to keep the invalid JSON open so you can fix it.</sourc </context-group> <context-group purpose="location"> <context context-type="sourcefile">src/assets/wise5/authoringTool/project-authoring/project-authoring.component.html</context> - <context context-type="linenumber">105</context> + <context context-type="linenumber">95</context> </context-group> </trans-unit> <trans-unit id="4f26c54d5c3edadf92756d7d3ce466dde1f01e2a" datatype="html"> @@ -12114,90 +12114,90 @@ Click "Cancel" to keep the invalid JSON open so you can fix it.</sourc <source>Back to Unit List</source> <context-group purpose="location"> <context context-type="sourcefile">src/assets/wise5/authoringTool/project-authoring/project-authoring.component.html</context> - <context context-type="linenumber">17</context> + <context context-type="linenumber">7</context> </context-group> </trans-unit> <trans-unit id="bcf0ed433ab4782db0764ae24fb015e22520f41f" datatype="html"> <source>Create New Lesson</source> <context-group purpose="location"> <context context-type="sourcefile">src/assets/wise5/authoringTool/project-authoring/project-authoring.component.html</context> - <context context-type="linenumber">28</context> + <context context-type="linenumber">18</context> </context-group> </trans-unit> <trans-unit id="93c7d1ec242f9b1551ee0b4ac7dc133dbeab61cf" datatype="html"> <source>Create New Step</source> <context-group purpose="location"> <context context-type="sourcefile">src/assets/wise5/authoringTool/project-authoring/project-authoring.component.html</context> - <context context-type="linenumber">39</context> + <context context-type="linenumber">29</context> </context-group> </trans-unit> <trans-unit id="2b3f9a010395471098728a566cd3849bed9f3301" datatype="html"> <source>Add Lesson Structure</source> <context-group purpose="location"> <context context-type="sourcefile">src/assets/wise5/authoringTool/project-authoring/project-authoring.component.html</context> - <context context-type="linenumber">50</context> + <context context-type="linenumber">40</context> </context-group> </trans-unit> <trans-unit id="3538ada3bf07e331bafa52cf68b5862c1670a695" datatype="html"> <source>Import Step</source> <context-group purpose="location"> <context context-type="sourcefile">src/assets/wise5/authoringTool/project-authoring/project-authoring.component.html</context> - <context context-type="linenumber">61</context> + <context context-type="linenumber">51</context> </context-group> </trans-unit> <trans-unit id="57cf305f9bfd681c70dc26e914108d06384ade9f" datatype="html"> <source>Move</source> <context-group purpose="location"> <context context-type="sourcefile">src/assets/wise5/authoringTool/project-authoring/project-authoring.component.html</context> - <context context-type="linenumber">72</context> + <context context-type="linenumber">62</context> </context-group> </trans-unit> - <trans-unit id="ba598ed596aebc49e193351062110e4d64897ce2" datatype="html"> + <trans-unit id="2babf1354d25bf42fc198b512e41efe699029adc" datatype="html"> <source>Branch point with <x id="INTERPOLATION" equiv-text="{{ - getNumberOfBranchPaths(item.key) - }}"/> paths based on <x id="INTERPOLATION_1" equiv-text="{{ getBranchCriteriaDescription(item.key) }}"/></source> + getNumberOfBranchPaths(item.key) + }}"/> paths based on <x id="INTERPOLATION_1" equiv-text="{{ getBranchCriteriaDescription(item.key) }}"/></source> <context-group purpose="location"> <context context-type="sourcefile">src/assets/wise5/authoringTool/project-authoring/project-authoring.component.html</context> - <context context-type="linenumber">175,177</context> + <context context-type="linenumber">154,156</context> </context-group> </trans-unit> - <trans-unit id="d2ccd4d6c7f329e359959ef05401ceb24408b711" datatype="html"> + <trans-unit id="30e48681d6264197efea8455adfefd170a75e87f" datatype="html"> <source><x id="INTERPOLATION" equiv-text="{{ getNumberOfConstraintsOnNode(item.key) }}"/> Constraint\n\n<x id="INTERPOLATION_1" equiv-text="{{ - getConstraintDescriptions(item.key) - }}"/></source> + getConstraintDescriptions(item.key) + }}"/></source> <context-group purpose="location"> <context context-type="sourcefile">src/assets/wise5/authoringTool/project-authoring/project-authoring.component.html</context> - <context context-type="linenumber">188,190</context> + <context context-type="linenumber">164,166</context> </context-group> </trans-unit> - <trans-unit id="97508c2924a55e395236962196cecae6e0900e86" datatype="html"> + <trans-unit id="352c3d81453aabe6f46a08ce422003e76f85f041" datatype="html"> <source><x id="INTERPOLATION" equiv-text="{{ getNumberOfConstraintsOnNode(item.key) }}"/> Constraints\n\n<x id="INTERPOLATION_1" equiv-text="{{ - getConstraintDescriptions(item.key) - }}"/></source> + getConstraintDescriptions(item.key) + }}"/></source> <context-group purpose="location"> <context context-type="sourcefile">src/assets/wise5/authoringTool/project-authoring/project-authoring.component.html</context> - <context context-type="linenumber">201,203</context> + <context context-type="linenumber">174,176</context> </context-group> </trans-unit> <trans-unit id="b3b4847175a6193afa85eb431bbe16d1f04470fa" datatype="html"> <source>Has Rubric</source> <context-group purpose="location"> <context context-type="sourcefile">src/assets/wise5/authoringTool/project-authoring/project-authoring.component.html</context> - <context context-type="linenumber">210</context> + <context context-type="linenumber">183</context> </context-group> </trans-unit> <trans-unit id="791981839110791639" datatype="html"> <source>Are you sure you want to delete the selected item?</source> <context-group purpose="location"> <context context-type="sourcefile">src/assets/wise5/authoringTool/project-authoring/project-authoring.component.ts</context> - <context context-type="linenumber">117</context> + <context context-type="linenumber">95</context> </context-group> </trans-unit> <trans-unit id="1189930234736223663" datatype="html"> <source>Are you sure you want to delete the <x id="PH" equiv-text="selectedNodeIds.length"/> selected items?</source> <context-group purpose="location"> <context context-type="sourcefile">src/assets/wise5/authoringTool/project-authoring/project-authoring.component.ts</context> - <context context-type="linenumber">118</context> + <context context-type="linenumber">96</context> </context-group> </trans-unit> <trans-unit id="e8fb2ceb6f8d4c3e90a6a688e9024461e67f44f0" datatype="html">