File

src/app/tool-page/issue-container/issue-container.component.ts

Description

Container for the display of a single Issue.

Implements

OnInit

Metadata

selector app-issue-container
styleUrls issue-container.component.css
templateUrl ./issue-container.component.html

Index

Properties
Methods
Inputs

Constructor

constructor(toolService: ToolService, courseService: CourseService)

Constructor

Parameters :
Name Type Optional Description
toolService ToolService no

Provides information and management for available tools.

courseService CourseService no

Provides information and management for selected courses. Being used in issue-container.component.html (i.e. DO NOT DELETE)

Inputs

index

The index of the item's issues array the issue is at.

Type: number

issue

The issue attached to the display.

Type: Issue

Methods

buildEditorTabs
buildEditorTabs()

Using the {@link Tab}s provided by the Node Tool, builds useable tab objects for each issue.

Returns : any

The tabs to use to build the editor instance.

getButtonClasses
getButtonClasses(desiredStatus: string, elType: string)

Determines the classes used to style buttons based on the current status of the issue they belong to.

Parameters :
Name Type Optional Description
desiredStatus string no

What status the issue current is.

elType string no

Either "button" or "icon".

Returns : string

The classes to apply to the element.

isFixed
isFixed()

Returns whether or not the item's status is fixed or failed.

Returns : boolean

Whether or not this issue's status is fixed or failed.

ngOnInit
ngOnInit()

Fired when the component is initialized, this manages the item's display. It inserts the form for the Issue's FixOptions if available.

Returns : void
onChange
onChange(optionKey: )

Manages the validity of the form on each keystroke.

Parameters :
Name Optional Description
optionKey no

The key of the option this came from.

Returns : void
setIssueStatus
setIssueStatus(newStatus: )

Sets the status of the issue.

Parameters :
Name Optional Description
newStatus no

The new status to set the issue to.

Returns : void
showEditor
showEditor()

Since Object.keys does not work in angular templating, this is a workaround. It checks if the issue has any HTML to display in the editor. Used by the app-code-editor tag to determine if it should display.

Returns : boolean

Properties

codeEditor
codeEditor: ElementRef
Type : ElementRef
Decorators : ViewChild

A reference to the code editor element for the respective issue.

Public courseService
courseService: CourseService
Type : CourseService
Provides information and management for selected courses. Being used in issue-container.component.html (i.e. DO NOT DELETE)
issueDetails
issueDetails: ElementRef
Type : ElementRef
Decorators : ViewChild

Element reference to the card containing details about the issue.

Public toolService
toolService: ToolService
Type : ToolService
Provides information and management for available tools.
import { Component, OnInit, Input, ViewChild, ElementRef } from '@angular/core';
import { CourseService } from '../../course.service'; // Being used in issue-container.component.html (i.e. DO NOT DELETE)
import { ToolService } from '../../tool.service';
import { Issue } from '../../interfaces';
import { OptionModel } from '../../classes';

/**
 * Container for the display of a single {@link Issue}.
 */
@Component({
    selector: 'app-issue-container',
    templateUrl: './issue-container.component.html',
    styleUrls: ['./issue-container.component.css']
})
export class IssueContainerComponent implements OnInit {
    /** The issue attached to the display. */
    @Input('issue') issue: Issue;

    /** The index of the item's issues array the issue is at. */
    @Input('index') index: number;

    /** Element reference to the card containing details about the issue. */
    @ViewChild('issueDetails') issueDetails: ElementRef;

    /** A reference to the code editor element for the respective issue. */
    @ViewChild('codeEditor') codeEditor: ElementRef;

    /**
     * Constructor
     * @param toolService Provides information and management for available tools.
     * @param courseService Provides information and management for selected courses.
     * Being used in issue-container.component.html (i.e. DO NOT DELETE)
     */
    constructor(public toolService: ToolService,
        public courseService: CourseService) { }

    /**
     * Fired when the component is initialized, this manages the item's display.
     * It inserts the form for the {@link Issue}'s {@link FixOption}s if available.
     */
    ngOnInit() {
        this.issueDetails.nativeElement.innerHTML = this.issue.display;
        this.issue.optionModel = new OptionModel(this.toolService.selectedTool.fixOptions);
        this.issue.formGroup = this.issue.optionModel.toGroup();

        // Update option values if there are values saved for any options
        if (this.issue.tempValues) {
            Object.keys(this.issue.tempValues).forEach(optionKey => {
                const control = this.issue.formGroup.get(optionKey);
                control.setValue(this.issue.tempValues[optionKey], { onlySelf: true });
                control.updateValueAndValidity();
            });
        }
    }

    /**
     * Using the {@link Tab}s provided by the Node Tool, builds
     * useable tab objects for each issue.
     * @returns {Object[]} The tabs to use to build the editor instance.
     */
    buildEditorTabs() {
        if (!this.toolService.selectedTool.editorTabs) { return; }
        return this.toolService.selectedTool.editorTabs.map(editorTab => {
            return {
                title: editorTab.title,
                htmlString: this.issue.html[editorTab.htmlKey],
                readOnly: editorTab.readOnly
            };
        });
    }

    /**
     * Sets the status of the issue.
     * @param newStatus The new status to set the issue to.
     */
    setIssueStatus(newStatus) {
        if (this.issue.status === 'fixed') {
            return;
        } else if (newStatus === this.issue.status) {
            this.issue.status = 'untouched';
        } else {
            this.issue.status = newStatus;
        }
    }

    /**
     * Determines the classes used to style buttons based on the
     * current status of the issue they belong to.
     * @param {string} desiredStatus What status the issue current is.
     * @param {string} elType Either "button" or "icon".
     * @returns {string} The classes to apply to the element.
     */
    getButtonClasses(desiredStatus: string, elType: string) {
        let classes = '';
        if (elType === 'button') {
            classes += 'waves-effect waves btn white';
        }
        if (this.issue.status !== 'untouched' && this.issue.status !== desiredStatus) {
            classes += ' text-lighten-4';
        } else if (desiredStatus === 'approved') {
            classes += ' text-accent-4';
        } else if (desiredStatus === 'skipped') {
            classes += ' text-darken-2';
        }
        return classes;
    }

    /**
     * Manages the validity of the form on each keystroke.
     * @param optionKey The key of the option this came from.
     */
    onChange(optionKey) {
        if (['untouched', 'fixed', 'failed'].includes(this.issue.status)) {
            this.issue.status = 'untouched';
        }
        if (!this.issue.tempValues) {
            this.issue.tempValues = {};
        }
        this.issue.tempValues[optionKey] = this.issue.formGroup.value[optionKey];
    }

    /**
     * Returns whether or not the item's status is fixed or failed.
     * @returns {boolean} Whether or not this issue's status is fixed or failed.
     */
    isFixed() {
        return this.issue.status === 'fixed' || this.issue.status === 'failed';
    }

    /**
     * Since Object.keys does not work in angular templating, this is
     * a workaround. It checks if the issue has any HTML to display in
     * the editor. Used by the app-code-editor tag to determine if it
     * should display.
     */
    showEditor() {
        return Object.keys(this.issue.html).length > 0;
    }
}
<div [ngClass]="courseService.getBackgroundColorClasses(issue.status)" class="issueContainer card">

  <div class="card-content">
    <h2 class="cobalt-text">{{issue.title}}</h2>
    <div class="issueContainer__issueDetails" #issueDetails></div>

    <form materialize [formGroup]="issue.formGroup" #optionsForm="ngForm">
      <div *ngFor="let option of issue.optionModel.options" class="form-row">
        <h3>{{option.title}}</h3>
        <div class="option__description">{{option.description}}</div>
        <div [ngSwitch]="option.type" class="option__container" [class.multiselect]="option.type === 'multiselect'" [class.required]="!issue.formGroup.controls[option.key].valid">

          <!-- Silly, but [attr.disabled] was the only way I could get it to be disabled -->
          <div *ngSwitchCase="'text'" class="option__text">
            <input [attr.disabled]="isFixed() ? 'disabled' : null" type="{{option.type}}" id="{{option.key}}" [formControlName]="option.key"
              (input)="onChange(option.key)" autocomplete="off" autofocus>
          </div>

          <div *ngSwitchCase="'dropdown'">
            <select [attr.disabled]="isFixed() ? 'disabled' : null" style="display: block" [formControlName]="option.key" (input)="onChange(option.key)">
              <option *ngFor="let choice of option.choices">{{choice}}</option>
            </select>
          </div>

          <div *ngSwitchCase="'multiselect'">
            <select [attr.disabled]="isFixed() ? 'disabled' : null" style="display: block" [formControlName]="option.key" (input)="onChange(option.key)"
              multiple>
              <option *ngFor="let choice of option.choices">{{choice}}</option>
            </select>
          </div>
        </div>
      </div>
    </form>
  </div>

  <!-- Code Editor - Will only show up if the issue has contents in its "html" property -->
  <div *ngIf="showEditor()">
    <app-code-editor [issue]="issue" [tabs]="buildEditorTabs()" [highlight]="issue.html.highlight"
      #codeEditor></app-code-editor>
  </div>

  <!-- Card Actions - this section contains the "approve" and "skip" buttons, as well as the fix message container -->
  <div class="card-action" *ngIf="toolService.selectedTool.toolType === 'fix'">

    <button *ngIf="issue.status !== 'fixed' && issue.status !== 'failed'" (click)="setIssueStatus('approved')" [ngClass]="getButtonClasses('approved', 'button')"
      class="green-text" [disabled]="issue.formGroup && !issue.formGroup.valid">
      <i *ngIf="!issue.formGroup || issue.formGroup.valid" [ngClass]="getButtonClasses('approved', 'icon')" class="green-text material-icons left">
        {{issue.status !== 'approved' ? 'check' : 'check_circle_outline'}}
      </i>
      <i *ngIf="issue.formGroup && !issue.formGroup.valid" class="material-icons left">
        block
      </i>
      {{issue.status !== 'approved' ? (issue.status !== 'fixed' ? 'approve' : 'fixed') : 'approved'}}
    </button>

    <button *ngIf="issue.status !== 'fixed' && issue.status !== 'failed'" (click)="setIssueStatus('skipped')" [ngClass]="getButtonClasses('skipped', 'button')"
      class="blue-grey-text">
      <i [ngClass]="getButtonClasses('skipped', 'icon')" class="blue-grey-text material-icons left">
        {{issue.status !== 'skipped' ? 'remove' : 'call_missed_outgoing'}}
      </i>

      {{issue.status !== 'skipped' ? 'skip' : 'skipped'}}
    </button>

    <div *ngIf="issue.status === 'fixed'" class="blue-text text-accent-3">
      FIXED {{toolService.selectedTool.fixedMessage ? ' - ' + toolService.selectedTool.fixedMessage : ''}}
    </div>
    <div *ngIf="issue.status === 'failed'" class="red-text text-accent-4">
      FAILED - Please contact a Katana developer with the course ID, item name, and issue title.
    </div>

  </div>

</div>
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""