Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[#13144] Copy students from existing students table to new students table #13146

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"lint:css:syntax": "stylelint \"src/web/**/*.css\" \"src/web/**/*.scss\" \"src/web/**/*.html\" --ignore-pattern \"src/web/dist/*.css\" --cache --config static-analysis/teammates-stylelint.yml",
"lint:css:styles": "prettier --print-width=120 --single-quote=true \"src/web/**/*.css\" \"src/web/**/*.scss\"",
"lint:windows:spaces": "lintspaces -n -t -d spaces -l 1 -. \"src/main/**/*.html\" \"src/web/**/*.html\" \"src/**/*.xml\" \"src/**/*.json\" \"src/**/*.properties\" \"*.yml\" \"*.json\" \"*.gradle\" \"static-analysis/*.*ml\" \".gitattributes\"",
"lint:nix:spaces": "lintspaces -n -t -d spaces -l 1 --matchdotfiles $(git diff --name-only --diff-filter=ACMRTUXB origin/master HEAD | grep -E \"src/(main|web)/.*.html|src/.*.(xml|json|properties)|*.(yml|json|gradle)|static-analysis/*.*ml|.gitattributes\") || :",
"lint:nix:spaces": "lintspaces -n -t -d spaces -l 1 --matchdotfiles $(git diff --name-only --diff-filter=ACMRTUXB origin/master HEAD | grep -E \"src/(main|web)/.*\\.html|src/.*\\.(xml|json|properties)|.*\\.(yml|json|gradle)|static-analysis/.*\\.(xml|yml)\") || :",
"lint": "run-script-os",
"lint:windows": "npm-run-all lint:ts lint:css:syntax lint:css:styles lint:windows:spaces -c",
"lint:nix": "npm-run-all lint:ts lint:css:syntax lint:css:styles lint:nix:spaces -c"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,26 @@ <h1 id="enroll-header" class="text-break">Enroll Students for {{ courseId }}</h1
</div>
</div>
<div class="enroll-button-group">
<button
[ngClass]="{'w-50': isCopying}"
type="button"
title="Copy"
id="btn-copy"
name="button-copy"
class="btn btn-info"
[disabled]="isCopying"
(click)="copyStudents()">
<tm-progress-bar *ngIf="isCopying"></tm-progress-bar>
<tm-ajax-loading *ngIf="isCopying"></tm-ajax-loading>
Copy students
</button>
<button
[ngClass]="{'w-50': isEnrolling}"
type="submit"
title="Enroll"
id="btn-enroll"
name="button-enroll"
class="btn btn-success float-end"
class="btn btn-success"
[disabled]="isEnrolling"
(click)="submitEnrollData()">
<tm-progress-bar *ngIf="isEnrolling"></tm-progress-bar>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,9 @@
}

.enroll-button-group {
display: flex;
justify-content: space-between;
width: 50%;
display: inline-block;
}

.enroll-button-group * {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export class InstructorCourseEnrollPageComponent implements OnInit {
isLoadingCourseEnrollPage: boolean = false;
showEnrollResults?: boolean = false;
enrollErrorMessage: string = '';
copyErrorMessage: string = '';
statusMessage: StatusMessage[] = [];
unsuccessfulEnrolls: { [email: string]: string } = {};

Expand Down Expand Up @@ -89,6 +90,7 @@ export class InstructorCourseEnrollPageComponent implements OnInit {
isLoadingExistingStudents: boolean = false;
isAjaxSuccess: boolean = true;
isEnrolling: boolean = false;
isCopying: boolean = false;

allStudentChunks: StudentEnrollRequest[][] = [];
invalidRowsIndex: Set<number> = new Set();
Expand Down Expand Up @@ -244,6 +246,49 @@ export class InstructorCourseEnrollPageComponent implements OnInit {
});
}

/**
* Copies data from existing students HOT to new students HOT
* The data is copied only if the existing students tab is expanded
*/
copyStudents(): void {
this.isCopying = true;
this.copyErrorMessage = '';
this.allStudentChunks = [];

const lastColIndex: number = 4;
const existingStudentsHOTInstance: Handsontable =
this.hotRegisterer.getInstance(this.existingStudentsHOT);
const newStudentsHOTInstance: Handsontable =
this.hotRegisterer.getInstance(this.newStudentsHOT);
const hotInstanceColHeaders: string[] = (newStudentsHOTInstance.getColHeader() as string[]);

const copyData = (): void => {
const existingStudentsData: Handsontable.CellValue[] = existingStudentsHOTInstance.getData();

if (existingStudentsData.length === 0) {
this.copyErrorMessage = 'No data to copy from existing students.';
this.isCopying = false;
return;
}

newStudentsHOTInstance.loadData(existingStudentsData);

this.resetTableStyle(newStudentsHOTInstance, 0,
newStudentsHOTInstance.getData().length - 1,
0,
hotInstanceColHeaders.indexOf(this.colHeaders[lastColIndex]));

this.isCopying = false;
this.statusMessageService.showSuccessToast('Students copied successfully.');
};

if (this.isExistingStudentsPanelCollapsed) {
this.toggleExistingStudentsPanel(copyData);
} else {
copyData();
}
}

private prepareEnrollmentResults(enrolledStudents: Student[],
studentEnrollRequests: Map<number, StudentEnrollRequest>): void {
this.enrollResultPanelList = this.populateEnrollResultPanelList(this.existingStudents,
Expand Down Expand Up @@ -546,7 +591,7 @@ export class InstructorCourseEnrollPageComponent implements OnInit {
/**
* Toggles the view of 'Existing Students' spreadsheet interface
*/
toggleExistingStudentsPanel(): void {
toggleExistingStudentsPanel(callback?: () => void): void {
// Has to be done before the API call is made so that HOT is available for data population
this.isExistingStudentsPanelCollapsed = !this.isExistingStudentsPanelCollapsed;
this.isLoadingExistingStudents = true;
Expand All @@ -556,6 +601,7 @@ export class InstructorCourseEnrollPageComponent implements OnInit {
// Calling REST API only the first time when spreadsheet has no data
if (this.getSpreadsheetLength(existingStudentsHOTInstance.getData()) !== 0) {
this.isLoadingExistingStudents = false;
if (callback) callback();
return;
}

Expand All @@ -576,6 +622,7 @@ export class InstructorCourseEnrollPageComponent implements OnInit {
},
complete: () => {
this.isLoadingExistingStudents = false;
if (callback) callback();
},
});
}
Expand Down
Loading