Skip to content
Snippets Groups Projects
Commit 422d3e11 authored by Scott Berg's avatar Scott Berg Committed by Scott Berg
Browse files

Add audit symbol component.

parent adc9efaa
No related branches found
No related tags found
No related merge requests found
<section id="audit-legend"> <section id="audit-legend">
<!-- COURSE SYMBOLS TABLE --> <table *ngFor="let legend of legends" mat-table [dataSource]="legend.symbols">
<table mat-table [dataSource]="auditCourseSymbols"> <caption>{{legend.title}}</caption>
<caption>Course Symbols</caption>
<tr mat-header-row *matHeaderRowDef="auditCourseColumns"></tr>
<tr mat-row *matRowDef="let row; columns: auditCourseColumns;"></tr>
<ng-container matColumnDef="symbol">
<th mat-header-cell *matHeaderCellDef scope="col">Symbol</th>
<td mat-cell *matCellDef="let legend">{{ legend.symbol }}</td>
</ng-container>
<ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef scope="col">Description</th>
<td mat-cell *matCellDef="let legend">{{ legend.description }}</td>
</ng-container>
</table>
<!-- GRADE SYMBOLS TABLE -->
<table mat-table [dataSource]="auditGradeSymbols">
<caption>Grade Symbols</caption>
<tr mat-header-row *matHeaderRowDef="auditCourseColumns"></tr>
<tr mat-row *matRowDef="let row; columns: auditCourseColumns;"></tr>
<ng-container matColumnDef="symbol">
<th mat-header-cell *matHeaderCellDef scope="col">Symbol</th>
<td mat-cell *matCellDef="let legend">{{ legend.symbol }}</td>
</ng-container>
<ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef scope="col">Description</th>
<td mat-cell *matCellDef="let legend">{{ legend.description }}</td>
</ng-container>
</table>
<!-- REQUIREMENT INFO TABLE -->
<table mat-table [dataSource]="auditReqInformation">
<caption>Requirement / Sub-requirement Information</caption>
<tr mat-header-row *matHeaderRowDef="auditCourseColumns"></tr>
<tr mat-row *matRowDef="let row; columns: auditCourseColumns;"></tr>
<ng-container matColumnDef="symbol">
<th mat-header-cell *matHeaderCellDef scope="col">Symbol</th>
<td mat-cell *matCellDef="let legend">{{ legend.symbol }}</td>
</ng-container>
<ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef scope="col">Description</th>
<td mat-cell *matCellDef="let legend">{{ legend.description }}</td>
</ng-container>
</table>
<!-- Audit Exception SYMBOLS TABLE -->
<table mat-table [dataSource]="auditExceptionSymbols">
<caption>Exception Symbols</caption>
<tr mat-header-row *matHeaderRowDef="auditCourseColumns"></tr> <tr mat-header-row *matHeaderRowDef="auditCourseColumns"></tr>
<tr mat-row *matRowDef="let row; columns: auditCourseColumns;"></tr> <tr mat-row *matRowDef="let row; columns: auditCourseColumns;"></tr>
<ng-container matColumnDef="symbol"> <ng-container matColumnDef="symbol">
<th mat-header-cell *matHeaderCellDef scope="col">Symbol</th> <th mat-header-cell *matHeaderCellDef scope="col">Symbol</th>
<td mat-cell *matCellDef="let legend">{{ legend.symbol }}</td> <td mat-cell *matCellDef="let symbol">
<cse-audit-symbol [symbol]="symbol" [disableTooltip]="true" class="{{symbol.slug}}"></cse-audit-symbol>
</td>
</ng-container> </ng-container>
<ng-container matColumnDef="description"> <ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef scope="col">Description</th> <th mat-header-cell *matHeaderCellDef scope="col">Description</th>
<td mat-cell *matCellDef="let legend">{{ legend.description }}</td> <td mat-cell *matCellDef="let symbol">{{ symbol.tooltip }}</td>
</ng-container> </ng-container>
</table> </table>
</section> </section>
\ No newline at end of file
...@@ -4,3 +4,11 @@ ...@@ -4,3 +4,11 @@
margin-bottom: 2em; margin-bottom: 2em;
} }
} }
.complete-sub {
color: #2e7d32;
}
.not-complete-sub {
color: #c5050c;
}
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { AuditSymbol } from '../models/audit-symbols';
@Component({ @Component({
selector: 'cse-audit-legend', selector: 'cse-audit-legend',
...@@ -7,88 +8,69 @@ import { Component } from '@angular/core'; ...@@ -7,88 +8,69 @@ import { Component } from '@angular/core';
}) })
export class AuditLegendComponent { export class AuditLegendComponent {
public auditCourseColumns: string[] = ['symbol', 'description']; public auditCourseColumns: string[] = ['symbol', 'description'];
public auditCourseSymbols: { symbol: string; description: string }[] = [ public legends: { title: string, symbols: AuditSymbol[] }[] = [
{ symbol: '>D', description: 'Duplicate course - retains GPA effect' },
{ symbol: '>R', description: 'Repeatable course' },
{ symbol: '>S', description: 'Credit split between requirements' },
{ {
symbol: '>X', title: 'Course Symbols',
description: 'Repeated course - no course credit or GPA effect', symbols: [
}, { type: 'text', text: '>D', tooltip: 'Duplicate course - retains GPA effect' },
{ symbol: '(R)', description: 'Required course' }, { type: 'text', text: '>R', tooltip: 'Repeatable course' },
{ symbol: '(X)', description: 'Original course value' }, { type: 'text', text: '>S', tooltip: 'Credit split between requirements' },
]; { type: 'text', text: '>R', tooltip: 'Repeatable course' },
{ type: 'text', text: '(R)', tooltip: 'Required course' },
public auditGradeSymbols: { symbol: string; description: string }[] = [ { type: 'text', text: '(X)', tooltip: 'Original course value' },
{ symbol: 'EIP', description: 'Extended incomplete' }, ]
{ symbol: 'CR', description: 'Credit (credit/no credit courses)' },
{ symbol: 'HS', description: 'High school unit' },
{ symbol: 'IN', description: 'Incomplete (credit/no credit courses)' },
{ symbol: 'INP', description: 'In-progress course (current term)' },
{ symbol: 'IP', description: 'Incomplete' },
{ symbol: 'N', description: 'No credit (credit/no credit courses)' },
{ symbol: 'NR', description: 'Not reported' },
{ symbol: 'NW', description: 'No work' },
{ symbol: 'PL', description: 'Planned course' },
{ symbol: 'PP', description: 'Progress' },
{ symbol: 'PS', description: 'Mock/pseudo course' },
{ symbol: 'Q', description: 'Question on credits or honors' },
{ symbol: 'S', description: 'Satisfactory (pass/fail and audit courses)' },
{ symbol: 'T', description: 'Transfer/test/advanced standing course' },
{ symbol: 'U', description: 'Unsatisfactory (pass/fail courses)' },
];
public auditReqInformation: { symbol: string; description: string }[] = [
{ symbol: 'OK', description: 'Requirement complete' },
{ symbol: 'NO', description: 'Requirement not complete' },
{
symbol: 'IP',
description: 'Requirement uses in-progress credit/courses',
},
{
symbol: 'IN-P',
description: 'Sub-requirement uses in progress credit/courses',
}, },
{ {
symbol: 'PL', title: 'Grade Symbols',
description: 'Requirement/sub-requirement uses planned course', symbols: [
{ type: 'text', text: 'EIP', tooltip: 'Extended incomplete' },
{ type: 'text', text: 'CR', tooltip: 'Credit (credit/no credit courses)' },
{ type: 'text', text: 'HS', tooltip: 'High school unit' },
{ type: 'text', text: 'IN', tooltip: 'Incomplete (credit/no credit courses)' },
{ type: 'text', text: 'INP', tooltip: 'In-progress course (current term)' },
{ type: 'text', text: 'IP', tooltip: 'Incomplete' },
{ type: 'text', text: 'N', tooltip: 'No credit (credit/no credit courses)' },
{ type: 'text', text: 'NR', tooltip: 'Not reported' },
{ type: 'text', text: 'NW', tooltip: 'No work' },
{ type: 'text', text: 'PL', tooltip: 'Planned course' },
{ type: 'text', text: 'PP', tooltip: 'Progress' },
{ type: 'text', text: 'PS', tooltip: 'Mock/pseudo course' },
{ type: 'text', text: 'Q', tooltip: 'Question on credits or honors' },
{ type: 'text', text: 'S', tooltip: 'Satisfactory (pass/fail and audit courses)' },
{ type: 'text', text: 'T', tooltip: 'Transfer/test/advanced standing course' },
{ type: 'text', text: 'U', tooltip: 'Unsatisfactory (pass/fail courses)' },
]
}, },
{ symbol: 'R', description: 'Required sub-requirement (mandatory)' },
{ {
symbol: '<>', title: 'Requirement / Sub-requirement Information',
description: "Optional/other requirement in OR'd set complete", symbols: [
{ type: 'text', text: 'OK', tooltip: 'Requirement complete' },
{ type: 'text', text: 'NO', tooltip: 'Requirement not complete' },
{ type: 'text', text: 'IP', tooltip: 'Requirement uses in-progress credit/courses' },
{ type: 'text', text: 'IN-P', tooltip: 'Sub-requirement uses in progress credit/courses' },
{ type: 'text', text: 'PL', tooltip: 'Requirement/sub-requirement uses planned course' },
{ type: 'text', text: 'R', tooltip: 'Required sub-requirement (mandatory)' },
{ type: 'text', text: '<>', tooltip: 'Optional/other requirement in OR\'d set complete' },
{ type: 'icon', text: '+', icon: 'check', tooltip: 'Sub-requirement complete', slug: 'complete-sub' },
{ type: 'icon', text: '-', icon: 'close', tooltip: 'Sub-requirement not complete', slug: 'not-complete-sub' },
{ type: 'text', text: '*', tooltip: 'Optional sub-requirement, courses assigned' },
{ type: 'text', text: ' ', tooltip: 'Optional sub-requirement, no courses assigned' },
]
}, },
{ symbol: '+', description: 'Sub-requirement complete' },
{ symbol: '-', description: 'Sub-requirement not complete' },
{ symbol: '*', description: 'Optional sub-requirement, courses assigned' },
{ {
symbol: ' ', title: 'Exception Symbols',
description: 'Optional sub-requirement, no courses assigned', symbols: [
}, { type: 'text', text: 'AC', tooltip: 'Course approved for requirement/sub-requirement', },
]; { type: 'text', text: 'IC', tooltip: 'Course inserted into requirement/sub-requirement', },
{ type: 'text', text: 'EC', tooltip: 'Course exchanged for specified course' },
public auditExceptionSymbols: { symbol: string; description: string }[] = [ { type: 'text', text: 'FC', tooltip: 'Course forced into requirement/sub-requirement', },
{ { type: 'text', text: 'CM', tooltip: 'Course modified' },
symbol: 'AC', { type: 'text', text: 'CY', tooltip: 'Catalog year modified' },
description: 'Course approved for requirement/sub-requirement', { type: 'text', text: 'DC', tooltip: 'Course deleted from requirement/sub-requirement', },
}, { type: 'text', text: 'RM', tooltip: 'Requirement modified' },
{ { type: 'text', text: 'WC', tooltip: 'Waive course' },
symbol: 'IC', { type: 'text', text: 'WP', tooltip: 'Waive mock/pseudo course' },
description: 'Course inserted into requirement/sub-requirement', ]
}, }
{ symbol: 'EC', description: 'Course exchanged for specified course' },
{
symbol: 'FC',
description: 'Course forced into requirement/sub-requirement',
},
{ symbol: 'CM', description: 'Course modified' },
{ symbol: 'CY', description: 'Catalog year modified' },
{
symbol: 'DC',
description: 'Course deleted from requirement/sub-requirement',
},
{ symbol: 'RM', description: 'Requirement modified' },
{ symbol: 'WC', description: 'Waive course' },
{ symbol: 'WP', description: 'Waive mock/pseudo course' },
]; ];
} }
<div
class="audit-symbol-wrapper"
[matTooltip]="symbol.tooltip"
matTooltipPosition="above"
[matTooltipDisabled]="!symbol.tooltip || disableTooltip">
<span *ngIf="symbol.type === 'text'">{{symbol.text}}</span>
<mat-icon *ngIf="symbol.type === 'icon'" class="material-icons audit-symbol audit-symbol-{{asIcon(symbol).icon}}">{{asIcon(symbol).icon}}</mat-icon>
</div>
\ No newline at end of file
.audit-symbol-wrapper {
display: inline-block;
}
span {
position: relative;
display: block;
padding-right: 5px;
color: inherit;
}
mat-icon {
margin-top: 4px;
color: inherit;
}
import { Component, Input, OnInit, ViewChild } from '@angular/core';
import { AuditSymbol, AuditIconSymbol } from '../models/audit-symbols';
@Component({
selector: 'cse-audit-symbol',
templateUrl: './audit-symbol.component.html',
styleUrls: ['./audit-symbol.component.scss']
})
export class AuditSymbolComponent {
@Input() symbol: AuditSymbol;
@Input() disableTooltip?: boolean;
// Used to typecast because ng-switch is dumb
asIcon(symbol: AuditSymbol): AuditIconSymbol {
return symbol as AuditIconSymbol;
}
}
...@@ -194,14 +194,11 @@ ...@@ -194,14 +194,11 @@
<div class="subrequirement-status-wrapper"> <div class="subrequirement-status-wrapper">
<p *ngIf="reqBody.contentType === 'okSubrequirementTLine' || reqBody.contentType === 'noSubrequirementTLine'"> <p *ngIf="reqBody.contentType === 'okSubrequirementTLine' || reqBody.contentType === 'noSubrequirementTLine'">
<ng-container *ngFor="let symbol of asLineBody(reqBody).lines | requirementSymbols"> <cse-audit-symbol
<ng-container [ngSwitch]="symbol.type"> *ngFor="let symbol of asLineBody(reqBody).lines | requirementSymbols"
<span *ngSwitchCase="'text'" [matTooltip]="symbol.tooltip" matTooltipPosition="above">{{symbol.text}}</span> class="{{symbol.slug}}"
<span *ngSwitchCase="'icon'" class="{{symbol.icon}}"> [symbol]="symbol"
<mat-icon [matTooltip]="symbol.tooltip" matTooltipPosition="above">{{symbol.icon}}</mat-icon> ></cse-audit-symbol>
</span>
</ng-container>
</ng-container>
</p> </p>
</div> </div>
...@@ -241,9 +238,10 @@ ...@@ -241,9 +238,10 @@
<ng-container matColumnDef="note"> <ng-container matColumnDef="note">
<th mat-header-cell *matHeaderCellDef scope="col">Course Note</th> <th mat-header-cell *matHeaderCellDef scope="col">Course Note</th>
<td mat-cell *matCellDef="let course"> <td mat-cell *matCellDef="let course">
<span *ngFor="let note of course.courseNote | courseNote" [matTooltip]="note.tooltip" matTooltipPosition="above"> <cse-audit-symbol
{{note.text}} *ngFor="let symbol of course.courseNote | courseNote"
</span> [symbol]="symbol"
></cse-audit-symbol>
</td> </td>
</ng-container> </ng-container>
</table> </table>
......
...@@ -202,19 +202,19 @@ $black: #000000; ...@@ -202,19 +202,19 @@ $black: #000000;
position: relative; position: relative;
display: block; display: block;
padding-right: 5px; padding-right: 5px;
&.close {
color: $red;
}
&.check {
color: $green;
}
} }
mat-icon { mat-icon {
margin-top: 3px; margin-top: 3px;
} }
.complete-sub {
color: $green;
}
.not-complete-sub {
color: $red;
}
} }
.subrequirement-content-wrapper { .subrequirement-content-wrapper {
......
...@@ -22,6 +22,7 @@ import { NewDegreeAuditDialogComponent } from './new-degree-audit-dialog/new-deg ...@@ -22,6 +22,7 @@ import { NewDegreeAuditDialogComponent } from './new-degree-audit-dialog/new-deg
import { NewWhatIfAuditDialogComponent } from './new-what-if-audit-dialog/new-what-if-audit-dialog.component'; import { NewWhatIfAuditDialogComponent } from './new-what-if-audit-dialog/new-what-if-audit-dialog.component';
import { AuditViewComponent } from './dars-audit-view/dars-audit-view.component'; import { AuditViewComponent } from './dars-audit-view/dars-audit-view.component';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { AuditSymbolComponent } from './audit-symbol/audit-symbol.component';
@NgModule({ @NgModule({
imports: [ imports: [
...@@ -48,6 +49,7 @@ import { RouterModule } from '@angular/router'; ...@@ -48,6 +49,7 @@ import { RouterModule } from '@angular/router';
AuditLegendComponent, AuditLegendComponent,
DarsMetadataTableComponent, DarsMetadataTableComponent,
MetadataMobileViewComponent, MetadataMobileViewComponent,
AuditSymbolComponent,
], ],
entryComponents: [ entryComponents: [
NewDegreeAuditDialogComponent, NewDegreeAuditDialogComponent,
......
export type AuditSymbol = AuditIconSymbol | AuditTextSymbol; export type AuditSymbol = AuditIconSymbol | AuditTextSymbol;
interface AuditIconSymbol { /**
type: 'icon'; * type: If the symbol should be plain text or a mat-icon.
* text: The original text of the symbol, will be used for find / replaces.
* icon: (type "icon" only) the text of the mat-icon.
* tooltip: The text to be displayed as the tooltip.
* slug: Text based identifier for the symbol. Used for createing class names.
*/
export interface AuditTextSymbol {
type: 'text' | 'icon';
text: string; text: string;
tooltip: string; tooltip?: string;
icon: string; slug?: string;
} }
interface AuditTextSymbol { export interface AuditIconSymbol extends AuditTextSymbol {
type: 'text'; type: 'icon';
text: string; icon: string;
tooltip: string;
} }
...@@ -7,14 +7,14 @@ export class RequirementSymbolsPipe implements PipeTransform { ...@@ -7,14 +7,14 @@ export class RequirementSymbolsPipe implements PipeTransform {
const singleLine = lines.join(' ').trim(); const singleLine = lines.join(' ').trim();
const matches = singleLine.match(/^((IP)|(IN-P)|(PL)|(R)|(<>)|\+|\-|\*)+/g); const matches = singleLine.match(/^((IP)|(IN-P)|(PL)|(R)|(<>)|\+|\-|\*)+/g);
const symbols: AuditSymbol[] = [ const symbols: AuditSymbol[] = [
{ type: 'text', text: 'IP', tooltip: 'Requirement uses in-progress credit/courses' }, { type: 'text', text: 'IP', tooltip: 'Requirement uses in-progress credit/courses', slug: 'in-progress' },
{ type: 'text', text: 'IN-P', tooltip: 'Sub-requirement uses in progress credit/courses' }, { type: 'text', text: 'IN-P', tooltip: 'Sub-requirement uses in progress credit/courses', slug: 'in-progress-sub' },
{ type: 'text', text: 'PL', tooltip: 'Requirement/sub-requirement uses planned course' }, { type: 'text', text: 'PL', tooltip: 'Requirement/sub-requirement uses planned course', slug: 'planned' },
{ type: 'text', text: 'R', tooltip: 'Required sub-requirement (mandatory)' }, { type: 'text', text: 'R', tooltip: 'Required sub-requirement (mandatory)', slug: 'required' },
{ type: 'text', text: '<>', tooltip: 'Optional/other requirement in OR\'d set complete' }, { type: 'text', text: '<>', tooltip: 'Optional/other requirement in OR\'d set complete', slug: 'optional' },
{ type: 'text', text: '*', tooltip: 'Optional sub-requirement, courses assigned' }, { type: 'text', text: '*', tooltip: 'Optional sub-requirement, courses assigned', slug: 'optional-sub' },
{ type: 'icon', text: '+', icon: 'check', tooltip: 'Sub-requirement complete' }, { type: 'icon', text: '+', icon: 'check', tooltip: 'Sub-requirement complete', slug: 'complete-sub' },
{ type: 'icon', text: '-', icon: 'close', tooltip: 'Sub-requirement not complete' } { type: 'icon', text: '-', icon: 'close', tooltip: 'Sub-requirement not complete', slug: 'not-complete-sub' }
]; ];
if (matches && matches.length > 0) { if (matches && matches.length > 0) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment