You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@griffin.apache.org by gu...@apache.org on 2017/10/11 04:31:12 UTC

[12/13] incubator-griffin git commit: refactor ui with angular2

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/42ee8863/ui/angular/src/app/job/create-job/create-job.component.html
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/job/create-job/create-job.component.html b/ui/angular/src/app/job/create-job/create-job.component.html
new file mode 100644
index 0000000..23e62d0
--- /dev/null
+++ b/ui/angular/src/app/job/create-job/create-job.component.html
@@ -0,0 +1,252 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<div class="mask" *ngIf = 'maskOpen' (click)="close()"></div>
+
+<div class="container-fluid">
+  <div class="row">
+    <h5 class="over-title margin-bottom-15 job">Create Job</h5>
+  </div><!--//row-->
+  <div class="row">
+    <!-- <form name="Form" id="form" novalidate> -->
+    <form name= "Form" id="form" (ngSubmit)="submit(jobForm)" #jobForm="ngForm" novalidate>
+      <div  class="formStep" >
+        <label class="stepDesc info">Please setup the job required information</label>
+        <div class="container-fluid">
+
+          <!-- schema definition list -->
+          <div class="col-md-12 col-lg-12 col-sm-12">
+            <fieldset (window:resize)="onResize($event)">
+              <legend>
+                Required Information
+              </legend>
+              <div class="y-scrollable">
+                <div class="col-md-12 col-lg-12 col-sm-12">
+                  <div class="form-group"
+                       [ngClass]="{'has-error':jobName.dirty&&jobName.invalid, 'has-success':jobName.valid}">
+                    <label class="col-md-2 col-lg-2 col-sm-2 control-label">
+                      Source Pattern<span class="symbol required"></span>:
+                    </label>
+
+                    <div class="col-md-10 col-lg-10 col-sm-10 ">
+                      <input type="text" class="form-control" [(ngModel)]="sourcePat" #jobName="ngModel" name="jobName" placeholder="Please input the source partition, such as 'YYYYMMdd-HH'." required
+                             pattern="YYYYMMdd-HH"
+                             maxlength='11'>
+                      <!-- /i<span class="error text-small block " *ngIf="jobName.dirty && jobName.errors.Pattern">Please input partition like 'YYYYMMdd-HH'</span> jobName.dirty && jobName.errors.pattern-->
+                      <span class="error text-small block " *ngIf="jobName.dirty&&jobName.invalid">Please input partition like 'YYYYMMdd-HH'</span>
+                    </div>
+                  </div>
+                </div>
+                <div class="col-md-12 col-lg-12 col-sm-12">
+                  <div class="form-group" [ngClass]="{'has-error':targetName.dirty&&targetName.invalid, 'has-success':targetName.valid}">
+                    <label class="col-md-2 col-lg-2 col-sm-2 control-label">
+                      Target Pattern<span class="symbol required"></span>:
+                    </label>
+                    <div class="col-md-10 col-lg-10 col-sm-10 ">
+                      <input type="text" class="form-control" [(ngModel)]="targetPat" placeholder="Please input target partition of your job, such as 'YYYYMMdd-HH'."
+                             required pattern="YYYYMMdd-HH" maxlength='11' name="targetName" #targetName="ngModel">
+                      <span class="error text-small block " *ngIf="targetName.dirty&&targetName.invalid">Please input partition like 'YYYYMMdd-HH'</span>
+                    </div>
+                  </div>
+                </div>
+                <div class="col-md-12 col-lg-12 col-sm-12">
+                  <div class="form-group">
+                    <label for="measureSelector" class="col-md-2 col-lg-2 col-sm-2 control-label">
+                      Measure Name:
+                    </label>
+
+                    <div class="col-md-10 col-lg-10 col-sm-10 ">
+                      <select id="measureSelector" class="form-control"
+                              ngControl="name" required name="measure.name" [(ngModel)]="measure">
+                        <option *ngFor="let row of Measures" value="{{row.name}}" >{{row.name}}</option>
+                      </select>
+                    </div>
+                  </div>
+                </div>
+                <div class="col-md-12 col-lg-12 col-sm-12">
+                  <div class="form-group" >
+                    <label class="col-md-2 col-lg-2 col-sm-2 control-label">
+                      Start At:
+                    </label>
+
+                    <!-- <div class="col-md-5 col-lg-5 col-sm-5 ">
+                        <input type="text" id="datepicker" class="form-control" name="jobStartTime" [(ngModel)]="jobStartTime" >
+                    </div> -->
+                    <div class="col-md-5 col-lg-5 col-sm-5 ">
+                      <!-- <md-form-field> -->
+                      <input matInput [matDatepicker]="picker" placeholder="Choose a date" style="color:black;" [(ngModel)]="jobStartTime" name="jobStartTime"
+                      >
+                      <mat-datepicker-toggle mdSuffix [for]="picker" (click)="setHeight()"></mat-datepicker-toggle>
+                      <mat-datepicker #picker ></mat-datepicker>
+
+
+                      <!-- </md-form-field> -->
+                    </div>
+                    <div class="col-md-5 col-lg-5 col-sm-5" [ngClass]="{'has-error':timeDetail.invalid, 'has-success':timeDetail.valid}">
+                      <input type="text" class="form-control" id="timeDetail" (click)="showTime()" value="{{hourDetail}}:{{minuteDetail}}:{{secondDetail}} "
+                             [(ngModel)]="timeDetail" name="time"
+
+                      >
+                      <div id="timePopup"  class="col-md-11 col-lg-11 col-sm-11 setgrey" *ngIf="isOpen">
+                        <div id="hourSelector">
+                          <p (click)="changeTime(0,23,true,hourDetail,1)"><i class="fa fa-caret-up" aria-hidden="true"></i></p>
+                          <p>{{hourDetail}}</p>
+                          <p (click)="changeTime(0,23,false,hourDetail,1)"><i class="fa fa-caret-down" aria-hidden="true"></i></p>
+                        </div>
+                        <div class="division">
+                          <p>:</p>
+                        </div>
+                        <div id="minuteSelector">
+                          <p (click)="changeTime(0,59,true,minuteDetail,2)"><i class="fa fa-caret-up" aria-hidden="true"></i></p>
+                          <p >{{minuteDetail}}</p>
+                          <p (click)="changeTime(0,59,false,minuteDetail,2)"><i class="fa fa-caret-down" aria-hidden="true"></i></p>
+                        </div>
+                        <div class="division">
+                          <p>:</p>
+                        </div>
+                        <div id="secondSelector">
+                          <p (click)="changeTime(0,59,true,secondDetail,3)"><i class="fa fa-caret-up" aria-hidden="true"></i></p>
+                          <p >{{secondDetail}}</p>
+                          <p (click)="changeTime(0,59,false,secondDetail,3)"><i class="fa fa-caret-down" aria-hidden="true"></i></p>
+                        </div>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+                <div class="col-md-12 col-lg-12 col-sm-12">
+                  <div class="form-group">
+                    <label for="systemSelector" class="col-md-2 col-lg-2 col-sm-2 control-label">
+                      Interval:
+                    </label>
+
+                    <div class="col-md-5 col-lg-5 col-sm-5 ">
+                      <input type="text" id="systemSelector" class="form-control" [(ngModel)]="periodTime"  required placeholder="How often it works" name="periodTime"
+                             onblur="if(this.value.length==1){this.value=this.value.replace(/[^1-9]/g,'')}else{this.value=this.value.replace(/\D/g,'')}"
+                             onafterpaste="if(this.value.length==1){this.value=this.value.replace(/[^1-9]/g,'')}else{this.value=this.value.replace(/\D/g,'')}">
+                    </div>
+                    <div class="col-md-5 col-lg-5 col-sm-5 ">
+                      <select id="timeSelector" class="form-control" [(ngModel)]="timeType" name="timeSelector" required>
+                        <!--<option  value="hours" >hours</option>-->
+                        <!--<option  value="minutes" >minutes</option>-->
+                        <!--<option  value="seconds" >seconds</option>-->
+                        <option *ngFor="let time of Times"  >{{time}}</option>
+                      </select>
+                    </div>
+                  </div>
+                </div>
+              </div>
+
+              <div class="setcolor">
+                <p>
+                  <i class="fa fa-info-circle"></i> After submitted, please go to "
+                  <a class="bark-link" href="/jobs">Jobs</a>" to check the job status
+                </p>
+              </div>
+
+            </fieldset>
+          </div>
+
+          <div class="form-group btn-container" >
+            <button class="btn btn-primary btn-o back-step btn-wide pull-left" (click)="form.prev()">
+              <i class="fa fa-arrow-circle-left"></i> Back
+            </button>
+            <!-- <button class="btn btn-primary btn-o next-step btn-wide pull-right" (click)="form.submit(Form)"> -->
+            <toaster-container></toaster-container>
+            <button type="submit" class="btn btn-primary btn-o next-step btn-wide pull-right" (click)="submit(jobForm)"
+            >
+              <!-- <button class="btn btn-primary btn-o next-step btn-wide pull-right" data-toggle="modal" data-target="#confirm"> -->
+              Submit
+            </button>
+          </div>
+        </div>
+      </div>
+
+      <div class="modal fade" id="confirm-job" role="dialog" [ngClass]="{'in': visibleAnimate}"
+           [ngStyle]="{'display': visible ? 'block' : 'none', 'opacity': visibleAnimate ? 1 : 0}"
+           (click)="onContainerClicked($event)">
+        <div class="modal-dialog modal-xg modal-lg">
+          <div class="modal-content">
+            <div class="modal-header">
+              <button type="button" class="close" data-dismiss="modal" aria-hidden="true" (click)="hide()">&times;</button>
+              <h4 class="modal-title">Save the job with the below information?</h4>
+            </div>
+            <div class="modal-body">
+              <!-- <ng-include src="'/pages/jobs/confirmation-ac.html'"/> -->
+              <div class="container-fluid" id="viewJobContent" style="overflow:auto;">
+                <div class="row">
+                  <h5 class="over-title margin-bottom-15">Basic information</h5>
+                </div><!--//row-->
+                <div class="row">
+                  <div  class="col-lg-12 col-md-12 col-sm-12">
+                    <div id="viewrule-definition" class="viewrule-content">
+                      <div class="row">
+                        <label class="col-md-4 col-lg-4 col-sm-4">
+                          Source Pattern:
+                        </label>
+                        <div class="col-md-8 col-lg-8 col-sm-8 " style="color: #fff">
+                          {{sourcePat}}
+                        </div>
+                      </div>
+                      <div class="row">
+                        <label class="col-md-4 col-lg-4 col-sm-4">
+                          Target Pattern:
+                        </label>
+                        <div class="col-md-8 col-lg-8 col-sm-8 " style="color: #fff">
+                          {{targetPat}}
+                        </div>
+                      </div>
+                      <div class="row">
+                        <label class="col-md-4 col-lg-4 col-sm-4">
+                          Measure Name:
+                        </label>
+                        <div class="col-md-8 col-lg-8 col-sm-8 " style="color: #fff">
+                          {{measure}}
+                          <!-- {{Measures}} -->
+                        </div>
+                      </div>
+                      <div class="row">
+                        <label for="systemSelector" class="col-md-4 col-lg-4 col-sm-4">
+                          Start at:
+                        </label>
+                        <div class="col-md-8 col-lg-8 col-sm-8 " style="color: #fff" *ngIf="jobStartTime">
+                          {{jobStartTime.toLocaleDateString("en-US")}}&nbsp; {{timeDetail}}
+                        </div>
+                      </div>
+                      <div class="row">
+                        <label class="col-md-4 col-lg-4 col-sm-4">
+                          Interval:
+                        </label>
+                        <div class="col-md-8 col-lg-8 col-sm-8" style="color: #fff">{{periodTime}}&nbsp;{{timeType}}
+                        </div>
+                      </div>
+                    </div>
+                  </div>
+                </div><!--//row-->
+                <br/>
+              </div>
+            </div>
+            <div class="modal-footer">
+              <button type="button" class="btn btn-default" data-dismiss="modal" (click)="hide()">Cancel</button>
+              <button type="button" class="btn btn-primary" (click)="save()">Save</button>
+            </div>
+          </div>
+        </div>
+      </div>
+    </form>
+  </div><!--//row-->
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/42ee8863/ui/angular/src/app/job/create-job/create-job.component.spec.ts
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/job/create-job/create-job.component.spec.ts b/ui/angular/src/app/job/create-job/create-job.component.spec.ts
new file mode 100644
index 0000000..44292d5
--- /dev/null
+++ b/ui/angular/src/app/job/create-job/create-job.component.spec.ts
@@ -0,0 +1,43 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { CreateJobComponent } from './create-job.component';
+
+describe('CreateJobComponent', () => {
+  let component: CreateJobComponent;
+  let fixture: ComponentFixture<CreateJobComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ CreateJobComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(CreateJobComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should be created', () => {
+    expect(component).toBeTruthy();
+  });
+});

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/42ee8863/ui/angular/src/app/job/create-job/create-job.component.ts
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/job/create-job/create-job.component.ts b/ui/angular/src/app/job/create-job/create-job.component.ts
new file mode 100644
index 0000000..1cadc85
--- /dev/null
+++ b/ui/angular/src/app/job/create-job/create-job.component.ts
@@ -0,0 +1,229 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+import { Component, OnInit } from '@angular/core';
+import { FormControl } from '@angular/forms';
+import { FormsModule } from '@angular/forms';
+import { MaxLengthValidator } from '@angular/forms';
+import { NgControlStatus ,Validators} from '@angular/forms';
+import { PatternValidator } from '@angular/forms';
+// import {MdDatepickerModule} from '@angular/material';
+import {MatDatepickerModule} from '@angular/material';
+import {ServiceService} from '../../service/service.service';
+
+
+import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
+import {ToasterModule, ToasterService, ToasterConfig} from 'angular2-toaster';
+import * as $ from 'jquery';
+import  {HttpClient,HttpParams} from '@angular/common/http';
+import  {Router} from "@angular/router";
+
+@Component({
+  selector: 'app-create-job',
+  templateUrl: './create-job.component.html',
+  providers:[ServiceService],
+  styleUrls: ['./create-job.component.css']
+})
+export class CreateJobComponent implements OnInit {
+
+  constructor(toasterService: ToasterService,private http: HttpClient,private router:Router,public servicecService:ServiceService) {
+    this.toasterService = toasterService;
+  };
+
+  public toasterconfig : ToasterConfig =
+        new ToasterConfig({
+            showCloseButton: true,
+            tapToDismiss: false,
+            timeout: 0
+        });
+
+  currentStep = 1;
+  Times = ['seconds','minutes','hours'];
+  timeType = 'seconds';
+  isOpen = false;
+  maskOpen = false;
+
+  hourDetail = '00';
+  minuteDetail = '00';
+  secondDetail = '00';
+  timeDetail = '00:00:00';
+  periodTime :number;
+  StartTime = '';
+  sourcePat :'';
+  targetPat :'';
+  createResult = '';
+  jobStartTime : any;
+
+  Measures:object;
+
+  measure:string;
+  measureid:string;
+  ntAccount = 0;
+  newJob={
+        "sourcePattern":'',
+        "targetPattern":'',
+        "jobStartTime":0,
+        "interval":'',
+        "groupName":'',
+      }
+
+  private toasterService: ToasterService;
+
+
+  public visible = false;
+  public visibleAnimate = false;
+
+  public hide(): void {
+    this.visibleAnimate = false;
+    setTimeout(() => this.visible = false, 300);
+  }
+
+  public onContainerClicked(event: MouseEvent): void {
+    if ((<HTMLElement>event.target).classList.contains('modal')) {
+      this.hide();
+    }
+  }
+
+  changeTime(min,max,increase,time,type){
+  	time = parseInt(time);
+  	if(increase){
+          if(time==max)
+              time = min;
+          else time = time + 1;
+      }
+      else{
+          if(time==min)
+              time = max;
+          else time = time - 1;
+      }
+      if(time < 10)
+          time = '0' + time;
+      if(type==1)
+          this.hourDetail = time;
+      else if(type==2)
+          this.minuteDetail = time;
+      else
+          this.secondDetail = time;
+      this.timeDetail = this.hourDetail+':'+this.minuteDetail+':'+this.secondDetail;
+  }
+
+  showTime(){
+  	this.isOpen = !this.isOpen;
+    this.maskOpen = !this.maskOpen;
+  }
+
+  close(){
+  	this.isOpen = false;
+    this.maskOpen = false;
+  }
+
+  prev(form){
+  	history.back();
+  }
+
+  submit (jobForm) {
+      // jobForm.markAsPristine();
+      var period;
+      if(this.timeType=='minutes')
+          period = this.periodTime *60;
+      else if(this.timeType=='hours')
+          period = this.periodTime * 3600;
+      else period = this.periodTime;
+      var rule = '';
+      var time :number;
+      if(this.jobStartTime){
+        var year = this.jobStartTime.getFullYear();
+        var month = this.jobStartTime.getMonth() + 1;
+        var day = this.jobStartTime.getDate();
+        var startTime = year +'-'+ month + '-'+ day + ' '+ this.timeDetail;
+      }
+
+      time = Date.parse(startTime);
+      if(isNaN(time)){
+         this.toasterService.pop('error','Error!','Please input the right format of start time');
+          return false;
+      }
+      if (!jobForm.valid) {
+        this.toasterService.pop('error', 'Error!', 'Please complete the form!');
+        return false;
+      }
+
+      this.newJob={
+        "sourcePattern":this.sourcePat,
+        "targetPattern":this.targetPat,
+        "jobStartTime":time,
+        "interval":period,
+        "groupName":'BA',
+      },
+      this.visible = true;
+      setTimeout(() => this.visibleAnimate = true, 100);
+  }
+  save() {
+  	var date = new Date();
+  	var datastr = date.toString();
+    var month = date.getMonth()+1;
+    var timestamp = Date.parse(datastr);
+    var jobName = this.measure + '-BA-' + this.ntAccount + '-' + timestamp;
+    var addJobs = this.servicecService.config.uri.addJobs;
+    var newJob = addJobs + '?group=' + this.newJob.groupName + '&jobName=' + jobName + '&measureId=' + this.measureid;
+    this.http
+    .post(newJob, this.newJob)
+    .subscribe(data => {
+      this.createResult = data['results'];
+      this.hide();
+      this.router.navigate(['/jobs']);
+    },
+    err => {
+      console.log('Error when creating job');
+    });
+  }
+
+
+  onResize(event){
+   this.resizeWindow();
+  }
+
+  resizeWindow(){
+    var stepSelection = '.formStep';
+    $(stepSelection).css({
+        height: window.innerHeight - $(stepSelection).offset().top - $('#footerwrap').outerHeight()
+    });
+    $('fieldset').height($(stepSelection).height() - $(stepSelection + '>.stepDesc').height() - $('.btn-container').height() - 80);
+    $('.y-scrollable').css({
+        'max-height': $('fieldset').height()- $('.add-dataset').outerHeight()
+    });
+    $('#data-asset-pie').css({
+        height: $('#data-asset-pie').parent().width(),
+        width: $('#data-asset-pie').parent().width()
+    });
+  }
+
+  setHeight(){
+  	$('#md-datepicker-0').height(250);
+  }
+
+  ngOnInit() {
+    var allModels = this.servicecService.config.uri.allModels;
+    this.http.get(allModels).subscribe(data =>{
+      this.Measures = data;
+      this.measure = this.Measures[0].name;
+      this.measureid = this.Measures[0].id;
+    });
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/42ee8863/ui/angular/src/app/job/job.component.css
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/job/job.component.css b/ui/angular/src/app/job/job.component.css
new file mode 100644
index 0000000..1c68dfc
--- /dev/null
+++ b/ui/angular/src/app/job/job.component.css
@@ -0,0 +1,29 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+.table-striped > tbody > tr{
+     background-color: #1f1f1f; 
+}
+a{
+	color: white;
+}
+
+#pagination .pagination{
+	margin:20px 0 0 0 ;
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/42ee8863/ui/angular/src/app/job/job.component.html
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/job/job.component.html b/ui/angular/src/app/job/job.component.html
new file mode 100644
index 0000000..e2bb2de
--- /dev/null
+++ b/ui/angular/src/app/job/job.component.html
@@ -0,0 +1,192 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<div >
+    <p>
+        <a routerLink="/createjob" class="btn btn-primary btn-o btn-wide" >
+        <i class="fa fa-plus"></i> Create Job</a>
+    </p>
+
+    <div id="modelContainer">
+        <table class="table table-striped" [mfData]="results" #mf="mfDataTable" [mfRowsOnPage]="10">
+            <thead>
+            <tr style="background-color:#7D95CC">
+                <th st-ratio="15">Job Name</th>
+                <th st-ratio="15">Source Pattern</th>
+                <th st-ratio="15">Target Pattern</th>
+                <th st-ratio="15">Previous Fire Time</th>
+
+                <th st-ratio="20">Next Fire Time</th>
+                <th st-ratio="15">Trigger State</th>
+
+                <th st-ratio="5">Interval</th>
+                <th st-ratio="5">Action</th>
+            </tr>
+            </thead>
+            <tbody>
+            <tr *ngIf="!results">
+                <td colspan="7" style="text-align:center">No content!</td>
+            </tr>
+            </tbody>
+            <tbody *ngFor="let row of mf.data">
+            <tr (click) = "showInstances(row)">
+                <td [ngClass]="{accordion:true}" style="cursor: pointer;">
+                    <i *ngIf="!row.showDetail" class="fa fa-chevron-circle-right blue"></i>
+                    <i *ngIf="row.showDetail" class="fa fa-chevron-circle-down blue"></i>
+                    {{row.jobName}}
+                     -{{(row.createTime | date: 'yyyy/MM/dd HH:mm:ss') || 'N/A' }}
+                </td>
+                <td>{{row.sourcePattern}}</td>
+                <td>{{row.targetPattern}}</td>
+                <td [hidden]="row.previousFireTime!=-1">--/--/-- &nbsp;&nbsp;--:--</td> 
+                <td [hidden]="row.previousFireTime==-1">{{(row.previousFireTime | date: 'yyyy/MM/dd HH:mm:ss') || 'N/A' }}</td>
+                <td>{{(row.nextFireTime | date: 'yyyy/MM/dd HH:mm:ss') || 'N/A' }}</td>
+                <td>
+                    <span *ngIf='row.triggerState == "NORMAL"' class="normal">{{row.triggerState}}
+                    </span>
+                    <span *ngIf='row.triggerState != "NORMAL"' class = 'unnormal'>{{row.triggerState}}</span>
+                </td>
+                <td>{{row.interval}}</td>
+                <td>
+                    &nbsp;
+                    <a (click)="remove(row)" title="delete" style="text-decoration:none">
+                        <i class="fa fa-trash-o"></i>
+                    </a>
+                    &nbsp;
+                </td>
+            </tr>
+            <tr *ngIf="row.showDetail">
+                <td colspan="7" style="padding:20px 30px 10px 30px;">
+                    <table class="table table-striped" [mfData]="allInstances" #mf2="mfDataTable" [mfRowsOnPage]="10">
+                        <thead>
+                        <tr style="background-color:#7D95CC">
+                            <th style="width:30%" >AppID</th>
+                            <th style="width:25%" >Time</th>
+                            <th style="width:20%" >State</th>
+                        </tr>
+                        </thead>
+                        <tbody >
+                        <tr *ngIf="!allInstances">
+                            <td colspan="7" style="text-align:center">No content.</td>
+                        </tr>
+                        <tr *ngFor="let item of mf2.data" >
+                            <td><a href={{item.appUri}} target="_blank" style="color:white">{{item.appId}}</a></td>
+                            <td>{{item.timestamp | date: 'yyyy/MM/dd HH:mm:ss'}}</td>
+                            <td>{{item.state}}</td>
+                        </tr>                
+                        </tbody>
+                        <tfoot>
+                          <tr>
+                            <td class="text-center" colspan="8" style="background-color:#1f1f1f;" id="pagination">
+                              <mfBootstrapPaginator></mfBootstrapPaginator>
+                            </td>
+                          </tr>
+                        </tfoot>
+                    </table>
+                </td>
+            </tr>
+            </tbody>
+            <tfoot>
+            <tr>
+                <td colspan="8" class="text-right" >
+                    <mfBootstrapPaginator></mfBootstrapPaginator>
+                </td>
+            </tr>
+            </tfoot>
+        </table>
+    </div>
+    <div class="modal fade" id="deleteJobConfirmation" role="dialog" tabindex="-1" [ngClass]="{'in': visibleAnimate}" *ngIf="deletedRow"
+       [ngStyle]="{'display': visible ? 'block' : 'none', 'opacity': visibleAnimate ? 1 : 0}"
+       (click)="onContainerClicked($event)">
+        <div class="modal-dialog modal-xg modal-lg">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+                    <h4 class="modal-title">Delete the job with the below information?</h4>
+                </div>
+                <div class="modal-body">
+                    <!-- <ng-include src="'/pages/jobs/delete-confirm.html'"/> -->
+                    <div class="container-fluid" id="deleteContent" style="overflow:auto;">
+                      <div class="row">
+                          <h5 class="over-title margin-bottom-15">Basic information</h5>
+                      </div><!--//row-->
+                      <div class="row">
+                          <div  class="col-lg-12 col-md-12 col-sm-12">
+                              <div id="viewrule-definition" class="viewrule-content">
+                                  <div class="row">
+                                      <label class="col-md-4 col-lg-4 col-sm-4">
+                                          Job Name:
+                                      </label>
+                                      <div class="col-md-8 col-lg-8 col-sm-8 " style="color: #fff">
+                                          {{deletedRow.jobName}}
+                                      </div>
+                                  </div>
+                                  <div class="row">
+                                      <label class="col-md-4 col-lg-4 col-sm-4">
+                                          Source Pattern:
+                                      </label>
+                                      <div class="col-md-8 col-lg-8 col-sm-8 " style="color: #fff">
+                                          {{deletedRow.sourcePattern}}
+                                      </div>
+                                  </div>
+                                  <div class="row">
+                                      <label class="col-md-4 col-lg-4 col-sm-4">
+                                          Target Pattern:
+                                      </label>
+                                      <div class="col-md-8 col-lg-8 col-sm-8 " style="color: #fff">
+                                          {{deletedRow.targetPattern}}
+                                      </div>
+                                  </div>
+                                  <div class="row">
+                                      <label for="systemSelector" class="col-md-4 col-lg-4 col-sm-4">
+                                          Next Fire Time:
+                                      </label>
+                                      <div class="col-md-8 col-lg-8 col-sm-8 " style="color: #fff">
+                                          {{(deletedRow.nextFireTime | date: 'yyyy/MM/dd HH:mm:ss') || 'N/A' }}
+                                      </div>
+                                  </div>
+                                  <div class="row">
+                                      <label class="col-md-4 col-lg-4 col-sm-4">
+                                          Interval:
+                                      </label>
+                                      <div class="col-md-8 col-lg-8 col-sm-8" style="color: #fff">
+                                          {{deletedRow.interval}}
+                                      </div>
+                                  </div>
+                                  <div class="row">
+                                      <label class="col-md-4 col-lg-4 col-sm-4">
+                                          Group:
+                                      </label>
+                                      <div class="col-md-8 col-lg-8 col-sm-8" style="color: #fff">
+                                          {{deletedRow.groupName}}
+                                      </div>
+                                  </div>
+                              </div>
+                          </div>
+                      </div><!--//row-->
+                  </div>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-primary" (click)="confirmDelete()">Yes</button>
+                    <button type="button" class="btn btn-default" data-dismiss="modal" (click)="hide()">No</button>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/42ee8863/ui/angular/src/app/job/job.component.spec.ts
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/job/job.component.spec.ts b/ui/angular/src/app/job/job.component.spec.ts
new file mode 100644
index 0000000..2caf041
--- /dev/null
+++ b/ui/angular/src/app/job/job.component.spec.ts
@@ -0,0 +1,43 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { JobComponent } from './job.component';
+
+describe('JobComponent', () => {
+  let component: JobComponent;
+  let fixture: ComponentFixture<JobComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ JobComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(JobComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should be created', () => {
+    expect(component).toBeTruthy();
+  });
+});

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/42ee8863/ui/angular/src/app/job/job.component.ts
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/job/job.component.ts b/ui/angular/src/app/job/job.component.ts
new file mode 100644
index 0000000..5e4a2ea
--- /dev/null
+++ b/ui/angular/src/app/job/job.component.ts
@@ -0,0 +1,165 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+import { Component, OnInit } from '@angular/core';
+import { HttpClient} from '@angular/common/http';
+import { Ng2SmartTableModule ,LocalDataSource} from 'ng2-smart-table';
+import {DataTableModule} from "angular2-datatable";
+import {ServiceService} from '../service/service.service';
+
+import { DatePipe } from '@angular/common';
+import { Router} from "@angular/router";
+import * as $ from 'jquery';
+
+@Component({
+  selector: 'app-job',
+  templateUrl: './job.component.html',
+  providers:[ServiceService],
+  styleUrls: ['./job.component.css']
+})
+export class JobComponent implements OnInit {
+  // results:object[];
+  allInstances:any;
+  results:any;
+  source:LocalDataSource;
+  deletedBriefRow:object;
+  jobName:string;
+  public visible = false;
+  public visibleAnimate = false;
+  oldindex:number;
+
+
+  deletedRow : object;
+  sourceTable :string;
+  targetTable :string;
+  deleteId : string;
+  deleteIndex:number;
+  deleteGroup :string;
+  deleteJob :string;
+
+
+  
+  constructor(private http:HttpClient,private router:Router,public servicecService:ServiceService) { };
+
+  public hide(): void {
+    this.visibleAnimate = false;
+    setTimeout(() => this.visible = false, 300);
+  }
+
+  public onContainerClicked(event: MouseEvent): void {
+    if ((<HTMLElement>event.target).classList.contains('modal')) {
+      this.hide();
+    }
+  }
+  
+  // resultData = [{"jobName":"i-BA-0-1504837194000","measureId":"22","groupName":"BA","targetPattern":"YYYYMMdd-HH","triggerState":"NORMAL","nextFireTime":1505875500000,"previousFireTime":1504864200000,"interval":"300","sourcePattern":"YYYYMMdd-HH","jobStartTime":"1504800000000"},{"jobName":"i-BA-0-1504837194000","measureId":"22","groupName":"BA","targetPattern":"YYYYMMdd-HH","triggerState":"NORMAL","nextFireTime":1505875500000,"previousFireTime":1504864200000,"interval":"300","sourcePattern":"YYYYMMdd-HH","jobStartTime":"1504800000000"},{"jobName":"i-BA-0-1504837194000","measureId":"22","groupName":"BA","targetPattern":"YYYYMMdd-HH","triggerState":"NORMAL","nextFireTime":1505875500000,"previousFireTime":1504864200000,"interval":"300","sourcePattern":"YYYYMMdd-HH","jobStartTime":"1504800000000"}];
+  remove(row){
+    this.visible = true;
+    setTimeout(() => this.visibleAnimate = true, 100);
+    this.deletedRow = row;
+    this.deleteIndex = this.results.indexOf(row);
+    this.deletedBriefRow = row;
+    this.deleteGroup = row.groupName;
+    this.deleteJob = row.jobName;
+  }
+
+  confirmDelete(){
+    let deleteJob = this.servicecService.config.uri.deleteJob;
+    let deleteUrl = deleteJob + '?group=' + this.deleteGroup + '&jobName=' + this.deleteJob;
+    this.http.delete(deleteUrl).subscribe(data => {
+      let deleteResult:any = data;
+      console.log(deleteResult.code);
+      if(deleteResult.code==206){
+        var self = this;
+        self.hide();
+        setTimeout(function () {
+          self.results.splice(self.deleteIndex,1);
+          self.source.load(self.results);
+        },0);
+      }
+    },
+    err =>{
+        console.log('Error when deleting record');
+
+    });
+  };
+  
+  showInstances(row){
+    if(row.showDetail){
+        row.showDetail = !row.showDetail;     
+      return;
+    }
+    let index  = this.results.indexOf(row);
+    if (this.oldindex!=undefined &&this.oldindex != index){
+        this.results[this.oldindex].showDetail = false;}
+    let getInstances = this.servicecService.config.uri.getInstances;
+    let getInstanceUrl = getInstances+ '?group=' + 'BA' + '&jobName=' + row.jobName +'&page='+'0'+'&size='+'200';
+    this.http.get(getInstanceUrl).subscribe(data =>{      
+        row.showDetail = !row.showDetail;     
+        this.allInstances = data;   
+        setTimeout(function(){
+          console.log($('.pagination'));
+          $('.pagination').css("marginBottom","-10px");
+        },0);
+
+        // this.source = new LocalDataSource(this.allInstances);
+        // this.source.load(this.allInstances);
+    });
+    this.oldindex = index;
+  }
+
+  intervalFormat(second){
+     if(second<60)
+         return (second + 's');
+     else if(second<3600)
+     {
+         if(second%60==0)
+             return(second / 60 + 'min');
+         else 
+             return((second - second % 60) / 60 + 'min'+second % 60 + 's');
+     }
+     else 
+     {
+         if(second%3600==0)
+             return ( second / 3600 + 'h');
+         else
+         {
+             second = (second - second % 3600) / 3600 + 'h';
+             var s = second % 3600;
+             return ( second + (s-s%60)/60+'min'+s%60+'s');
+         }
+     }
+  }
+  
+  
+  ngOnInit():void {
+
+    var self = this;
+    let allJobs = this.servicecService.config.uri.allJobs;
+  	this.http.get(allJobs).subscribe(data =>{       
+        this.results = Object.keys(data).map(function(index){
+          let job = data[index];
+          job.showDetail = false;
+          job.interval = self.intervalFormat(job.interval);
+          return job;
+        });    
+    });
+   // this.results = this.resultData;
+
+  };
+}

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/42ee8863/ui/angular/src/app/login/login.component.css
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/login/login.component.css b/ui/angular/src/app/login/login.component.css
new file mode 100644
index 0000000..3ad96c3
--- /dev/null
+++ b/ui/angular/src/app/login/login.component.css
@@ -0,0 +1,83 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+@import url('../../../node_modules/bootstrap/dist/css/bootstrap.css');
+#content {
+    background-color: #1A237E;
+    background-position: center center;
+    background-repeat: no-repeat;
+    background-attachment: fixed;
+    background-size: cover;
+    height: 100vh;
+}
+hr {
+    margin-bottom: 30px;
+}
+
+@media (min-width: 992px) {
+
+    #content-row {
+        margin-top:12em;
+        margin-bottom:7em;
+    }
+
+    #bark-description {
+        display: block;
+    }
+
+    #bark-description-2 {
+        display: none;
+    }
+}
+
+@media (max-width:991px) {
+
+    #content-row {
+        margin-top:0em;
+        margin-bottom:0em;
+    }
+
+    #bark-description {
+        display: none;
+    }
+
+    #bark-description-2 {
+        margin-top: 3em;
+        display: block;
+    }
+}
+
+#bark-description p, #bark-description-2 p {
+    margin-left: 100px;
+    color: #ffffff;
+    font-size: 20px;
+}
+
+#content-row {
+    padding: 3em 0;
+    background-color: rgba(255, 255, 255, 0.2);
+}
+
+#loginMsg {
+    display: none;
+    background-color: #F1D7D7;
+    color: #A95252;
+    padding: 8px 12px;
+    border-radius: 4px;
+    text-align:center;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/42ee8863/ui/angular/src/app/login/login.component.html
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/login/login.component.html b/ui/angular/src/app/login/login.component.html
new file mode 100644
index 0000000..c150ca0
--- /dev/null
+++ b/ui/angular/src/app/login/login.component.html
@@ -0,0 +1,88 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<div *ngIf="!ntAccount" id="content" class="container-fluid">
+        <div class="row" id="content-row">
+
+            <div class="col-md-6 col-md-offset-1 col-xs-12">
+                <div id="bark-description">
+                    <h3>
+                        Data Quality Service Platform on eBay Cloud.
+                    </h3><br>
+                    <p>
+                        Automates your data quality validation
+                    </p><br>
+                    <p>
+                        Health monitoring, Profiling and detection
+                    </p><br>
+                    <p>
+                        Unified Visualization
+                    </p><br>
+                    <p>
+                        One set of tools to build data quality pipelines
+                    </p>
+                </div>
+            </div>
+
+            <div class="col-md-3 col-md-offset-1 col-xs-12">
+                <div id="login-form">
+                    <div style="text-align:center;margin-bottom:30px;">
+                        <img src="../assets/img/logo.png" class="img-rounded" style="width:80%;">
+                    </div>
+
+                    <input type="input" class="form-control" placeholder="username" autocomplete="on" style="margin-bottom:20px;" (focus)="focus($event)">
+
+                    <input type="password" class="form-control" placeholder="password" autocomplete="on" (keyup)="submit($event)" (focus)="focus($event)">
+
+                    <div class="checkbox">
+                    <label style="color:white;">
+                        <input type="checkbox" value="remember-me" checked>Remember me
+                    </label>
+                    </div>
+
+                    <button class="btn btn-default btn-large btn-block" id="login-btn" (click)="login()" style="margin-bottom: 20px;">Log in</button>
+
+                    <div id="loginMsg">Login failed. Try again.</div>
+                </div>
+            </div>
+
+            <div class="col-xs-12">
+                <div id="bark-description-2">
+                    <h3>
+                        Data Quality Service Platform on the eBay Cloud.
+                    </h3><br>
+                    <p>
+                        Automates your data quality validation
+                    </p><br>
+                    <p>
+                        Health monitoring, Profiling and detection
+                    </p><br>
+                    <p>
+                        Unified Visualization
+                    </p><br>
+                    <p>
+                        One set of tools to build data quality pipelines
+                    </p>
+                </div>
+            </div>
+        </div>
+
+</div>
+
+
+

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/42ee8863/ui/angular/src/app/login/login.component.spec.ts
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/login/login.component.spec.ts b/ui/angular/src/app/login/login.component.spec.ts
new file mode 100644
index 0000000..db3a317
--- /dev/null
+++ b/ui/angular/src/app/login/login.component.spec.ts
@@ -0,0 +1,43 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { LoginComponent } from './login.component';
+
+describe('LoginComponent', () => {
+  let component: LoginComponent;
+  let fixture: ComponentFixture<LoginComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ LoginComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(LoginComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should be created', () => {
+    expect(component).toBeTruthy();
+  });
+});

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/42ee8863/ui/angular/src/app/login/login.component.ts
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/login/login.component.ts b/ui/angular/src/app/login/login.component.ts
new file mode 100644
index 0000000..632a18f
--- /dev/null
+++ b/ui/angular/src/app/login/login.component.ts
@@ -0,0 +1,31 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+  selector: 'app-login',
+  templateUrl: './login.component.html',
+  styleUrls: ['./login.component.css']
+  // providers:[ServiceService]
+})
+export class LoginComponent implements OnInit {
+	ngOnInit(){
+
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/42ee8863/ui/angular/src/app/measure/create-measure/ac/ac.component.css
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/measure/create-measure/ac/ac.component.css b/ui/angular/src/app/measure/create-measure/ac/ac.component.css
new file mode 100644
index 0000000..38ec745
--- /dev/null
+++ b/ui/angular/src/app/measure/create-measure/ac/ac.component.css
@@ -0,0 +1,119 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+@import url('../../../../../node_modules/angular2-toaster/toaster.css');
+@import url('../../measure.component.css');
+
+div.tree div.tree-children::before,
+div.tree::before {
+    content: "";
+    position: absolute;
+    border-left: 1px dotted #23527c;
+    height: 100%;
+    top: -14px;
+    left: 12px
+}
+
+div.tree {
+    padding-left: 0;
+    margin-left: -5px
+}
+tree-root{
+    color: #999; 
+}
+
+div.tree div.tree-children {
+    position: relative;
+    padding-left: 0;
+    margin-left: 16px
+}
+
+div.tree div.tree-children::before {
+    left: 5px
+}
+
+div.tree treenode>div>.node-wrapper {
+    margin-left: 24px
+}
+
+div.tree treenode>div>.node-wrapper>.node-content-wrapper {
+    margin-left: 4px
+}
+
+div.tree treenode>div.tree-node-leaf>.node-wrapper {
+    margin-left: 0
+}
+
+div.tree treenode>div::before {
+    content: "";
+    position: absolute;
+    border-bottom: 1px dotted #23527c;
+    width: 7px;
+    margin-top: 12px;
+    left: 7px
+}
+
+div.tree treenode>div .toggle-children-wrapper {
+    width: 13px;
+    height: 13px;
+    border: 1px solid #23527c;
+    position: absolute;
+    left: 15px;
+    margin-top: 5px;
+    margin-left: 0;
+    display: inline-block;
+    background-color: #fff;
+    z-index: 1
+}
+
+div.tree treenode>div .toggle-children-wrapper::before {
+    content: "";
+    display: inline-block;
+    width: 7px;
+    border-top: 1px solid #23527c;
+    position: absolute;
+    top: 5px;
+    left: 2px
+}
+
+div.tree treenode>div .toggle-children-wrapper.toggle-children-wrapper-collapsed::after {
+    content: "";
+    display: inline-block;
+    height: 7px;
+    border-left: 1px solid #23527c;
+    position: absolute;
+    top: 2px;
+    left: 5px
+}
+
+div.tree treenode>div .toggle-children-wrapper .toggle-children {
+    display: none
+}
+
+div.tree treenode>div .node-content-wrapper {
+    margin-left: 4px
+}
+
+div.tree>treenode>div::before {
+    left: 14px
+}
+
+div.tree>treenode>div>.node-wrapper>treenodeexpander>.toggle-children-wrapper {
+    left: 22px
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/42ee8863/ui/angular/src/app/measure/create-measure/ac/ac.component.html
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/measure/create-measure/ac/ac.component.html b/ui/angular/src/app/measure/create-measure/ac/ac.component.html
new file mode 100644
index 0000000..57d19cd
--- /dev/null
+++ b/ui/angular/src/app/measure/create-measure/ac/ac.component.html
@@ -0,0 +1,467 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<div class="container-fluid" (window:resize)="onResize($event)">
+  <div class="row">
+    <h5 class="over-title margin-bottom-15">Create Measure</h5>
+  </div>
+  <div class="row">
+    <form name="Form" id="form" (ngSubmit)="submit(acForm)" #acForm="ngForm"  novalidate>
+      <div id="wizard" class="swMain" >
+        <ul>
+          <li (click)="goTo(1)" >
+            <a [ngClass]="{'selected' : currentStep >= 1, 'done' : currentStep > 1}" class="selected">
+              <div class="stepNumber">
+                1
+              </div>
+              <span class="stepDesc text-small"> Choose Source </span>
+            </a>
+          </li>
+          <li (click)="goTo(2)">
+            <a [ngClass]="{'selected' : currentStep >= 2, 'done' : currentStep > 2}" class="" style="">
+              <div class="stepNumber">
+                2
+              </div>
+              <span class="stepDesc text-small"> Choose Target </span>
+            </a>
+          </li>
+          <li (click)="goTo(3)">
+            <a [ngClass]="{'selected' : currentStep >= 3, 'done' : currentStep > 3}">
+              <div class="stepNumber">
+                3
+              </div>
+              <span class="stepDesc text-small"> Mapping Source and Target </span>
+            </a>
+          </li>
+          <li (click)="goTo(4)">
+            <a [ngClass]="{'selected' : currentStep >= 4, 'done' : currentStep > 4}">
+              <div class="stepNumber">
+                4
+              </div>
+              <span class="stepDesc text-small"> Configuration </span>
+            </a>
+          </li>
+        </ul>
+      </div>
+
+        <div id="step-1" *ngIf="currentStep == 1" class="formStep" >
+          <label class="stepDesc">This step let you choose the single source of truth for data quality comparision with target. Currently you can only select the attributes from one schema</label>
+          <div class="container-fluid">
+           
+            <div class="col-md-4 col-lg-4 col-sm-4">
+              <fieldset>
+                <legend>Please select schema</legend>
+                <tree-root [nodes]="nodeList" [options]="options"></tree-root>
+              </fieldset>
+            </div>
+            <div class="col-md-8 col-lg-8 col-sm-8">
+              <fieldset>
+                <legend>
+                  Select attributes
+                </legend>
+                <div class="y-scrollable">
+                  <div>
+                    <label>View schema:</label> 
+                    <i
+                    style="color:#fff;font-weight: bold;">{{currentDB}}.{{currentTable}}
+                    </i>
+                  </div>
+                  <div>
+                    <table class="table table-striped">
+                      <thead>
+                      <tr style="background-color:#7D95CC">
+                        <th><input type="checkbox" (click)="toggleAll()" [checked]="selectedAll"
+                        /></th>
+                        <th>Column Name</th>
+                        <th>Type</th>
+                        <th>Comment</th>
+                      </tr>
+                      </thead>
+                      <tbody>
+                      <tr *ngIf="!schemaCollection || schemaCollection.length == 0">
+                        <td colspan="5" style="text-align:center" ><span class="highlight">Please select a schema from the left tree first</span></td>
+                      </tr>
+                      <tr *ngFor="let row of schemaCollection">
+                        <td>
+                        <input type="checkbox" (click)='toggleSelection(row)' [checked]="row.selected" value={{row.name}}
+                        />
+                        </td>
+                        <td>{{row.name}}</td>
+                        <td>{{row.type}}</td>
+                        <td>{{row.comment}}</td>
+                      </tr>
+                      </tbody>
+                    </table>
+                  </div>
+                </div>
+              </fieldset>
+            </div>
+            <div class="form-group btn-container">
+              <toaster-container></toaster-container>
+              <button class="btn btn-primary btn-o next-step btn-wide pull-right" (click)="next(Form)">
+                Next <i class="fa fa-arrow-circle-right"></i>
+              </button>
+            </div>
+          </div>
+        </div>
+        <div id="step-2" *ngIf="currentStep == 2" class="formStep" >
+          <label class="stepDesc">This step let you choose the target for data quality comparision with source</label>
+          <div class="container-fluid">
+            <div class="col-md-4 col-lg-4 col-sm-4">
+              <fieldset>
+                <legend>Please select schema</legend>
+                <tree-root [nodes]="nodeListTarget" [options]="targetOptions"></tree-root>
+              </fieldset>
+            </div>
+            <div class="col-md-8 col-lg-8 col-sm-8">
+              <fieldset>
+                <legend>
+                  Select attributes
+                </legend>
+                <div class="y-scrollable">
+                  <div>
+                    <label>View schema:</label> 
+                    <i style="color:#fff;font-weight: bold;">{{currentDBTarget}}.{{currentTableTarget}}</i>
+                  </div>
+                  <div>
+                    <table st-table="schemaCollectionTarget" class="table table-striped">
+                      <thead>
+                      <tr style="background-color:#7D95CC">
+                        <th><input type="checkbox" (click)="toggleAllTarget()" [checked]="selectedAllTarget"  /></th>
+                        <th>Column Name</th>
+                        <th>Type</th>
+                        <th>Comment</th>
+                      </tr>
+                      </thead>
+                      <tbody>
+                      <tr *ngIf="!schemaCollectionTarget || schemaCollectionTarget.length == 0">
+                        <td colspan="5" style="text-align:center" ><span class="highlight">Please select a schema from the left tree first</span></td>
+                      </tr>
+                      <tr *ngFor="let row of schemaCollectionTarget">
+                        <td>
+                        <input type="checkbox" (click)='toggleSelectionTarget(row)'  [checked]="row.selected"/>
+                        </td>
+                        <td>{{row.name}}</td>
+                        <td>{{row.type}}</td>
+                        <td>{{row.comment}}</td>
+                      </tr>
+                      </tbody>
+                    </table>
+                  </div>
+                </div>
+              </fieldset>
+            </div>
+            <div class="form-group btn-container" >
+              <button class="btn btn-primary btn-o back-step btn-wide pull-left" (click)="prev(Form)">
+                <i class="fa fa-arrow-circle-left"></i> Back
+              </button>
+              <toaster-container></toaster-container>
+              <button class="btn btn-primary btn-o next-step btn-wide pull-right" (click)="next(Form)">
+                Next <i class="fa fa-arrow-circle-right"></i>
+              </button>
+            </div>
+          </div>
+        </div>
+
+        <div id="step-3" *ngIf="currentStep == 3" class="formStep" >
+          <label class="stepDesc">This step let you map the target data fields to source fields, you can choose the related fields from dropdown list of source</label>
+          <div class="container-fluid">
+            <div class="col-md-12 col-lg-12 col-sm-12">
+              <fieldset>
+                <legend>
+                  Map the fields
+                </legend>
+
+                <div class="y-scrollable">
+
+                  <div class="container col-md-12 col-lg-12 col-sm-12">
+                    <table class="table table-striped">
+                      <thead>
+                      <tr style="background-color:#7D95CC;font-size:20px">
+                        <th style="width:40%;">Target Fields</th>
+                        <th style="width:10%;text-align:center">Map To</th>
+                        <th style="width:40%;text-align:center">Source Fields</th>
+                      </tr>
+                      </thead>
+                      <tbody>
+                      <tr *ngFor="let item of selectionTarget; let i=index" >
+                        <td>{{currentDBTarget}}.{{currentTableTarget}}.{{item}}</td>
+                        <td style="text-align:center;">
+                          <select class="form-control" style="background:#00FFFF;font-weight:bold" id="mapRule" name='mapRule-{{i}}' [(ngModel)]="matches[i]" value="matches[i]">
+                            <option *ngFor="let func of matchFunctions">{{func}}</option>
+                          </select>
+                        </td>
+                        <td>
+                          <select class="form-control" [(ngModel)] = 'mappings[i]' name="mappings{{i}}"
+                          (ngModelChange)="addMapping($event,i)" value="mappings[i]">
+                            <option  
+                            *ngFor="let itemSrc of selection"  
+                            [ngValue]="itemSrc"   
+                        >
+                            {{currentDB}}.{{currentTable}}.{{itemSrc}}</option>
+                          </select>
+                        </td>
+                      </tr>
+                      </tbody>
+                    </table>
+                    <p>
+                      <label style="color:#B2C831">Accuracy Calculation Formula as Below:</label>
+                    </p>
+
+                    <div class="col-md-12 col-lg-12 col-sm-12" style="color:#fff;font-size:16px;display: flex;align-items: center">
+
+                      <div class="" style="text-align:right;display:block;float:left;width:20%;">
+                        Accuracy Rate(%) =
+                      </div>
+                      <div class="" style="text-align:center;display:block;float:left;margin:0 10px 0 10px">
+                        <div class="formula-text-up" style="border-bottom:1px solid;">
+                          Total Count of Matched records between <span class="badge">{{selectionTarget.length}}</span> <span style="color:green;">{{currentTableTarget}}</span>  and <span class="badge">{{mappings.length}}
+                          </span> <span style="color:green;">{{currentTable}}</span>  fields
+                        </div>
+                        <div>
+                          Total Count of records in <span style="color:green;font-weight:bold;">{{currentDB}}.{{currentTable}}</span>
+                        </div>
+                      </div>
+                      <div class="" style="text-align:left;display:block;float:left;width:10%;">
+                        x 100%
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </fieldset>
+            </div>
+
+            <div class="form-group btn-container" >
+              <button class="btn btn-primary btn-o back-step btn-wide pull-left" (click)="prev(Form)">
+                <i class="fa fa-arrow-circle-left"></i> Back
+              </button>
+              <toaster-container></toaster-container>
+              <button class="btn btn-primary btn-o next-step btn-wide pull-right" (click)="next(Form)">
+                Next <i class="fa fa-arrow-circle-right"></i>
+              </button>
+            </div>
+          </div>
+        </div>
+
+        <div id="step-4" *ngIf="currentStep == 4" class="formStep" >
+          <label class="stepDesc">Please setup the measure required information</label>
+          <div class="container-fluid">
+            <div class="col-md-12 col-lg-12 col-sm-12">
+              <fieldset>
+                <legend>
+                  Required Information
+                </legend>
+                <div class="y-scrollable">
+                  <div class="col-md-12 col-lg-12 col-sm-12">
+                    <div class="form-group" [ngClass]="{'has-error':acName.dirty&&acName.invalid, 'has-success':acName.valid}">
+                      <label class="col-md-2 col-lg-2 col-sm-2 control-label">
+                        Measure Name<span class="symbol required"></span>:
+                      </label>
+
+                      <div class="col-md-10 col-lg-10 col-sm-10 ">
+                        <input type="text" class="form-control" [(ngModel)]="name" name="acName" #acName="ngModel" placeholder="Please input the measure name" required pattern="^[a-zA-Z0-9_-]*$" id="acName">
+                        <span class="error text-small block " 
+                        *ngIf="acName.dirty && (acName.errors?.required)">
+                        Measure Name is required</span>
+                        <span class="error text-small block " *ngIf="acName.dirty && (acName.errors?.pattern)">Only letter, number, "-" and "_" are allowed</span>
+                      </div>
+                    </div>
+                  </div>
+                  <div class="col-md-12 col-lg-12 col-sm-12">
+                    <div class="form-group">
+                      <label class="col-md-2 col-lg-2 col-sm-2 control-label">
+                        Measure Description:
+                      </label>
+
+                      <div class="col-md-10 col-lg-10 col-sm-10 ">
+                        <input type="text" class="form-control" [(ngModel)]="desc" placeholder="Please input detailed description of your measure" name="desc">
+                      </div>
+                    </div>
+                  </div>
+                  <div class="col-md-12 col-lg-12 col-sm-12">
+                    <div class="form-group">
+                      <label for="typeSelector" class="col-md-2 col-lg-2 col-sm-2 control-label">
+                        Measure Type:
+                      </label>
+                      <div class="col-md-10 col-lg-10 col-sm-10 ">
+                        <select id="typeSelector" class="form-control" [(ngModel)]="type"  disabled required name="type">
+                          <!-- <option *ngFor="let row of measureTypes" value="{{$index}}" >{{type}}</option> -->
+                          <option>{{type}}</option>
+                        </select>
+                      </div>
+                    </div>
+                  </div>
+                  <div class="col-md-12 col-lg-12 col-sm-12">
+                    <div class="form-group">
+                      <label for="systemSelector" class="col-md-2 col-lg-2 col-sm-2 control-label">
+                        Organization:
+                      </label>
+                      <div class="col-md-10 col-lg-10 col-sm-10 ">
+                        <input type="text" id="systemSelector" class="form-control" [(ngModel)]="org"  required ng-pattern="'([0-9a-zA-Z\\_\\-])+'" name="org">
+                      </div>
+                    </div>
+                  </div>
+                  <div class="col-md-12 col-lg-12 col-sm-12">
+                    <div class="form-group">
+                      <label class="col-md-2 col-lg-2 col-sm-2 control-label">
+                        DataAsset:
+                      </label>
+                      <div class="col-md-10 col-lg-10 col-sm-10">
+                        <input type="text" class="form-control" name="DataAsset"
+                        value="{{currentTable}},{{currentTableTarget}}" disabled>
+                      </div>
+                    </div>
+                  </div>
+                  <div class="col-md-12 col-lg-12 col-sm-12">
+                    <div class="form-group">
+                      <label class="col-md-2 col-lg-2 col-sm-2 control-label">
+                        Owner:
+                      </label>
+                      <div class="col-md-10 col-lg-10 col-sm-10">
+                        <input type="text"  class="form-control" name="owner" disabled
+                        [(ngModel)]="owner" >
+                      </div>
+                    </div>
+                  </div>
+                </div>
+                <div style="color:#b2c831">
+                  <p>
+                    <i class="fa fa-info-circle"></i> After submitted, please go to "<a class="bark-link" routerLink="/measures">Measures</a>" to check the measure status
+                  </p>
+                </div>
+
+              </fieldset>
+            </div>
+
+            <div class="form-group btn-container" >
+              <button class="btn btn-primary btn-o back-step btn-wide pull-left" (click)="prev(Form)">
+                <i class="fa fa-arrow-circle-left"></i> Back
+              </button>
+              <toaster-container></toaster-container>
+              <button type="submit" class="btn btn-primary btn-o next-step btn-wide pull-right">
+                Submit
+              </button>
+            </div>
+          </div>
+        </div>
+
+        <div class="modal fade" id="confirm" role="dialog" #modal tabindex="-1" [ngClass]="{'in': visibleAnimate}"
+       [ngStyle]="{'display': visible ? 'block' : 'none', 'opacity': visibleAnimate ? 1 : 0}"
+       (click)="onContainerClicked($event)">
+          <div class="modal-dialog modal-xg modal-lg">
+            <div class="modal-content">
+              <div class="modal-header">
+                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+                <h4 class="modal-title">Save the measure with the below information?</h4>
+              </div>
+              <div class="modal-body">
+                <div class="container-fluid" id="viewruleContent" style="overflow:auto;">
+                  <div class="row">
+                    <h5 class="over-title margin-bottom-15">Basic information</h5>
+                  </div>
+                  <div class="row">
+                    <div  class="col-lg-12 col-md-12 col-sm-12">
+                      <div id="viewrule-definition" class="viewrule-content">
+                        <div class="row">
+                          <label class="col-md-4 col-lg-4 col-sm-4">
+                            Measure Name:
+                          </label>
+                          <div class="col-md-8 col-lg-8 col-sm-8 ">
+                            {{name}}
+                          </div>
+                        </div>
+                        <div class="row">
+                          <label class="col-md-4 col-lg-4 col-sm-4">
+                            Measure Description:
+                          </label>
+                          <div class="col-md-8 col-lg-8 col-sm-8 ">
+                            {{desc}}
+                          </div>
+                        </div>
+                        <div class="row">
+                          <label class="col-md-4 col-lg-4 col-sm-4">
+                            Measure Type:
+                          </label>
+                          <div class="col-md-8 col-lg-8 col-sm-8 ">
+                            {{type}}
+                          </div>
+                        </div>
+                        <div class="row">
+                          <label for="systemSelector" class="col-md-4 col-lg-4 col-sm-4">
+                            Organization:
+                          </label>
+                          <div class="col-md-8 col-lg-8 col-sm-8 ">
+                            {{org}}
+                          </div>
+                        </div>
+                        <div class="row">
+                          <label class="col-md-4 col-lg-4 col-sm-4">
+                            DataAsset:
+                          </label>
+                          <div class="col-md-8 col-lg-8 col-sm-8">{{currentTable}},{{currentTableTarget}}
+                          </div>
+                        </div>
+                        <div class="row">
+                          <label class="col-md-4 col-lg-4 col-sm-4">
+                            Owner:
+                          </label>
+                          <div class="col-md-8 col-lg-8 col-sm-8" >
+                            {{owner}}
+                          </div>
+                        </div>
+                      </div>
+                    </div>
+                  </div>
+                  <br/>
+                  <h5 class="row">Mapping rules</h5>
+                  <div class="row">
+                    <p>{{rules}}</p>
+                    <p>
+                      <label style="color:#B2C831">Accuracy Calculation Formula as Below:</label>
+                    </p>
+                    <div class="col-md-12 col-lg-12 col-sm-12" style="color:#fff;font-size:16px;display: flex;                align-items: center">
+                      <div class="" style="text-align:right;display:block;float:left;width:20%;">
+                        Accuracy Rate(%) =
+                      </div>
+                      <div class="" style="text-align:center;display:block;float:left;margin:0 10px 0 10px">
+                        <div class="formula-text-up" style="border-bottom:1px solid;">
+                          Total Count of Matched records between <span class="badge">{{selectionTarget.length}}</span> <span style="color:green;">{{currentTableTarget}}</span>  and <span class="badge">{{mappings.length}}
+                          </span> <span style="color:green;">{{currentTable}}</span>  fields
+                        </div>
+                        <div>
+                          Total Count of records in <span style="color:green;font-weight:bold;">{{currentDB}}.{{currentTable}}</span>
+                        </div>
+                      </div>
+                      <div class="" style="text-align:left;display:block;float:left;width:10%;">
+                        x 100%
+                      </div>
+                    </div>
+                  </div>
+                </div>
+
+              </div>
+              <div class="modal-footer">
+                <button type="button" class="btn btn-default" (click)="hide()">Cancel</button>
+                <button type="button" class="btn btn-primary" (click)="save()">Save</button>
+              </div>
+            </div>
+          </div>
+        </div>
+    </form>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/42ee8863/ui/angular/src/app/measure/create-measure/ac/ac.component.spec.ts
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/measure/create-measure/ac/ac.component.spec.ts b/ui/angular/src/app/measure/create-measure/ac/ac.component.spec.ts
new file mode 100644
index 0000000..ee0762d
--- /dev/null
+++ b/ui/angular/src/app/measure/create-measure/ac/ac.component.spec.ts
@@ -0,0 +1,43 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { AcComponent } from './ac.component';
+
+describe('AcComponent', () => {
+  let component: AcComponent;
+  let fixture: ComponentFixture<AcComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ AcComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(AcComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should be created', () => {
+    expect(component).toBeTruthy();
+  });
+});