Reading Time: 5 minutes

මේ ලිපියෙන් කියන්න යන්නේ අනිත් ලිපි 3න්ම Continue වුන Application එකේ අන්තිම ලිපිය. ඒ ලිපි ටික බැලුවේ නැත්නම් මෙතනින් බලන්න.

Part 01
Part 02
Part 03

මේ part එකේදි අපි font-end part එක complete කරන්න යන්නේ.

Implementing Angular Material

මුල්ම part එකේදි අපි Material components පාවිච්චි කරා Mat toolbar එකකට. මේ part එකේදි අපි තවත් Modules කිහිපයක්ම යොදා ගන්නවා Front end එක් design කරගන්න. ඒකට මුලින්ම මේ module ටික app module එකට import කරගන්න ඕන මේ විදියට

 
import { MatToolbarModule,
MatFormFieldModule,
MatInputModule,
MatOptionModule,
MatSelectModule,
MatIconModule,
MatButtonModule,
MatCardModule,
MatTableModule,
MatDividerModule,
MatSnackBarModule } from '@angular/material';

ඊළඟට මේ විදියට import කරගත්ත Module ටික imports Array එකට මේ විදියට add කරගන්න.

 
@NgModule({
declarations: [
AppComponent,
CreateComponent,
EditComponent,
ListComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
RouterModule.forRoot(routes),
HttpClientModule,
MatToolbarModule,
MatFormFieldModule,
MatInputModule,
MatOptionModule,
MatSelectModule,
MatIconModule,
MatButtonModule,
MatCardModule,
MatTableModule,
MatDividerModule,
MatSnackBarModule
],
providers: [IssueService],
bootstrap: [AppComponent]
})

දැන් අපි කරන්න යන්නේ අලුතින් Issue model එකක් හදා ගන්න එක. Issue Objects හදා ගන්න පහසු වෙන්න අපි ඕන තැනකින් Access කරන්න පුළුවන් වෙන විදියට මේ Issue model එක අලුත් file එකක හදා ගන්නවා මේ විදියට. මේ file එක src/app/issue.model.ts විදියට path එක තියෙන්න හදා ගන්න.

 
export interface Issue {
id: String;
title: String;
responsible: String;
description: String;
severity: String;
status: String;
}

මේ විදියට Object එකක තියෙන්න ඕන elements ටික interface එකක් ඇතුලෙ define කර ගත්තහම අපිට අවශ්‍ය වෙලාවට මේ template එක use කරලා issue objects හදා ගන්න පුළුවන්.

Implementing ListComponent

දැන් අපි කරන්න යන්නේ පළවෙනි ලිපියෙදි අපි හදා ගත්ත list component එකේ modification එකක් කරන්න. ඒකෙ code එක මේ විදියට හදා ගන්න මුලන්ම. එක එක function එකින් කරන දේ පහලින් විස්තර කරන්නම්

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { MatTableDataSource } from '@angular/material';
import { Issue } from '../../issue.model';
import { IssueService } from '../../issue.service';
@Component({
  selector: 'app-list',
  templateUrl: './list.component.html',
  styleUrls: ['./list.component.css']
})
export class ListComponent implements OnInit {
  issues: Issue[];
  displayedColumns = ['title', 'responsible', 'severity', 'status', 'actions'];
  constructor(private issueService: IssueService, private router: Router) { }
  ngOnInit() {
    this.fetchIssues();
  }
  fetchIssues() {
    this.issueService
    .getIssues()
    .subscribe((data: Issue[]) => {
      this.issues = data;
      console.log('Data requested ... ');
      console.log(this.issues);
    });
  }
  editIssue(id) {
    this.router.navigate([`/edit/${id}`]);
  }
  deleteIssue(id) {
    this.issueService.deleteIssue(id).subscribe(() => {
      this.fetchIssues();
    });
  }
}

මුලින්ම අපි කලින් හදා ගත්ත Issue Service එක import කරගෙන constructor එකට inject කරන්න ඕන. ඒ වගේම Issue model එකත් අපි import කරගන්න ඕන.

මේ list component එකට අපි functions 3ක් add කරලා තියෙනවා.

  1. fetchIssue : මේ function එකෙන් කරන්නේ issue service එක හරහා issue list එක fetch කරගන්න එක. මේ fetch කරගන්න issue list එක issue service එකේ තියෙන getIssue method එකෙන් observable type එකක් return වෙනවා. මේකට subscribe කරාම එන issue list එක අපි issues array එකට දාගන්න එක තමයි මේ function එකෙන් කරන්නේ
  2. editIssue: මේ function එකෙන් කරන්නේ button click එකකින් edit component එකට navigate කරන එක. ඒ එක්ක අපි click කරේ මොන element එකද කියලා හොයා ගන්න පුළුවන් විදියේ id එකක් route එකට pass කරනවා
  3. deleteIssue: මේ function එකෙන් අපි issue service එකේ deleteissue function එක call කරනවා. ඊට පස්සේ edit කරපු data ආපහු fetch කරගෙන table එක refresh කරගන්නවා.

Implementing The Component Template

<div>
  <br>
  <mat-card>
    <button mat-raised-button color="primary" routerLink="/create">Create New Issue</button>
    <br><br>
    <mat-divider></mat-divider>
    <br>
    <table mat-table [dataSource]="issues">
      <ng-container matColumnDef="title">
        <th mat-header-cell *matHeaderCellDef> Title </th>
        <td mat-cell *matCellDef="let element"> {{element.title}} </td>
      </ng-container>
      <ng-container matColumnDef="responsible">
        <th mat-header-cell *matHeaderCellDef> Responsible </th>
        <td mat-cell *matCellDef="let element"> {{element.responsible}} </td>
      </ng-container>
      <ng-container matColumnDef="severity">
        <th mat-header-cell *matHeaderCellDef> Severity </th>
        <td mat-cell *matCellDef="let element"> {{element.severity}} </td>
      </ng-container>
      <ng-container matColumnDef="status">
        <th mat-header-cell *matHeaderCellDef> Status </th>
        <td mat-cell *matCellDef="let element"> {{element.status}} </td>
      </ng-container>
      <ng-container matColumnDef="actions">
          <th mat-header-cell *matHeaderCellDef class="mat-column-right"> Actions </th>
          <td mat-cell *matCellDef="let element" class="mat-column-right">
            <button mat-button color="primary" (click)="editIssue(element._id)">Edit</button>
            <button mat-button color="warn" (click)="deleteIssue(element._id)">Delete</button>
          </td>
        </ng-container>
      <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
      <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
    </table>
  </mat-card>
</div>

අපි මේ html component එක හදා ගන්න කලින් import කරගත්ත angular material components යොදාගෙන තියෙනවා.

Implementing CreateComponent

කලින් වගේම මුලින්ම මුලින්ම create.component.ts එක මේ විදියට හදා ගන්න ඕන

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { IssueService } from '../../issue.service';
@Component({
  selector: 'app-create',
  templateUrl: './create.component.html',
  styleUrls: ['./create.component.css']
})
export class CreateComponent implements OnInit {
  createForm: FormGroup;
  constructor(private issueService: IssueService, private fb: FormBuilder, private router: Router) {
    this.createForm = this.fb.group({
      title: ['', Validators.required],
      responsible: '',
      description: '',
      severity: ''
    });
  }
  addIssue(title, responsible, description, severity) {
    this.issueService.addIssue(title, responsible, description, severity).subscribe(() => {
      this.router.navigate(['/list']);
    });
  }
  ngOnInit() {
  }
}

මේ form එක හදා ගන්න අපි FormBuilder, FormGroup, Validators යොදා ගන්නවා. ඒ වගේම ReactiveFormsModule එක app.module.ts එකට import කරගන්න ඕන.

import { ReactiveFormsModule } from '@angular/forms';

ඒ වගේම imports array එකට insert කරගන්න ඕන.

Add Issue Button click එකට අපි addissue function එක fire වෙන්න link කරගෙන තියෙන්නේ. මේ function එකෙන් issueService එක call කරලා db එකේ save කරගන්නවා.

create.component.html එක මේ විදියට code කරගන්න

<div>
  <br>
  <mat-card>
    <section class="mat-typography">
      <h3>Create A New Issue</h3>
    </section>
    <mat-divider></mat-divider>
    <br>
    <form [formGroup]="createForm" class="create-form">
      <mat-form-field class="field-full-width">
        <input matInput placeholder="Issue Title" formControlName="title" #title>
      </mat-form-field>
      <mat-form-field class="field-full-width">
        <input matInput placeholder="Responsible" formControlName="responsible" #responsible>
      </mat-form-field>
      <mat-form-field class="field-full-width">
        <textarea matInput placeholder="Description" formControlName="description" #description></textarea>
      </mat-form-field>
      <mat-form-field>
          <mat-select placeholder="Severity" formControlName="severity" #severity>
            <mat-option value="Low">Low</mat-option>
            <mat-option value="Medium">Medium</mat-option>
            <mat-option value="High">High</mat-option>
          </mat-select>
      </mat-form-field>
      <mat-divider></mat-divider>
      <br><br>
      <button mat-raised-button color="accent" routerLink="/list">Back</button> 
      <button type="submit" (click)="addIssue(title.value, responsible.value, description.value, severity.value)" [disabled]="createForm.pristine || createForm.invalid" mat-raised-button color="primary">Save</button>
    </form>
  </mat-card>
</div>

Implementing EditComponent

edit.component.ts

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { MatSnackBar } from '@angular/material';
import { IssueService } from '../../issue.service';
import { Issue } from '../../issue.model';

@Component({
  selector: 'app-edit',
  templateUrl: './edit.component.html',
  styleUrls: ['./edit.component.css']
})

export class EditComponent implements OnInit {
  id: String;
  issue: any = {};
  updateForm: FormGroup;
  constructor(private issueService: IssueService, private router: Router, private route: ActivatedRoute, private snackBar: MatSnackBar, private fb: FormBuilder) { 
    this.createForm();
  }
  ngOnInit() {
    this.route.params.subscribe(params => {
      this.id = params.id;
      this.issueService.getIssueById(this.id).subscribe(res => {
        this.issue = res;
        this.updateForm.get('title').setValue(this.issue.title);
        this.updateForm.get('responsible').setValue(this.issue.responsible);
        this.updateForm.get('description').setValue(this.issue.description);
        this.updateForm.get('severity').setValue(this.issue.severity);
        this.updateForm.get('status').setValue(this.issue.status);
      });
    });
  }
  createForm() {
    this.updateForm = this.fb.group({
      title: ['', Validators.required ],
      responsible: '',
      description: '',
      severity: '',
      status: ''
    });
  }
  updateIssue(title, responsible, description, severity, status) {
    this.issueService.updateIssue(this.id, title, responsible, description, severity, status).subscribe(() => {
      this.snackBar.open('Issue updated successfully', 'OK', {
        duration: 3000,
      });
    });
  }

මේ component එකේ විශේෂත්වය තමයි component එක create වෙද්දි data fetch වෙන්න ඕන. ඒක හින්දා අපි ඒක onInit function එක ඇතුලට දාලා තියෙන්න ඕන.

edit.component.html

<div>
    <br>
    <mat-card>
      <section class="mat-typography">
          <h3>Update Issue</h3>
      </section>
      <mat-divider></mat-divider>
      <br>
      <form [formGroup]="updateForm" class="edit-form">
        <mat-form-field class="field-full-width">
          <input placeholder="Title" matInput formControlName="title" #title>
        </mat-form-field>
        <mat-form-field class="field-full-width">
          <input placeholder="Responsible" matInput formControlName="responsible" #responsible>
        </mat-form-field>
        <mat-form-field class="field-full-width">
          <textarea placeholder="Description" matInput formControlName="description" #description></textarea>
        </mat-form-field>
        <mat-form-field  class="field-full-width">
            <mat-select placeholder="Severity" formControlName="severity" #severity>
              <mat-option value="Low">Low</mat-option>
              <mat-option value="Medium">Medium</mat-option>
              <mat-option value="High">High</mat-option>
            </mat-select>
        </mat-form-field>
        <mat-form-field class="field-full-width">
            <mat-select placeholder="Status" formControlName="status" #status>
              <mat-option value="Open">Open</mat-option>
              <mat-option value="In Progress">In Progress</mat-option>
              <mat-option value="Done">Done</mat-option>
            </mat-select>
        </mat-form-field>
        <mat-divider></mat-divider>
        <br><br>
        <button mat-raised-button color="accent" routerLink="/list">Back</button> 
        <button type="submit" (click)="updateIssue(title.value, responsible.value, description.value, severity.value, status.value)" [disabled]="updateForm.pristine || updateForm.invalid" mat-raised-button color="primary">Save</button>
      </form>
    </mat-card>
</div>

මේ විදියට හදා ගත්තට පස්සේ front angular එකයි back node එකයි start කරලා test කරලා බලන්න පුළුවන්.

code එකේ නොපැහැදිලි තැනක් හරි error එකක් හරි තිබුණොත් මේ github repo එකේ තියෙනවා මේ application එකේ tested version එක. ඒකෙ code එක බලන්න.

https://github.com/Danushka96/issuetracker/


Danushka Herath

Undergraduate of UCSC | Blogger @thesigma.gq | Co-founder of esportlk | Game Developer @esportlk |

Leave a Reply

Your email address will not be published. Required fields are marked *