Skip to content
Open
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
8,127 changes: 4,810 additions & 3,317 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"build:angular17": "ng build",
"lint:fix": "ng lint --fix",
"lint": "ng lint",
"serve:angular17": "export NODE_OPTIONS=--max_old_space_size=4096 && ng serve --configuration $NODE_ENV",
"serve:angular17": "export NODE_OPTIONS=--max_old_space_size=4096 && ng serve --poll=2000 --configuration $NODE_ENV",
"start": "npm-run-all -l -s build:angular1 -p watch:angular1 serve:angular17",
"watch:angular1": "grunt delta",
"deploy:build2api": "ng build --delete-output-path=true --optimization=true --configuration production --output-path dist",
Expand Down Expand Up @@ -81,7 +81,7 @@
"ng-csv": "0.2.3",
"ng-file-upload": "~5.0.9",
"ng-flex-layout": "^17.3.7-beta.1",
"ng2-pdf-viewer": "^10.2",
"ng2-pdf-viewer": "10.2.2",
"ngx-bootstrap": "^6.1.0",
"ngx-entity-service": "^0.0.39",
"ngx-lottie": "^11.0.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,32 @@ <h3 mat-dialog-title>Create Unit</h3>
<input matInput placeholder="Introduction to OnTrack" name="unitName" ngModel />
</mat-form-field>

<mat-form-field appearance="outline">
<mat-label>Credit Points</mat-label>
<input matInput type="number" placeholder="e.g., 1" name="creditpoint" ngModel min="0" />
</mat-form-field>

<mat-form-field appearance="outline">
<mat-label>Teaching Period</mat-label>
<mat-select (valueChange)="handleChangeTeachingPeriod($event)" name="selectedTeachingPeriod" ngModel>
<mat-option value="custom"> Custom teaching period </mat-option>
<mat-option value="custom">Custom teaching period</mat-option>
<mat-option *ngFor="let tp of teachingPeriods; let i = index" [value]="tp.id">
{{ tp.name }}
</mat-option>
</mat-select>
</mat-form-field>

@if(showDates) {
<mat-form-field appearance="outline">
<mat-label>Enter a date range</mat-label>
<mat-date-range-input [rangePicker]="picker">
<input matStartDate placeholder="Start date" name="customStardDate" [(ngModel)]="startDate" />
<input matEndDate placeholder="End date" name="customEndDate" [(ngModel)]="endDate" />
</mat-date-range-input>
<mat-hint>DD/MM/YYYY - DD/MM/YYYY</mat-hint>
<mat-datepicker-toggle matIconSuffix [for]="picker"></mat-datepicker-toggle>
<mat-date-range-picker #picker></mat-date-range-picker>
</mat-form-field>
<mat-form-field appearance="outline">
<mat-label>Enter a date range</mat-label>
<mat-date-range-input [rangePicker]="picker">
<input matStartDate placeholder="Start date" name="customStartDate" [(ngModel)]="startDate" />
<input matEndDate placeholder="End date" name="customEndDate" [(ngModel)]="endDate" />
</mat-date-range-input>
<mat-hint>DD/MM/YYYY - DD/MM/YYYY</mat-hint>
<mat-datepicker-toggle matIconSuffix [for]="picker"></mat-datepicker-toggle>
<mat-date-range-picker #picker></mat-date-range-picker>
</mat-form-field>
}

<mat-dialog-actions align="end">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@ export class CreateNewUnitModalContentComponent implements OnInit {
private alerts: AlertService,
) {}
showDates = false;
startDate: Date;
startDate: Date
endDate: Date;
selectedTeachingPeriod: number = null;
corequisite: string = "null";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be a "null" string, but just null.

teachingPeriods: TeachingPeriod[];

ngOnInit(): void {
this.teachingPeriodsService.fetchAll().subscribe((teachingPeriods) => {
this.teachingPeriods = teachingPeriods;
});
}

public createUnit(unit: { unitName: string; unitCode: string; selectedTeachingPeriod: number }): void {
public createUnit(unit: { unitName: string; unitCode: string; selectedTeachingPeriod: number; creditpoint: number; prerequisite: string }): void {
let newUnit;

if (this.selectedTeachingPeriod === null) {
Expand All @@ -36,12 +36,18 @@ export class CreateNewUnitModalContentComponent implements OnInit {
name: unit.unitName,
start_date: this.startDate,
end_date: this.endDate,
creditpoint: unit.creditpoint,
prerequisite: unit.prerequisite,
corequisite: this.corequisite
};
} else {
newUnit = {
code: unit.unitCode,
name: unit.unitName,
teaching_period_id: this.selectedTeachingPeriod,
creditpoint: unit.creditpoint,
prerequisite: unit.prerequisite,
corequisite: this.corequisite
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,16 @@ <h3>Create Unit</h3>
<input type="text" class="form-control" ng-model="unit.code" placeholder="COS123456"/>
</div>
</div>
<div class="form-group" required>
<label class="col-sm-3 control-label">Credit Points</label>
<div class="col-sm-7">
<input type="number" class="form-control" ng-model="unit.creditPoints" placeholder="e.g., 1" min="0"/>
</div>
</div>
</div>
<div class="modal-footer text-right">
<input type="submit" class="btn btn-primary" value="Create" ng-disabled="unit.name == null || unit.code == null"/>
<input type="submit" class="btn btn-primary" value="Create"
ng-disabled="unit.name == null || unit.code == null || unit.creditPoints == null"/>
</div>
</form>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<h3 mat-dialog-title>Unit Details</h3>

<div mat-dialog-content class="pt-4">
<p><strong>Unit Code:</strong> {{ unit.code }}</p>
<p><strong>Name:</strong> {{ unit.name }}</p>
<p>
<strong>Description:</strong><br /> {{ unit.description }}
</p>

<!-- Requirements Section -->
<div class="requirements-container mt-3">
<h3>Requirements</h3>

<div *ngIf="isLoading" class="loading-indicator">
Loading requirements...
</div>

<div *ngIf="errorMessage" class="error-message text-danger">
{{ errorMessage }}
</div>

<div *ngIf="!isLoading && !errorMessage && requirements.length === 0" class="no-requirements">
No requirements found for this unit.
</div>

<div *ngIf="requirements.length > 0" class="requirements-list">
<div *ngFor="let requirement of requirements" class="requirement-item mb-2">
<div><strong>Type:</strong> {{ requirement.type }}</div>
<div><strong>Category:</strong> {{ requirement.category }}</div>
<div><strong>Minimum: </strong> {{ requirement.minimum }}</div>
<div><strong>Maximum: </strong>{{ requirement.maximum }}</div>
</div>
</div>
</div>
</div>

<mat-dialog-actions align="end">
<button mat-button mat-dialog-close>Close</button>
</mat-dialog-actions>
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
import { MatButtonModule } from '@angular/material/button';
import { CommonModule } from '@angular/common';
import { UnitDefinition } from 'src/app/api/models/unit-definition';
import { RequirementService } from 'src/app/services/requirement.service';
import { Requirement } from 'src/app/api/models/requirement-definition';

@Component({
selector: 'unit-description-modal-content',
standalone: true,
imports: [CommonModule, MatDialogModule, MatButtonModule],
templateUrl: 'unit-description-modal-content.component.html',
})
export class UnitDescriptionModalContentComponent implements OnInit {
requirements: Requirement[] = [];
isLoading = false;
errorMessage = '';

constructor(
@Inject(MAT_DIALOG_DATA) public unit: UnitDefinition,
private requirementService: RequirementService
) {}

ngOnInit(): void {
this.loadRequirements();
}

loadRequirements(): void {
this.isLoading = true;
this.requirementService.getByUnitId(this.unit.id).subscribe({
next: (requirements) => {
this.requirements = requirements;
this.isLoading = false;
},
error: (error) => {
console.error('Error loading requirements:', error);
this.errorMessage = 'Failed to load requirements. Please try again later.';
this.isLoading = false;
}
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Component } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { UnitDescriptionModalContentComponent } from './unit-description-modal-content.component';
import { UnitDefinition } from 'src/app/api/models/unit-definition'; // Adjust path if needed

@Component({
selector: 'unit-description-modal',
template: '',
})
export class UnitDescriptionModal {
constructor(private dialog: MatDialog) {}

public show(unit: UnitDefinition): void {
this.dialog.open(UnitDescriptionModalContentComponent, {
width: '500px',
data: unit,
});
}
}
11 changes: 11 additions & 0 deletions src/app/api/models/requirement-definition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export interface Requirement {
id: number;
unitId: number;
courseId: number;
type: string;
category: string;
description: string;
minimum: number;
maximum: number;
requirementSetGroupId: number;
}
3 changes: 1 addition & 2 deletions src/app/api/models/unit-definition.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
export interface UnitDefinition {
id?: number;
id: number;
name: string;
description: string;
code: string;
}

14 changes: 13 additions & 1 deletion src/app/api/services/unit-definition.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {Observable} from 'rxjs';
import {HttpClient, HttpParams} from '@angular/common/http';

import API_URL from 'src/app/config/constants/apiURL';
import { param } from 'jquery';

@Injectable({
providedIn: 'root'
Expand Down Expand Up @@ -41,12 +42,18 @@ export class UnitDefinitionService {
description: string,
code: string,
version: string,
tasknum: number,
unitTutorFirstName: string,
unitTutorLastName: string,
): Observable<UnitDefinition> {
let params = new HttpParams();
params.set('name', name);
params.set('description', description);
params.set('code', code);
params.set('version', version);
params.set('Number of Tasks', tasknum);
params.set('Unit Tutor first name', unitTutorFirstName);
params.set('Unit Tutor last name', unitTutorLastName);
console.log("added unit definition");
return this.http.post<UnitDefinition>(this.baseUrl, {params});
}
Expand All @@ -56,13 +63,18 @@ export class UnitDefinitionService {
name: string,
description: string,
code: string,
tasknum: number,
unitTutorFirstName: string,
unitTutorLastName: string,
): Observable<UnitDefinition> {
const params = new HttpParams();
params.set('unitDefinitionId', unitDefinitionId.toString());
params.set('name', name);
params.set('description', description);
params.set('code', code);

params.set('Number of Tasks', tasknum);
params.set('Unit Tutor first name', unitTutorFirstName);
params.set('Unit Tutor last name', unitTutorLastName);
Comment on lines +76 to +77
Copy link

@aNebula aNebula Jun 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These shouldn't be in courseflow - there is no need to include this, unless they are used.

const url = `${this.baseUrl}/:id:`;
return this.http.put<UnitDefinition>(url, {params});
}
Expand Down
31 changes: 25 additions & 6 deletions src/app/courseflow/coursemap/coursemap.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ <h3 class="required-units-title">Required Units</h3>
[id]="'requiredUnits'"
>
<div class="unit" *ngFor="let unit of requiredUnits" cdkDrag>
<strong>{{ unit.code }}</strong> - {{ unit.name }}
<div>
<strong>{{ unit.code }}</strong> - {{ unit.name }}
<button mat-icon-button class="info-button" (click)="openUnitDetailModal(unit)">
<mat-icon>more_vert</mat-icon>
</button>
</div>
</div>
</div>
<div class="electives-container">
Expand All @@ -27,7 +32,7 @@ <h3 class="electives-title">Elective Units</h3>
[id]="electiveUnits"
>
<div class="text" *ngFor="let unit of electiveUnits" cdkDrag class="unit">
<p >
<p>
<strong>{{ unit.code }}</strong> - {{ unit.name }}
</p>
</div>
Expand All @@ -39,7 +44,6 @@ <h3 class="electives-title">Elective Units</h3>
<input class="search-bar" matInput [(ngModel)]="unitCode" name="unitCode" id="unitCode"/>
</mat-form-field>
<button mat-flat-button class="button" color="primary" type="submit">Add Unit</button>

<div *ngIf="errorMessage" class="error">
{{ errorMessage }}
</div>
Expand Down Expand Up @@ -73,7 +77,12 @@ <h3 class="year-title">{{ year.year }}</h3>
<h5 class="trimester-heading">Trimester 1</h5>

<div *ngFor="let unit of year.trimester1" cdkDrag class="unit">
<strong>{{ unit.code }}</strong> - {{ unit.name }}
<div>
<strong>{{ unit.code }}</strong> - {{ unit.name }}
<button mat-icon-button class="info-button" (click)="openUnitDetailModal(unit)">
<mat-icon>more_vert</mat-icon>
</button>
</div>
</div>
<button class="delete-button" mat-icon-button (click)="deleteTrimester(i, 0)">
<mat-icon>delete</mat-icon>
Expand All @@ -92,7 +101,12 @@ <h5 class="trimester-heading">Trimester 1</h5>
<h5 class="trimester-heading">Trimester 2</h5>

<div *ngFor="let unit of year.trimester2" cdkDrag class="unit">
<strong>{{ unit.code }}</strong> - {{ unit.name }}
<div>
<strong>{{ unit.code }}</strong> - {{ unit.name }}
<button mat-icon-button class="info-button" (click)="openUnitDetailModal(unit)">
<mat-icon>more_vert</mat-icon>
</button>
</div>
</div>
<button class="delete-button" mat-icon-button (click)="deleteTrimester(i, 1)">
<mat-icon>delete</mat-icon>
Expand All @@ -111,7 +125,12 @@ <h5 class="trimester-heading">Trimester 2</h5>
<h5 class="trimester-heading">Trimester 3</h5>

<div *ngFor="let unit of year.trimester3" cdkDrag class="unit">
<strong>{{ unit.code }}</strong> - {{ unit.name }}
<div>
<strong>{{ unit.code }}</strong> - {{ unit.name }}
<button mat-icon-button class="info-button" (click)="openUnitDetailModal(unit)">
<mat-icon>more_vert</mat-icon>
</button>
</div>
</div>
<button class="delete-button" mat-icon-button (click)="deleteTrimester(i, 2)">
<mat-icon>delete</mat-icon>
Expand Down
Loading