Skip to content

Commit ad50805

Browse files
authored
Merge pull request #1 from kwakuduahc1/Results
Results
2 parents bd11ad3 + 45b8115 commit ad50805

File tree

110 files changed

+3740
-394
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

110 files changed

+3740
-394
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Injectable } from '@angular/core';
2+
import { IStudents } from '../app/model/IStudents';
3+
4+
@Injectable()
5+
export class StudentsService {
6+
private stds!: IStudents[];
7+
constructor() {
8+
}
9+
10+
get():IStudents[] {
11+
return this.stds;
12+
}
13+
14+
set(stds: IStudents[]) {
15+
this.stds = stds;
16+
}
17+
}

TeachingAssistantUltimate/ClientApp/app/app.shared.module.ts

+57-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,26 @@ import { QuillEditorModule } from './Editor';
2323
import { TopicsResolver } from './resolvers/TopicsResolver';
2424
import { HttpClientModule } from '@angular/common/http';
2525
import { PrintProviderService } from './providers/print-provider.service';
26+
import { AssTypesComponent } from './components/ass-types/ass-types.component';
27+
import { AssTypesResolver } from './resolvers/AssTypesResolver';
28+
import { EditAssTypeComponent } from './components/edit-ass-type/edit-ass-type.component';
29+
import { AssTypeResolver } from './resolvers/AssTypeResolver';
30+
import { ClassesComponent } from './components/classes/classes.component';
31+
import { ClassessHttpProvider } from './providers/classes-http-provider';
32+
import { AssessTypeHttpProvider } from './providers/ass-types-http-provider';
33+
import { ClassesResolver } from './resolvers/ClassesResolver';
34+
import { PreviewStudentsComponent } from './components/preview-students/preview-students.component';
35+
import { StudentsService } from '../Services/students.service';
36+
import { StudentsHttpProvider } from './providers/students-http-provider';
37+
import { ClassResolver } from './resolvers/ClassResolver';
38+
import { AddResultsComponent } from './components/add-results/add-results.component';
39+
import { StudentsResolver } from './resolvers/StudentsResolver';
40+
import { ResultsHttpProvider } from './providers/results-http-provider';
41+
import { ClassSubjectsResolver } from './resolvers/ClassSubjectsResolver';
42+
import { ViwResultsComponent } from './components/viw-results/viw-results.component';
43+
import { SmartEntryComponent } from './components/smart-entry/smart-entry.component';
44+
import { TagResultsComponent } from './components/tag-results/tag-results.component';
45+
import { TagsResolver } from './resolvers/TagsResolver';
2646

2747
@NgModule({
2848
declarations: [
@@ -34,9 +54,36 @@ import { PrintProviderService } from './providers/print-provider.service';
3454
EditSubjectComponent,
3555
GeneratorComponent,
3656
QuestionsComponent,
37-
ViewQuestionComponent
57+
ViewQuestionComponent,
58+
AssTypesComponent,
59+
EditAssTypeComponent,
60+
ClassesComponent,
61+
PreviewStudentsComponent,
62+
AddResultsComponent,
63+
ViwResultsComponent,
64+
SmartEntryComponent,
65+
TagResultsComponent
66+
],
67+
providers: [
68+
HttpProvider,
69+
AssessTypeHttpProvider,
70+
HttpHandler,
71+
SubjectsResolver,
72+
SubjectResolver,
73+
TopicsResolver,
74+
PrintProviderService,
75+
AssTypesResolver,
76+
AssTypeResolver,
77+
ClassessHttpProvider,
78+
ClassesResolver,
79+
StudentsService,
80+
StudentsHttpProvider,
81+
ClassResolver,
82+
StudentsResolver,
83+
ResultsHttpProvider,
84+
ClassSubjectsResolver,
85+
TagsResolver
3886
],
39-
providers: [HttpProvider, HttpHandler, SubjectsResolver, SubjectResolver, TopicsResolver, PrintProviderService],
4087
exports: [RouterModule],
4188
imports: [
4289
CommonModule,
@@ -51,6 +98,14 @@ import { PrintProviderService } from './providers/print-provider.service';
5198
{ path: 'edit-subject/:id', component: EditSubjectComponent, resolve: { subject: SubjectResolver } },
5299
{ path: 'add-question/:id', component: QuestionsComponent, resolve: { subject: SubjectResolver } },
53100
{ path: 'generate/:id', component: GeneratorComponent, resolve: { subject: SubjectResolver, topics: TopicsResolver } },
101+
{ path: 'types', component: AssTypesComponent, resolve: { types: AssTypesResolver } },
102+
{ path: 'edit-type/:id', component: EditAssTypeComponent, resolve: { type: AssTypeResolver } },
103+
{ path: 'classes', component: ClassesComponent, resolve: { classes: ClassesResolver } },
104+
{ path: 'preview-students/:id', component: PreviewStudentsComponent, resolve: { "class": ClassResolver } },
105+
{ path: 'add-results/:id', component: AddResultsComponent, resolve: { "class": ClassResolver, 'students': StudentsResolver, 'types': AssTypesResolver, 'subjects': SubjectsResolver } },
106+
{ path: 'smart-entry/:id', component: SmartEntryComponent, resolve: { "class": ClassResolver, 'students': StudentsResolver, 'types': AssTypesResolver, 'subjects': SubjectsResolver } },
107+
{ path: 'view-results/:id', component: ViwResultsComponent, resolve: { "class": ClassResolver, 'subjects': ClassSubjectsResolver } },
108+
{ path: 'tag-results/:id', component: TagResultsComponent, resolve: { "class": ClassResolver, 'subjects': ClassSubjectsResolver, 'tags': TagsResolver, 'types': AssTypesResolver } },
54109
{ path: '**', redirectTo: 'home' }
55110
])
56111
]
Loading
Loading
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<div class="row">
2+
<div class="col-md-4">
3+
<article>
4+
<section class="">
5+
<h2 class="h2">Setting up</h2>
6+
<p>The database is first created when the application first launches and subsequently recreated if the database is missing. There is no need to do anything thereof</p>
7+
<p>
8+
Add the <a [routerLink]="['/subjects']">Subjects</a> and the <a [routerLink]="['/classes']">Classes</a> you teach
9+
</p>
10+
<p>Once the above steps are done, you are more than ready to explore the application in full</p>
11+
</section>
12+
<section>
13+
<h2 class="h2">Adding students</h2>
14+
<p>Upload the list of students with an excel file. Simple as that . However a pattern must be observed to create the understanding between you and the software</p>
15+
<ul class="list-group">
16+
<li class="list-group-item-heading">Uploading students data instructions</li>
17+
<li class="list-group-item">Have an excel sheets that contains the list of students</li>
18+
<li class="list-group-item-warning">There must be no header of any sort. They will be included as students. Do not provide a header</li>
19+
<li class="list-group-item-success">The system reads all cells for which it can read data in the cell from columns A and B. All other columns will be ignored</li>
20+
<li class="list-group-item">To make life easier for yourself and the system, follow the instructions given</li>
21+
</ul>
22+
</section>
23+
</article>
24+
</div>
25+
<div class="col-md-4">
26+
<article>
27+
<section>
28+
<h2>Managing the classes</h2>
29+
<p>When adding classes, you need to supply some parameter which will be used later by the application to help you do things easily</p>
30+
<dl class="dl-horizontal">
31+
<dt>Class Name</dt>
32+
<dd>The name of the class as know in your school or institution. The user interface will tell you on the valid values</dd>
33+
<dt>Prefix</dt>
34+
<dd>The prefix is all the characters that precede the actual number of the student. E.g. "MS/2019/045" where "MS/2019/" is the prefix for all students in that class and the 045 is the actual number of the student. You would therefore store the "MS/2019/" as the prefix for all students in that class.</dd>
35+
</dl>
36+
<p>
37+
The padding is the number of zeros that precede the actual number. While the developer does not personally find that behavior useful, it is a common practice. Depending on the estimated number of students, some institution pad the numbers of the students with zeros as in the example given above. The number of the student was given as 045; a padding of 1. This can be inferred that if the number ranged between 1 and 9, two zeros would have been padded to the left of the number. The user is expected to provide the padding that is used in the institution where he/she works. Default is 0, meaning no padding
38+
</p>
39+
</section>
40+
</article>
41+
</div>
42+
<div class="col-md-4">
43+
<article>
44+
<section>
45+
<h2>Adding results</h2>
46+
<p>From the classes page, you will have two options "Add results" button and "Smart Entry"</p>
47+
</section>
48+
<section>
49+
<h2>Add Results</h2>
50+
<p>This give the old familiar excel interface to add your results. The names and index number of the students in the class are generated and text boxes for the score added. The list is generated orderly for entry. Validation rules are enforced before saving the data is allowed.</p>
51+
<p>This is suitable for small number of students or when the index number of the students do not follow a particular patter</p>
52+
</section>
53+
<section>
54+
<h2>Smart Entry</h2>
55+
<p>Based on the number part, the index number of the student can be inferred and used to enter the score. The user simply provides the number part, say 45, and the program will infer that, it should pad two zeros and attach the prefix of the class. Should the number match a valid student, the results are added, else you will be prompted to correct the anomaly</p>
56+
<p>Smart entry is faster when processing large numbers of students where most of them have a predictable index number. In those occasions where some of the students do not have the class pattern, the full index number should be provided and there would be no smart inference</p>
57+
</section>
58+
</article>
59+
</div>
60+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/// <reference path="../../../../node_modules/@types/jasmine/index.d.ts" />
2+
import { TestBed, async, ComponentFixture, ComponentFixtureAutoDetect } from '@angular/core/testing';
3+
import { BrowserModule, By } from "@angular/platform-browser";
4+
import { AboutComponent } from './about.component';
5+
6+
let component: AboutComponent;
7+
let fixture: ComponentFixture<AboutComponent>;
8+
9+
describe('about component', () => {
10+
beforeEach(async(() => {
11+
TestBed.configureTestingModule({
12+
declarations: [ AboutComponent ],
13+
imports: [ BrowserModule ],
14+
providers: [
15+
{ provide: ComponentFixtureAutoDetect, useValue: true }
16+
]
17+
});
18+
fixture = TestBed.createComponent(AboutComponent);
19+
component = fixture.componentInstance;
20+
}));
21+
22+
it('should do something', async(() => {
23+
expect(true).toEqual(true);
24+
}));
25+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { Component } from '@angular/core';
2+
3+
@Component({
4+
selector: 'bs-about',
5+
templateUrl: './about.component.html',
6+
styleUrls: ['./about.component.css']
7+
})
8+
/** about component*/
9+
export class AboutComponent {
10+
/** about ctor */
11+
constructor() {
12+
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<title>Add results</title>
2+
<h1>Add student results</h1>
3+
<dl class="dl-horizontal">
4+
<dt>Class</dt>
5+
<dd>{{_class.className}}</dd>
6+
<dt>Prefix</dt>
7+
<dd>{{_class.indexPrefix}}</dd>
8+
</dl>
9+
<form id="form" [hidden]="!status" name="form" [formGroup]="form" class="form-horizontal">
10+
<fieldset>
11+
<legend>Select the initial data</legend>
12+
<div class="form-group">
13+
<label class="col-md-2 control-label" aria-label="" for="subjectsID">Subject</label>
14+
<div class="col-md-6" aria-labelledby="subjectsID" [ngClass]="form.controls.subjectsID?.errors ? 'has-error' : 'has-success'">
15+
<select class="form-control"
16+
id="subjectsID"
17+
title="select the subject for which you are recording this score"
18+
formControlName="subjectsID"
19+
placeholder="subjectsID">
20+
<option [ngValue]="s.subjectsID" *ngFor="let s of subjects">{{s.subject}} - Code:{{s.subjectCode}}</option>
21+
</select>
22+
</div>
23+
<span [ngClass]="form.controls.subjectsID.errors?.maxlength ? 'text-danger' : ''" *ngIf="form.controls.subjectsID.errors?.maxlength">The maximum length is {{form.controls.subjectsID.errors.max.max}} characters: Current is {{form.controls.subjectsID.errors.max.max}}</span>
24+
<span [ngClass]="form.controls.subjectsID.errors?.required ? 'text-danger' : ''" *ngIf="form.controls.subjectsID.errors?.required">Enter subjectsID</span>
25+
<span [ngClass]="form.controls.subjectsID.errors?.minlength ? 'text-danger' : ''" *ngIf="form.controls.subjectsID.errors?.minlength">The minimum length is {{form.controls.subjectsID.errors.min.min}} characters: Current is {{form.controls.subjectsID.errors.min.min}}</span>
26+
</div>
27+
<div class="form-group">
28+
<label class="col-md-2 control-label" aria-label="" for="tag">Tag</label>
29+
<div class="col-md-6" aria-labelledby="tag" [ngClass]="form.controls.tag?.errors ? 'has-error' : 'has-success'">
30+
<input type="text"
31+
class="form-control"
32+
id="tag"
33+
title="Add a tag for this assessment. This tags will be used to recollect this exams from the list. Since you can add more than one quiz, the tag will be used to find this session"
34+
formControlName="tag"
35+
placeholder="tag for the examination">
36+
</div>
37+
<span [ngClass]="form.controls.tag.errors?.maxlength ? 'text-danger' : ''" *ngIf="form.controls.tag.errors?.maxlength">The maximum length is {{form.controls.tag.errors.maxlength.requiredLength}} characters: Current is {{form.controls.tag.errors.maxlength.actualLength}}</span>
38+
<span [ngClass]="form.controls.tag.errors?.required ? 'text-danger' : ''" *ngIf="form.controls.tag.errors?.required">Enter tag</span>
39+
<span [ngClass]="form.controls.tag.errors?.minlength ? 'text-danger' : ''" *ngIf="form.controls.tag.errors?.minlength">The minimum length is {{form.controls.tag.errors.minlength.requiredLength}} characters: Current is {{form.controls.tag.errors.minlength.actualLength}}</span>
40+
</div>
41+
<div class="form-group">
42+
<label class="col-md-2 control-label" aria-label="" for="assessmentTypesID">Exam Type</label>
43+
<div class="col-md-6" aria-labelledby="assessmentTypesID" [ngClass]="form.controls.assessmentTypesID?.errors ? 'has-error' : 'has-success'">
44+
<select class="form-control"
45+
id="assessmentTypesID"
46+
title="select the exams type for which you are recording this score"
47+
formControlName="assessmentTypesID"
48+
placeholder="assessmentTypesID">
49+
<option [ngValue]="s.assessmentTypesID" *ngFor="let s of types">{{s.assessmentType}}</option>
50+
</select>
51+
</div>
52+
<span [ngClass]="form.controls.assessmentTypesID.errors?.maxlength ? 'text-danger' : ''" *ngIf="form.controls.assessmentTypesID.errors?.maxlength">The maximum length is {{form.controls.assessmentTypesID.errors.max.max}} characters: Current is {{form.controls.assessmentTypesID.errors.max.max}}</span>
53+
<span [ngClass]="form.controls.assessmentTypesID.errors?.required ? 'text-danger' : ''" *ngIf="form.controls.assessmentTypesID.errors?.required">Select assessment type</span>
54+
<span [ngClass]="form.controls.assessmentTypesID.errors?.minlength ? 'text-danger' : ''" *ngIf="form.controls.assessmentTypesID.errors?.minlength">The minimum length is {{form.controls.assessmentTypesID.errors.min.min}} characters: Current is {{form.controls.assessmentTypesID.errors.min.min}}</span>
55+
</div>
56+
<div class="form-group">
57+
<label class="col-md-2 control-label" aria-label="" for="max">Max Score</label>
58+
<div class="col-md-6" aria-labelledby="max" [ngClass]="form.controls.max?.errors ? 'has-error' : 'has-success'">
59+
<input type="number" class="form-control"
60+
id="max"
61+
title="maximum score for which you are recording this score"
62+
formControlName="max"
63+
placeholder="max score" />
64+
</div>
65+
<span [ngClass]="form.controls.max.errors?.max ? 'text-danger' : ''" *ngIf="form.controls.max.errors?.max">The maximum {{form.controls.max.errors.max.max}}</span>
66+
<span [ngClass]="form.controls.max.errors?.required ? 'text-danger' : ''" *ngIf="form.controls.max.errors?.required">Enter maximum score</span>
67+
<span [ngClass]="form.controls.max.errors?.min ? 'text-danger' : ''" *ngIf="form.controls.max.errors?.min">The minimum length is {{form.controls.max.errors.min.min}} characters: Current is {{form.controls.max.errors.min.min}}</span>
68+
</div>
69+
</fieldset>
70+
</form>
71+
<div class="col-md-offset-2"><button class="btn" (click)="this.status=!this.status" [disabled]="form.invalid" [ngClass]="status ? 'btn-primary' : 'btn-secondary'">{{status ? 'Continue' : 'Back'}}</button></div>
72+
73+
<div class="row" [hidden]="status">
74+
<div class="col-md-2">ID</div>
75+
<div class="col-md-2">Index Number</div>
76+
<div class="col-md-5">Name</div>
77+
<div class="col-md-3">Score</div>
78+
</div>
79+
<form [hidden]="status" *ngFor="let f of res_form;let ix=index" [formGroup]="f" class="row table-striped form-horizontal">
80+
<div class="col-md-2">
81+
<input type="number" [attr.disabled]="true" formControlName="studentsID" class="form-control" />
82+
</div>
83+
<div class="col-md-2">
84+
<input type="text" [attr.disabled]="true" class="form-control" formControlName="indexNumber" />
85+
</div>
86+
<div class="col-md-5">
87+
<input type="text" [attr.disabled]="true" class="form-control" formControlName="name" />
88+
</div>
89+
<div class="col-md-3" aria-labelledby="score" [ngClass]="f.controls.score?.errors ? 'has-error' : 'has-success'">
90+
<input type="number" class="form-control"
91+
id="score"
92+
title="Enter the student score for the exam"
93+
formControlName="score"
94+
placeholder="score for {{students[ix].name}}" />
95+
<span [ngClass]="f.controls.score.touched && f.controls.score.errors?.max ? 'text-danger' : ''" *ngIf="f.controls.score.touched && f.controls.score.errors?.max">The maximum {{f.controls.score.errors.max.max}}</span>
96+
<span [ngClass]="f.controls.score.touched && f.controls.score.errors?.required ? 'text-danger' : ''" *ngIf="f.controls.score.touched && f.controls.score.errors?.required">Enter score</span>
97+
<span [ngClass]="f.controls.score.touched && f.controls.score.errors?.minlength ? 'text-danger' : ''" *ngIf="f.controls.score.touched && f.controls.score.errors?.min">The minimum is {{f.controls.score.errors.min.min}}</span>
98+
</div>
99+
<br />
100+
<br />
101+
<br />
102+
</form>
103+
<div class="btn-group" [hidden]="status">
104+
<button title="Save button. If the actions are successful after clicking this button, you will be routed to the class page" aria-label="Save the results button" (click)="save(form,res_form)" class="btn" [ngClass]="form_valid() ? 'btn-success' : 'btn-danger'" [disabled]="!form_valid()"><span class="glyphicon glyphicon-floppy-save"></span> Save</button>
105+
</div>

0 commit comments

Comments
 (0)