Commit 2af96b1f authored by Christopher Fullarton's avatar Christopher Fullarton

Reworks the style of the progress bars

parent 63879d82
......@@ -10,34 +10,34 @@ export const availableQuestionTypes: Array<IAvailableQuestionType> = [
{
id: QuestionType.MultipleChoiceQuestion,
translationName: 'component.questions.multiple_choice_question',
descriptionType: 'component.question_type.description.MultipleChoiceQuestion',
descriptionType: 'view.question_type.description.MultipleChoiceQuestion',
}, {
id: QuestionType.SingleChoiceQuestion,
translationName: 'component.questions.single_choice_question',
descriptionType: 'component.question_type.description.SingleChoiceQuestion',
descriptionType: 'view.question_type.description.SingleChoiceQuestion',
}, {
id: QuestionType.ABCDSingleChoiceQuestion,
translationName: 'component.questions.single_choice_question_abcd',
descriptionType: 'component.question_type.description.AbcdSingleChoiceQuestion',
descriptionType: 'view.question_type.description.AbcdSingleChoiceQuestion',
}, {
id: QuestionType.YesNoSingleChoiceQuestion,
translationName: 'component.questions.single_choice_question_yes_no',
descriptionType: 'component.question_type.description.YesNoSingleChoiceQuestion',
descriptionType: 'view.question_type.description.YesNoSingleChoiceQuestion',
}, {
id: QuestionType.TrueFalseSingleChoiceQuestion,
translationName: 'component.questions.single_choice_question_true_false',
descriptionType: 'component.question_type.description.TrueFalseSingleChoiceQuestion',
descriptionType: 'view.question_type.description.TrueFalseSingleChoiceQuestion',
}, {
id: QuestionType.RangedQuestion,
translationName: 'component.questions.ranged_question',
descriptionType: 'component.question_type.description.RangedQuestion',
descriptionType: 'view.question_type.description.RangedQuestion',
}, {
id: QuestionType.FreeTextQuestion,
translationName: 'component.questions.free_text_question',
descriptionType: 'component.question_type.description.FreeTextQuestion',
descriptionType: 'view.question_type.description.FreeTextQuestion',
}, {
id: QuestionType.SurveyQuestion,
translationName: 'component.questions.survey_question',
descriptionType: 'component.question_type.description.SurveyQuestion',
descriptionType: 'view.question_type.description.SurveyQuestion',
},
];
import { SecurityContext } from '@angular/core';
import { DomSanitizer, SafeStyle } from '@angular/platform-browser';
export abstract class AbstractProgressBar {
public absolute: number;
public label: string;
public normalizedAnswerIndex: string;
public progressbarCssClass: string;
private _percent: number;
get percent(): number {
return this._percent;
}
set percent(value: number) {
this._percent = value;
}
private _base: number;
get base(): number {
return this._base;
}
set base(value: number) {
this._base = value;
}
protected constructor(private sanitizer: DomSanitizer) {}
public sanitizeStyle(value: string | number): SafeStyle {
value = value.toString().replace(/\s/g, '');
return this.sanitizer.sanitize(SecurityContext.STYLE, `${value}`);
}
public sanitizeHTML(value: string): string {
return this.sanitizer.sanitize(SecurityContext.HTML, `${value}`);
}
protected initData(value: any): void {
this.percent = value.percent;
this.base = value.base;
this.absolute = value.absolute;
this.label = value.label;
this.normalizedAnswerIndex = String.fromCharCode(65 + value.answerIndex);
this.progressbarCssClass = typeof value.isCorrect === 'undefined' ? 'default' : value.isCorrect === -1 ? 'danger' : value.isCorrect === 0
? 'warning' : 'success';
}
}
<hr/>
<ng-container *ngIf="!isSurveyQuestion()">
<div *ngIf="correct"
class="progress my-2 position-relative"
style="height: 2rem;">
<div [attr.aria-valuenow]="correct.percent"
[style.width]="sanitizeStyle(correct.percent)"
aria-valuemax="100"
aria-valuemin="0"
class="progress-bar overflow-hidden bg-success"
role="progressbar"></div>
class="my-2">
<ng-container *ngIf="base">
<div class="d-flex align-self-center align-items-center position-absolute h-100"
style="left: 10px;"><span>{{'component.liveResults.correct_answer' | translate}}</span>
</div>
<div class="align-self-center position-absolute"
style="right: 10px;">{{correct.percent}}&nbsp;|&nbsp;{{correct.absolute}}&nbsp;/&nbsp;{{base}}
<div *ngIf="base"
class="d-flex justify-content-between">
<span class="text-truncate mx-2">{{'component.liveResults.correct_answer' | translate}}</span>
<span class="mr-2">{{correct.percent}}&nbsp;|&nbsp;{{correct.absolute}}&nbsp;/&nbsp;{{base}}</span>
</div>
<div class="progress">
<div *ngIf="base && correct.percent"
[attr.aria-valuenow]="correct.percent"
[style.width]="sanitizeStyle(correct.percent)"
aria-valuemax="100"
aria-valuemin="0"
class="progress-bar overflow-visible bg-success box-shadow-success"
role="progressbar">
</div>
</ng-container>
<div *ngIf="!base"
class="w-100 d-flex align-items-center justify-content-center">
<fa-icon [icon]="'spinner'"
[spin]="true"></fa-icon>
<div *ngIf="!base"
class="w-100 d-flex align-items-center justify-content-center">
<fa-icon [icon]="'spinner'"
[spin]="true"></fa-icon>
</div>
</div>
</div>
<div *ngIf="wrong"
class="progress my-2 position-relative"
style="height: 2rem;">
<div [attr.aria-valuenow]="wrong.percent"
[style.width]="sanitizeStyle(wrong.percent)"
aria-valuemax="100"
aria-valuemin="0"
class="progress-bar overflow-hidden bg-danger"
role="progressbar"></div>
class="my-2">
<ng-container *ngIf="base">
<div class="d-flex align-self-center align-items-center position-absolute h-100"
style="left: 10px;"><span>{{'component.liveResults.wrong_answer' | translate}}</span>
</div>
<div class="align-self-center position-absolute"
style="right: 10px;">{{wrong.percent}}&nbsp;|&nbsp;{{wrong.absolute}}&nbsp;/&nbsp;{{base}}
<div *ngIf="base"
class="d-flex justify-content-between">
<span class="text-truncate mx-2">{{'component.liveResults.wrong_answer' | translate}}</span>
<span class="mr-2">{{wrong.percent}}&nbsp;|&nbsp;{{wrong.absolute}}&nbsp;/&nbsp;{{base}}</span>
</div>
<div class="progress">
<div *ngIf="base && wrong.percent"
[attr.aria-valuenow]="wrong.percent"
[style.width]="sanitizeStyle(wrong.percent)"
aria-valuemax="100"
aria-valuemin="0"
class="progress-bar overflow-visible bg-danger box-shadow-danger"
role="progressbar">
</div>
</ng-container>
<div *ngIf="!base"
class="w-100 d-flex align-items-center justify-content-center">
<fa-icon [icon]="'spinner'"
[spin]="true"></fa-icon>
<div *ngIf="!base"
class="w-100 d-flex align-items-center justify-content-center">
<fa-icon [icon]="'spinner'"
[spin]="true"></fa-icon>
</div>
</div>
</div>
</ng-container>
<div *ngIf="isSurveyQuestion() && neutral"
class="progress my-2 position-relative"
style="height: 2rem;">
<div [attr.aria-valuenow]="neutral.percent"
[style.width]="sanitizeStyle(neutral.percent)"
aria-valuemax="100"
aria-valuemin="0"
class="progress-bar overflow-hidden"
role="progressbar"></div>
<ng-container *ngIf="base">
<div class="d-flex align-self-center align-items-center position-absolute h-100"
style="left: 10px;"><span>{{'component.liveResults.neutral_answer' | translate}}</span>
</div>
<div class="align-self-center position-absolute"
style="right: 10px;">{{neutral.percent}}&nbsp;|&nbsp;{{neutral.absolute}}&nbsp;/&nbsp;{{base}}
class="my-2">
<div *ngIf="base"
class="d-flex justify-content-between">
<span class="text-truncate mx-2">{{'component.liveResults.neutral_answer' | translate}}</span>
<span class="mr-2">{{neutral.percent}}&nbsp;|&nbsp;{{neutral.absolute}}&nbsp;/&nbsp;{{base}}</span>
</div>
<div class="progress">
<div *ngIf="base && neutral.percent"
[attr.aria-valuenow]="neutral.percent"
[style.width]="sanitizeStyle(neutral.percent)"
aria-valuemax="100"
aria-valuemin="0"
class="progress-bar overflow-visible bg-success box-shadow-success"
role="progressbar">
</div>
</ng-container>
<div *ngIf="!base"
class="w-100 d-flex align-items-center justify-content-center">
<fa-icon [icon]="'spinner'"
[spin]="true"></fa-icon>
<div *ngIf="!base"
class="w-100 d-flex align-items-center justify-content-center">
<fa-icon [icon]="'spinner'"
[spin]="true"></fa-icon>
</div>
</div>
</div>
import { ChangeDetectorRef, Component, Input, SecurityContext } from '@angular/core';
import { DomSanitizer, SafeStyle } from '@angular/platform-browser';
import { Component, Input } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { QuestionType } from '../../../../../lib/enums/QuestionType';
import { AbstractProgressBar } from '../AbstractProgressBar';
@Component({
selector: 'app-progress-bar-anonymous',
templateUrl: './progress-bar-anonymous.component.html',
styleUrls: ['./progress-bar-anonymous.component.scss'],
})
export class ProgressBarAnonymousComponent {
export class ProgressBarAnonymousComponent extends AbstractProgressBar {
public static TYPE = 'ProgressBarAnonymousComponent';
public correct: { absolute: number; percent: string } = {
absolute: 0,
percent: '',
......@@ -29,15 +32,10 @@ export class ProgressBarAnonymousComponent {
this.wrong = value.wrong;
this.base = value.base;
this.neutral = value.neutral;
this.cd.markForCheck();
}
constructor(private sanitizer: DomSanitizer, private cd: ChangeDetectorRef) {
}
public sanitizeStyle(value: string | number): SafeStyle {
value = value.toString().replace(/\s/g, '');
return this.sanitizer.sanitize(SecurityContext.STYLE, `${value}`);
constructor(sanitizer: DomSanitizer) {
super(sanitizer);
}
public isSurveyQuestion(): boolean {
......
<div class="progress my-2 position-relative"
style="height: 2rem;">
<div *ngIf="base && percent"
[attr.aria-valuenow]="percent"
[class]="('progress-bar overflow-hidden bg-' + progressbarCssClass)"
[style.width]="sanitizeStyle(percent)"
aria-valuemax="100"
aria-valuemin="0"
role="progressbar"></div>
<div class="my-2">
<ng-container *ngIf="base">
<div class="d-flex align-self-center align-items-center position-absolute h-100"
style="left: 10px;"><span [innerHTML]="sanitizeHTML(label)"></span>
</div>
<div class="align-self-center position-absolute"
style="right: 10px;">{{percent}}&nbsp;|&nbsp;{{absolute}}&nbsp;/&nbsp;{{base}}
<div *ngIf="base"
class="d-flex justify-content-between">
<span class="text-truncate mx-2"><span [innerHTML]="sanitizeHTML(label)"></span></span>
<span class="mr-2">{{percent}}&nbsp;|&nbsp;{{absolute}}&nbsp;/&nbsp;{{base}}</span>
</div>
<div class="progress">
<div *ngIf="base && percent"
[attr.aria-valuenow]="percent"
[class]="('progress-bar overflow-visible bg-' + progressbarCssClass + ' ' + ('box-shadow-' + progressbarCssClass))"
[style.width]="sanitizeStyle(percent)"
aria-valuemax="100"
aria-valuemin="0"
role="progressbar">
</div>
</ng-container>
<div *ngIf="!base"
class="w-100 d-flex align-items-center justify-content-center">
<fa-icon [icon]="'spinner'"
[spin]="true"></fa-icon>
<div *ngIf="!base"
class="w-100 d-flex align-items-center justify-content-center">
<fa-icon [icon]="'spinner'"
[spin]="true"></fa-icon>
</div>
</div>
</div>
import { ChangeDetectorRef, Component, Input, SecurityContext } from '@angular/core';
import { DomSanitizer, SafeStyle } from '@angular/platform-browser';
import { Component, Input } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { AbstractProgressBar } from '../AbstractProgressBar';
@Component({
selector: 'app-progress-bar-freetext',
templateUrl: './progress-bar-freetext.component.html',
styleUrls: ['./progress-bar-freetext.component.scss'],
})
export class ProgressBarFreetextComponent {
export class ProgressBarFreetextComponent extends AbstractProgressBar {
public static TYPE = 'ProgressBarFreetextComponent';
public absolute: number;
public label: string;
public progressbarCssClass: string;
@Input() set attendeeData(value: any) {
this.percent = value.percent;
this.base = value.base;
this.absolute = value.absolute;
this.label = value.label;
this.progressbarCssClass = typeof value.isCorrect === 'undefined' ? 'default' : value.isCorrect === -1 ? 'danger' : value.isCorrect === 0
? 'warning' : 'success';
this.cd.markForCheck();
this.initData(value);
}
private _percent: number;
get percent(): number {
return this._percent;
}
set percent(value: number) {
this._percent = value;
}
private _base: number;
get base(): number {
return this._base;
}
set base(value: number) {
this._base = value;
}
constructor(private sanitizer: DomSanitizer, private cd: ChangeDetectorRef) {
}
public sanitizeStyle(value: string | number): SafeStyle {
value = value.toString().replace(/\s/g, '');
return this.sanitizer.sanitize(SecurityContext.STYLE, `${value}`);
}
public sanitizeHTML(value: string): string {
return this.sanitizer.sanitize(SecurityContext.HTML, `${value}`);
constructor(sanitizer: DomSanitizer) {
super(sanitizer);
}
}
<div class="progress my-2 position-relative"
style="height: 2rem;">
<div *ngIf="base && percent"
[attr.aria-valuenow]="percent"
[class]="('progress-bar overflow-hidden bg-' + progressbarCssClass)"
[style.width]="sanitizeStyle(percent)"
aria-valuemax="100"
aria-valuemin="0"
role="progressbar"></div>
<div class="my-2">
<ng-container *ngIf="base">
<div class="d-flex align-self-center align-items-center position-absolute h-100"
style="left: 10px;">{{normalizedAnswerIndex}}:&nbsp;<span [innerHTML]="sanitizeHTML(label)"></span>
</div>
<div class="align-self-center position-absolute"
style="right: 10px;">{{percent}}&nbsp;|&nbsp;{{absolute}}&nbsp;/&nbsp;{{base}}
<div *ngIf="base"
class="d-flex justify-content-between">
<span class="text-truncate mx-2">{{normalizedAnswerIndex}}:&nbsp;<span [innerHTML]="sanitizeHTML(label)"></span></span>
<span class="mr-2">{{percent}}&nbsp;|&nbsp;{{absolute}}&nbsp;/&nbsp;{{base}}</span>
</div>
<div class="progress">
<div *ngIf="base && percent"
[attr.aria-valuenow]="percent"
[class]="('progress-bar overflow-visible bg-' + progressbarCssClass + ' ' + ('box-shadow-' + progressbarCssClass))"
[style.width]="sanitizeStyle(percent)"
aria-valuemax="100"
aria-valuemin="0"
role="progressbar">
</div>
</ng-container>
<div *ngIf="!base"
class="w-100 d-flex align-items-center justify-content-center">
<fa-icon [icon]="'spinner'"
[spin]="true"></fa-icon>
<div *ngIf="!base"
class="w-100 d-flex align-items-center justify-content-center">
<fa-icon [icon]="'spinner'"
[spin]="true"></fa-icon>
</div>
</div>
</div>
import { ChangeDetectorRef, Component, Input, SecurityContext } from '@angular/core';
import { DomSanitizer, SafeStyle } from '@angular/platform-browser';
import { Component, Input } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { AbstractProgressBar } from '../AbstractProgressBar';
@Component({
selector: 'app-progress-bar-multiple-choice',
templateUrl: './progress-bar-multiple-choice.component.html',
styleUrls: ['./progress-bar-multiple-choice.component.scss'],
})
export class ProgressBarMultipleChoiceComponent {
export class ProgressBarMultipleChoiceComponent extends AbstractProgressBar {
public static TYPE = 'ProgressBarMultipleChoiceComponent';
public absolute: number;
public label: string;
public normalizedAnswerIndex: string;
public progressbarCssClass: string;
@Input() set attendeeData(value: any) {
this.percent = value.percent;
this.base = value.base;
this.absolute = value.absolute;
this.label = value.label;
this.normalizedAnswerIndex = String.fromCharCode(65 + value.answerIndex);
this.progressbarCssClass = typeof value.isCorrect === 'undefined' ? 'default' : value.isCorrect === -1 ? 'danger' : value.isCorrect === 0
? 'warning' : 'success';
this.cd.markForCheck();
this.initData(value);
}
private _percent: number;
get percent(): number {
return this._percent;
}
set percent(value: number) {
this._percent = value;
}
private _base: number;
get base(): number {
return this._base;
}
set base(value: number) {
this._base = value;
}
constructor(private sanitizer: DomSanitizer, private cd: ChangeDetectorRef) {
}
public sanitizeStyle(value: string | number): SafeStyle {
value = value.toString().replace(/\s/g, '');
return this.sanitizer.sanitize(SecurityContext.STYLE, `${value}`);
}
public sanitizeHTML(value: string): string {
return this.sanitizer.sanitize(SecurityContext.HTML, `${value}`);
constructor(sanitizer: DomSanitizer) {
super(sanitizer);
}
}
<div class="progress my-2 position-relative"
style="height: 2rem;">
<div *ngIf="base && percent"
[attr.aria-valuenow]="percent"
[class]="('progress-bar overflow-hidden bg-' + progressbarCssClass)"
[style.width]="sanitizeStyle(percent)"
aria-valuemax="100"
aria-valuemin="0"
role="progressbar"></div>
<div class="my-2">
<ng-container *ngIf="base">
<div class="d-flex align-self-center align-items-center position-absolute h-100"
style="left: 10px;"><span [innerHTML]="sanitizeHTML(label)"></span>
</div>
<div class="align-self-center position-absolute"
style="right: 10px;">{{percent}}&nbsp;|&nbsp;{{absolute}}&nbsp;/&nbsp;{{base}}
<div *ngIf="base"
class="d-flex justify-content-between">
<span class="text-truncate mx-2"><span [innerHTML]="sanitizeHTML(label)"></span></span>
<span class="mr-2">{{percent}}&nbsp;|&nbsp;{{absolute}}&nbsp;/&nbsp;{{base}}</span>
</div>
<div class="progress">
<div *ngIf="base && percent"
[attr.aria-valuenow]="percent"
[class]="('progress-bar overflow-visible bg-' + progressbarCssClass + ' ' + ('box-shadow-' + progressbarCssClass))"
[style.width]="sanitizeStyle(percent)"
aria-valuemax="100"
aria-valuemin="0"
role="progressbar">
</div>
</ng-container>
<div *ngIf="!base"
class="w-100 d-flex align-items-center justify-content-center">
<fa-icon [icon]="'spinner'"
[spin]="true"></fa-icon>
<div *ngIf="!base"
class="w-100 d-flex align-items-center justify-content-center">
<fa-icon [icon]="'spinner'"
[spin]="true"></fa-icon>
</div>
</div>
</div>
import { ChangeDetectorRef, Component, Input, SecurityContext } from '@angular/core';
import { DomSanitizer, SafeStyle } from '@angular/platform-browser';
import { Component, Input } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { AbstractProgressBar } from '../AbstractProgressBar';
@Component({
selector: 'app-progress-bar-ranged',
templateUrl: './progress-bar-ranged.component.html',
styleUrls: ['./progress-bar-ranged.component.scss'],
})
export class ProgressBarRangedComponent {
export class ProgressBarRangedComponent extends AbstractProgressBar {
public static TYPE = 'ProgressBarRangedComponent';
public absolute: number;
public label: string;
public progressbarCssClass: string;
@Input() set attendeeData(value: any) {
this.percent = value.percent;
this.base = value.base;
this.absolute = value.absolute;
this.label = value.label;
this.progressbarCssClass = typeof value.isCorrect === 'undefined' ? 'default' : value.isCorrect === -1 ? 'danger' : value.isCorrect === 0
? 'warning' : 'success';
this.cd.markForCheck();
this.initData(value);
}
private _percent: number;
get percent(): number {
return this._percent;
}
set percent(value: number) {
this._percent = value;
}
private _base: number;
get base(): number {
return this._base;
}
set base(value: number) {
this._base = value;
}
constructor(private sanitizer: DomSanitizer, private cd: ChangeDetectorRef) {
}
public sanitizeStyle(value: string | number): SafeStyle {
value = value.toString().replace(/\s/g, '');
return this.sanitizer.sanitize(SecurityContext.STYLE, `${value}`);
}
public sanitizeHTML(value: string): string {
return this.sanitizer.sanitize(SecurityContext.HTML, `${value}`);
constructor(sanitizer: DomSanitizer) {
super(sanitizer);
}
}
<div class="progress my-2 position-relative"
style="height: 2rem;">
<div *ngIf="base && percent"
[attr.aria-valuenow]="percent"
[class]="('progress-bar overflow-hidden bg-' + progressbarCssClass)"
[style.width]="sanitizeStyle(percent)"
aria-valuemax="100"
aria-valuemin="0"
role="progressbar"></div>
<div class="my-2">
<ng-container *ngIf="base">
<div class="d-flex align-self-center align-items-center position-absolute h-100"
style="left: 10px;">{{normalizedAnswerIndex}}:&nbsp;<span [innerHTML]="sanitizeHTML(label)"></span>
</div>
<div class="align-self-center position-absolute"
style="right: 10px;">{{percent}}&nbsp;|&nbsp;{{absolute}}&nbsp;/&nbsp;{{base}}
<div *ngIf="base"
class="d-flex justify-content-between">
<span class="text-truncate mx-2">{{normalizedAnswerIndex}}:&nbsp;<span [innerHTML]="sanitizeHTML(label)"></span></span>
<span class="mr-2">{{percent}}&nbsp;|&nbsp;{{absolute}}&nbsp;/&nbsp;{{base}}</span>
</div>
<div class="progress">