http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/c1b90c1a/ui/angular/src/app/app.component.html
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/app.component.html 
b/ui/angular/src/app/app.component.html
index da8f7e2..d5b2951 100644
--- a/ui/angular/src/app/app.component.html
+++ b/ui/angular/src/app/app.component.html
@@ -31,7 +31,7 @@ under the License.
       </div>
       <div class="collapse navbar-collapse" id="navbar-collapse">
         <ul class="nav navbar-nav">
-          <li><a routerLink="/health" routerLinkActive="active" 
class="changecolor">Health</a></li>
+          <li><a routerLink="/health" class="changecolor">Health</a></li>
           <li><a routerLink="/measures" class="highlight">Measures</a></li>
           <li><a routerLink="/jobs">Jobs</a></li>
           <li><a routerLink="/mydashboard">My Dashboard</a></li>

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/c1b90c1a/ui/angular/src/app/app.module.ts
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/app.module.ts b/ui/angular/src/app/app.module.ts
index 4815e55..44ea4a1 100644
--- a/ui/angular/src/app/app.module.ts
+++ b/ui/angular/src/app/app.module.ts
@@ -39,7 +39,7 @@ import { MeasureDetailComponent } from 
'./measure/measure-detail/measure-detail.
 import { MetricComponent } from './metric/metric.component';
 import { DetailMetricComponent } from 
'./metric/detail-metric/detail-metric.component';
 import { DataassetComponent } from './dataasset/dataasset.component';
-import { CreateJobComponent } from './job/create-job/create-job.component';
+import { BatchComponent } from './job/create-job/batch/batch.component';
 import { AcComponent} from './measure/create-measure/ac/ac.component';
 import { PrComponent } from './measure/create-measure/pr/pr.component';
 import { PubComponent } from './measure/create-measure/pub/pub.component';
@@ -50,8 +50,10 @@ import { TruncatePipe} from './sidebar/truncate.pipe';
 import { ConfigurationComponent } from 
'./measure/create-measure/configuration/configuration.component';
 import { NouisliderModule } from 'ng2-nouislider';
 import { HttpService } from './service/http.service';
-import {LoaderService} from './loader/loader.service';
+import { LoaderService } from './loader/loader.service';
 import { LoaderComponent } from './loader/loader.component';
+import { JobDetailComponent } from './job/job-detail/job-detail.component';
+import { StreamingComponent } from 
'./job/create-job/streaming/streaming.component';
 
 
 const appRoutes: Routes = [
@@ -73,11 +75,20 @@ const appRoutes: Routes = [
   },
   {
     path: 'jobs',
-    component: JobComponent,
+    component: JobComponent
   },
   {
-    path: 'createjob',
-    component: CreateJobComponent,
+    path: 'job/:id',
+    component: JobDetailComponent
+  },
+  {
+    path: 'createjob/batch',
+    component: BatchComponent
+
+  },
+  {
+    path: 'createjob/streaming',
+    component: StreamingComponent
 
   },
   {
@@ -137,7 +148,7 @@ const appRoutes: Routes = [
     MetricComponent,
     DetailMetricComponent,
     DataassetComponent,
-    CreateJobComponent,
+    BatchComponent,
     AcComponent,
     PrComponent,
     PubComponent,
@@ -145,7 +156,9 @@ const appRoutes: Routes = [
     RuleComponent,
     TruncatePipe,
     ConfigurationComponent,
-    LoaderComponent
+    LoaderComponent,
+    JobDetailComponent,
+    StreamingComponent
   ],
   imports: [
     BrowserModule,

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/c1b90c1a/ui/angular/src/app/health/health.component.ts
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/health/health.component.ts 
b/ui/angular/src/app/health/health.component.ts
index 8ea6c55..c0fe83b 100644
--- a/ui/angular/src/app/health/health.component.ts
+++ b/ui/angular/src/app/health/health.component.ts
@@ -167,7 +167,7 @@ export class HealthComponent implements OnInit {
     this.resizeTreeMap();
     this.chartOption = option;
   }
-  
+
   checkvalue(job){
     return job.metricValues.length === 0;
   }
@@ -184,7 +184,7 @@ export class HealthComponent implements OnInit {
       for (let mesName in this.mesWithJob) {
         var jobs = this.mesWithJob[mesName];
         if (
-          jobs.length > 0 && jobs[0].type == "accuracy"
+          jobs.length > 0 && jobs[0].type == "ACCURACY"
         ) {
           var jobs = this.mesWithJob[mesName];
           var node = null;
@@ -192,7 +192,7 @@ export class HealthComponent implements OnInit {
           node.name = mesName;
           node.dq = 0;
           node.metrics = [];
-          node.type = "accuracy";
+          node.type = "ACCURACY";
           for (let i = 0; i < jobs.length; i++) {
             if (jobs[i].metricValues.length != 0) {
               var metricNode = {
@@ -235,4 +235,4 @@ export class HealthComponent implements OnInit {
 
     // })
   }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/c1b90c1a/ui/angular/src/app/job/create-job/batch/batch.component.css
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/job/create-job/batch/batch.component.css 
b/ui/angular/src/app/job/create-job/batch/batch.component.css
new file mode 100644
index 0000000..6288f12
--- /dev/null
+++ b/ui/angular/src/app/job/create-job/batch/batch.component.css
@@ -0,0 +1,90 @@
+/*
+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.
+*/
+.job {
+    font-size: 20px;
+}
+
+.info {
+    color: #b2c831;
+}
+
+.btn-o {
+    background: 0 0 !important;
+}
+
+legend {
+    background-color: #000;
+    color: #007aff;
+    left: 10px;
+    padding: 0 10px;
+    position: absolute;
+    top: -12px;
+    font-weight: 400;
+    color: #fff;
+    margin-bottom: 20px;
+    font-size: 21px;
+    width: auto !important;
+    border: none !important;
+}
+fieldset {
+    border: 1px solid #e6e8e8;
+    border-radius: 5px;
+    margin: 20px 0;
+    padding: 25px;
+    position: relative;
+    min-width: 0;
+    display: block;
+    height: 320px;
+}
+
+.formStep {
+    background-color: #000;
+}
+.setcolor {
+    color: #b2c831;
+}
+.setgrey {
+    color: #888888;
+}
+.mat-calendar-table {
+    height: 400px;
+}
+.mat-datepicker-content {
+    overflow-y: auto;
+}
+
+#md-datepicker-0 {
+    height: 250px;
+}
+
+.center {
+    margin-left: 5%;
+}
+
+.range {
+    display: block;
+    width: 20%;
+    height: 10%;
+    margin-bottom: 5px;
+}
+.setborder {
+    border: 2px solid;
+    border-radius: 5px;
+    width: 8%;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/c1b90c1a/ui/angular/src/app/job/create-job/batch/batch.component.html
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/job/create-job/batch/batch.component.html 
b/ui/angular/src/app/job/create-job/batch/batch.component.html
new file mode 100644
index 0000000..86b82e3
--- /dev/null
+++ b/ui/angular/src/app/job/create-job/batch/batch.component.html
@@ -0,0 +1,179 @@
+<!--
+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="jobForm" 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">
+                      Job 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)]="jobname" name="jobName" #jobName="ngModel" placeholder="Please 
input the job name" required pattern="^[a-zA-Z0-9_-]*$" id="jobName">
+                      <span class="error text-small block " 
*ngIf="jobName.dirty && (jobName.errors?.required)">
+                        Job Name is required</span>
+                      <span class="error text-small block " 
*ngIf="jobName.dirty && (jobName.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 for="measureSelector" 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 ">
+                      <select id="measureSelector" class="form-control" 
ngControl="name" required name="measure.name" [(ngModel)]="measure" 
(ngModelChange)="onChange($event)">
+                        <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 for="measureSelector" class="col-md-2 col-lg-2 
col-sm-2 control-label">
+                      Cron Expression<span class="symbol required"></span>:
+                    </label>
+                    <div class="col-md-10 col-lg-10 col-sm-10 ">
+                      <input class="form-control" ngControl="name" required 
[(ngModel)]="cronExp" name="cronExp">
+                    </div>
+                  </div>
+                </div>
+                <div *ngFor="let connector of this.dropdownList; let i=index">
+                  <div>
+                    <label style="padding-left: 30px;padding-top: 10px;">
+                      please select data range for {{connector.name}}
+                    </label>
+                  </div>
+                  <p style="margin-left:60px" class="setcolor">
+                    <i class="fa fa-info-circle"></i> One step means a 
partition size,and {{connector.name}} partition size = {{connector.size}}
+                  </p>
+                  <div class="col-md-11 col-lg-11 col-sm-11 center">
+                    begin :
+                    <input type="number" class="setborder" value="{{ 
someKeyboard[i][0] }}" [(ngModel)]="someKeyboard[i][0]" max="0" 
name="begin{{i}}" (ngModelChange)="changeRange(index,someKeyboard[i][0],i)"> 
end :
+                    <input type="number" class="setborder" max="0" value="{{ 
someKeyboard[i][1] }}" [(ngModel)]="someKeyboard[i][1]" name="end{{i}}" 
(ngModelChange)="changeRange(1,$event,i)">
+                  </div>
+                  <nouislider class="col-md-11 col-lg-11 col-sm-11 center" 
id="slider{{i}}" #sliderRef name="slider{{i}}" [config]="someKeyboardConfig[i]" 
[(ngModel)]="someKeyboard[i]" (ngModelChange)="rangeChange($event,i)" 
(keyup)="blinkKeyupLabel()" (keydown)="blinkKeydownLabel()" 
style="margin-bottom: 5rem"></nouislider>
+                </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)="prev()">
+              <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" (click)="submit(jobForm)">
+              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">
+              <div class="container-fluid" id="viewJobContent" 
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 " style="color: 
#fff">
+                          {{measure}}
+                          <!-- {{Measures}} -->
+                        </div>
+                      </div>
+                      <div class="row">
+                        <label class="col-md-4 col-lg-4 col-sm-4">
+                          Cron Expression:
+                        </label>
+                        <div class="col-md-8 col-lg-8 col-sm-8 " style="color: 
#fff">
+                          {{cronExp}}
+                        </div>
+                      </div>
+                      <div *ngFor="let connector of this.dropdownList; let 
i=index">
+                        <div class="row">
+                          <label class="col-md-12 col-lg-12 col-sm-12">
+                            {{connector.name}}:
+                          </label>
+                        </div>
+                        <div class="row">
+                          <label class="col-md-4 col-lg-4 col-sm-4">
+                            Begin:
+                          </label>
+                          <div class="col-md-8 col-lg-8 col-sm-8 " 
style="color: #fff">
+                            {{originBegin[i]}}
+                          </div>
+                        </div>
+                        <div class="row">
+                          <label class="col-md-4 col-lg-4 col-sm-4">
+                            Length:
+                          </label>
+                          <div class="col-md-8 col-lg-8 col-sm-8 " 
style="color: #fff">
+                            {{originLength[i]}}
+                          </div>
+                        </div>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+                <br/>
+              </div>
+            </div>
+            <div class="modal-footer">
+              <button type="button" class="btn btn-default" 
data-dismiss="modal" (click)="hide()">Cancel</button>
+              <button type="button" id="save" 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/c1b90c1a/ui/angular/src/app/job/create-job/batch/batch.component.spec.ts
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/job/create-job/batch/batch.component.spec.ts 
b/ui/angular/src/app/job/create-job/batch/batch.component.spec.ts
new file mode 100644
index 0000000..25b1479
--- /dev/null
+++ b/ui/angular/src/app/job/create-job/batch/batch.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 { BatchComponent } from './batch.component';
+
+describe('BatchComponent', () => {
+  let component: BatchComponent;
+  let fixture: ComponentFixture<BatchComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ BatchComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(BatchComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should be created', () => {
+    expect(component).toBeTruthy();
+  });
+});

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/c1b90c1a/ui/angular/src/app/job/create-job/batch/batch.component.ts
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/job/create-job/batch/batch.component.ts 
b/ui/angular/src/app/job/create-job/batch/batch.component.ts
new file mode 100644
index 0000000..d94748f
--- /dev/null
+++ b/ui/angular/src/app/job/create-job/batch/batch.component.ts
@@ -0,0 +1,395 @@
+/*
+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, AfterViewChecked, ViewChildren } 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 { MatDatepickerModule } from "@angular/material";
+import { ServiceService } from "../../../service/service.service";
+import { AngularMultiSelectModule } from 
"angular2-multiselect-dropdown/angular2-multiselect-dropdown";
+import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
+import { ToasterModule, ToasterService, ToasterConfig } from 
"angular2-toaster";
+import * as $ from "jquery";
+import { HttpParams } from "@angular/common/http";
+import { Router } from "@angular/router";
+import { NouisliderModule } from "ng2-nouislider";
+import { HttpClient } from "@angular/common/http";
+
+@Component({
+  selector: "app-batch",
+  templateUrl: "./batch.component.html",
+  providers: [ServiceService],
+  styleUrls: ["./batch.component.css"]
+})
+export class BatchComponent implements OnInit, AfterViewChecked {
+  constructor(
+    toasterService: ToasterService,
+    private http: HttpClient,
+    private router: Router,
+    public serviceService: ServiceService
+  ) {
+    this.toasterService = toasterService;
+  }
+
+  @ViewChildren("sliderRef") sliderRefs;
+
+  someKeyboard = [];
+  someKeyboardConfig = [];
+  config: any;
+  baseline: string;
+  cronExp: string;
+  dropdownList = [];
+  currentStep = 1;
+  maskOpen = false;
+  keyupLabelOn = false;
+  keydownLabelOn = false;
+  createResult = "";
+  jobname: string;
+  Measures = [];
+  measure: string;
+  measureid: any;
+
+  newJob = {
+    "cron.expression": "",
+    "measure.id": "",
+    "job.name": "",
+    "cron.time.zone": "",
+    // "cron.time.zone": "GMT+8:00",
+    // "predicate.config": {
+    //   "interval": "1m",
+    //   "repeat": 2
+    // },
+    "data.segments": [
+      // {
+      //   "data.connector.index": "source[0]",
+      //   "segment.range": {
+      //     "begin": "",
+      //     "length": ""
+      //   }
+      // },
+      // {
+      //   "data.connector.index": "target[0]",
+      //   "segment.range": {
+      //     "begin": "",
+      //     "length": ""
+      //   }
+      // }
+    ]
+  };
+
+  beginTime = [];
+  timeLength = [];
+  originBegin = [];
+  originLength = [];
+
+  private toasterService: ToasterService;
+
+  public visible = false;
+  public visibleAnimate = false;
+
+  public hide(): void {
+    this.visibleAnimate = false;
+    setTimeout(() => (this.visible = false), 300);
+    this.originBegin = [];
+    this.originLength = [];
+    $("#save").removeAttr("disabled");
+  }
+
+  public onContainerClicked(event: MouseEvent): void {
+    if ((<HTMLElement>event.target).classList.contains("modal")) {
+      this.hide();
+    }
+  }
+
+  close() {
+    this.maskOpen = false;
+  }
+
+  prev() {
+    history.back();
+  }
+
+  submit(form) {
+    if (!form.valid) {
+      this.toasterService.pop("error", "Error!", "Please complete the form!");
+      return false;
+    }
+    this.measureid = this.getMeasureId();
+    let time = new Date().getTimezoneOffset() / 60;
+    let timezone = "GMT" + time + ":00";
+    this.newJob = {
+      "job.name": this.jobname,
+      "measure.id": this.measureid,
+      "cron.expression": this.cronExp,
+      "cron.time.zone": timezone,
+      // "cron.time.zone": "GMT+8:00",
+      // "predicate.config": {
+      // "interval": "1m",
+      // "repeat": 2
+      // },
+      "data.segments": [
+        // {
+        //   "data.connector.index": "source[0]",
+        //   "segment.range": {
+        //   "begin": "",
+        //   "length": ""
+        //   }
+        // },
+        // {
+        //   "data.connector.index": "target[0]",
+        //   "segment.range": {
+        //   "begin": "",
+        //   "length": ""
+        //   }
+        // }
+      ]
+    };
+    for (let i = 0; i < this.dropdownList.length; i++) {
+      var connector = this.dropdownList[i];
+      var begin = this.someKeyboard[i][0];
+      var length = this.someKeyboard[i][1] - this.someKeyboard[i][0];
+      var beginStr = this.getTimeByUnit(begin, connector.size);
+      var lengthStr = this.getTimeByUnit(length, connector.size);
+      this.newJob["data.segments"].push({
+        "data.connector.name": connector.connectorname,
+        "as.baseline": true,
+        "segment.range": {
+          begin: beginStr,
+          length: lengthStr
+        }
+      });
+      this.originBegin.push(beginStr);
+      this.originLength.push(lengthStr);
+    }
+    if (this.dropdownList.length == 2) {
+      delete this.newJob["data.segments"][1]["as.baseline"];
+    }
+    this.visible = true;
+    setTimeout(() => (this.visibleAnimate = true), 100);
+  }
+
+  save() {
+    var addJobs = this.serviceService.config.uri.addJobs;
+    $("#save").attr("disabled", "true");
+    this.http.post(addJobs, this.newJob).subscribe(
+      data => {
+        this.createResult = data["results"];
+        this.hide();
+        this.router.navigate(["/jobs"]);
+      },
+      err => {
+        let response = JSON.parse(err.error);
+        if(response.code === '40004'){
+          this.toasterService.pop("error", "Error!", "Job name already 
exists!");
+        } else {
+          this.toasterService.pop("error", "Error!", "Error when creating 
job");
+        }
+        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() -
+        200
+    );
+    $(".y-scrollable").css({
+      height: $("fieldset").height()
+    });
+    $("#data-asset-pie").css({
+      height: $("#data-asset-pie")
+        .parent()
+        .width(),
+      width: $("#data-asset-pie")
+        .parent()
+        .width()
+    });
+  }
+
+  getTimeByUnit(multiplier, unit) {
+    var regex = /^(\d+)([a-zA-Z]+)$/g;
+    var arr = regex.exec(unit);
+    if (arr.length > 2) {
+      var n = parseInt(arr[1]);
+      var unitStr = arr[2];
+      return ((n * multiplier).toString() + arr[2]);
+    } else {
+      return multiplier.toString();
+    }
+  }
+
+  getMeasureId() {
+    for (let index in this.Measures) {
+      if (this.measure == this.Measures[index].name) {
+        return this.Measures[index].id;
+      }
+    }
+  }
+
+  onChange(measure) {
+    this.dropdownList = [];
+    for (let index in this.Measures) {
+      var map = this.Measures[index];
+      if (measure == map.name) {
+        var source = map["data.sources"];
+        for (let i = 0; i < source.length; i++) {
+          var details = source[i].connectors;
+          for (let j = 0; j < details.length; j++) {
+            if (details[j]["data.unit"] != undefined) {
+              var table =
+                details[j].config.database +
+                "." +
+                details[j].config["table.name"];
+              var size = details[j]["data.unit"];
+              var connectorname = details[j]["name"];
+              var detail = {
+                id: i + 1,
+                name: table,
+                size: size,
+                connectorname: connectorname
+              };
+              this.dropdownList.push(detail);
+            }
+          }
+        }
+      }
+    }
+    for (let i = 0; i < this.dropdownList.length; i++) {
+      this.someKeyboard[i] = [-1, 0];
+      this.someKeyboardConfig[i] = JSON.parse(JSON.stringify(this.config));
+      if (this.sliderRefs._results[i]) {
+        this.sliderRefs._results[i].slider.updateOptions({
+          range: {
+            min: -10,
+            max: 0
+          }
+        });
+      }
+    }
+  }
+
+  changeRange(index, value, i) {
+    let newRange = [];
+    newRange[i] = [this.someKeyboard[i][0], this.someKeyboard[i][1]];
+    newRange[i][index] = value;
+    this.updateSliderRange(value, i);
+    this.someKeyboard[i] = newRange[i];
+  }
+
+  rangeChange(evt, i) {
+    var oldmin = this.sliderRefs._results[i].config.range.min;
+    if (evt[0] - oldmin <= 2) {
+      this.sliderRefs._results[i].slider.updateOptions({
+        range: {
+          min: oldmin - 10,
+          max: 0
+        }
+      });
+    }
+    if (evt[0] - oldmin >= 13) {
+      this.sliderRefs._results[i].slider.updateOptions({
+        range: {
+          min: oldmin + 10,
+          max: 0
+        }
+      });
+    }
+    this.someKeyboard[i] = evt;
+  }
+
+  updateSliderRange(value, i) {
+    // setTimeout(() => {
+    var oldmin = this.sliderRefs._results[i].config.range.min;
+    var oldmax = this.sliderRefs._results[i].config.range.max;
+    var newmin = Math.floor(value / 10);
+    if (value - oldmin <= 3) {
+      this.sliderRefs._results[i].slider.updateOptions({
+        range: {
+          min: newmin * 10,
+          max: 0
+        }
+      });
+    }
+    // }, 100)
+  }
+
+  blinkKeyupLabel() {
+    this.keyupLabelOn = true;
+    setTimeout(() => {
+      this.keyupLabelOn = false;
+    }, 450);
+  }
+
+  blinkKeydownLabel() {
+    this.keydownLabelOn = true;
+    setTimeout(() => {
+      this.keydownLabelOn = false;
+    }, 450);
+  }
+
+  ngOnInit() {
+    var allModels = this.serviceService.config.uri.allModels + '?type=griffin';
+    this.http.get(allModels).subscribe(data => {
+      let originData = data;
+      for(let i in originData){
+        if(originData[i]["process.type"] === "BATCH"){
+          this.Measures.push(originData[i]);
+        }
+      }
+    });
+    this.config = {
+      behaviour: "drag",
+      connect: true,
+      start: [-10, 0],
+      keyboard: true, // same as [keyboard]="true"
+      step: 1,
+      pageSteps: 0, // number of page steps, defaults to 10
+      range: {
+        min: -10,
+        max: 0
+      },
+      pips: {
+        mode: "steps",
+        density: 10,
+        // values: 1,
+        stepped: true
+      }
+    };
+  }
+
+  ngAfterViewChecked() {
+    this.resizeWindow();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/c1b90c1a/ui/angular/src/app/job/create-job/create-job.component.css
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/job/create-job/create-job.component.css 
b/ui/angular/src/app/job/create-job/create-job.component.css
deleted file mode 100644
index 6288f12..0000000
--- a/ui/angular/src/app/job/create-job/create-job.component.css
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
-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.
-*/
-.job {
-    font-size: 20px;
-}
-
-.info {
-    color: #b2c831;
-}
-
-.btn-o {
-    background: 0 0 !important;
-}
-
-legend {
-    background-color: #000;
-    color: #007aff;
-    left: 10px;
-    padding: 0 10px;
-    position: absolute;
-    top: -12px;
-    font-weight: 400;
-    color: #fff;
-    margin-bottom: 20px;
-    font-size: 21px;
-    width: auto !important;
-    border: none !important;
-}
-fieldset {
-    border: 1px solid #e6e8e8;
-    border-radius: 5px;
-    margin: 20px 0;
-    padding: 25px;
-    position: relative;
-    min-width: 0;
-    display: block;
-    height: 320px;
-}
-
-.formStep {
-    background-color: #000;
-}
-.setcolor {
-    color: #b2c831;
-}
-.setgrey {
-    color: #888888;
-}
-.mat-calendar-table {
-    height: 400px;
-}
-.mat-datepicker-content {
-    overflow-y: auto;
-}
-
-#md-datepicker-0 {
-    height: 250px;
-}
-
-.center {
-    margin-left: 5%;
-}
-
-.range {
-    display: block;
-    width: 20%;
-    height: 10%;
-    margin-bottom: 5px;
-}
-.setborder {
-    border: 2px solid;
-    border-radius: 5px;
-    width: 8%;
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/c1b90c1a/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
deleted file mode 100644
index 86b82e3..0000000
--- a/ui/angular/src/app/job/create-job/create-job.component.html
+++ /dev/null
@@ -1,179 +0,0 @@
-<!--
-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="jobForm" 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">
-                      Job 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)]="jobname" name="jobName" #jobName="ngModel" placeholder="Please 
input the job name" required pattern="^[a-zA-Z0-9_-]*$" id="jobName">
-                      <span class="error text-small block " 
*ngIf="jobName.dirty && (jobName.errors?.required)">
-                        Job Name is required</span>
-                      <span class="error text-small block " 
*ngIf="jobName.dirty && (jobName.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 for="measureSelector" 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 ">
-                      <select id="measureSelector" class="form-control" 
ngControl="name" required name="measure.name" [(ngModel)]="measure" 
(ngModelChange)="onChange($event)">
-                        <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 for="measureSelector" class="col-md-2 col-lg-2 
col-sm-2 control-label">
-                      Cron Expression<span class="symbol required"></span>:
-                    </label>
-                    <div class="col-md-10 col-lg-10 col-sm-10 ">
-                      <input class="form-control" ngControl="name" required 
[(ngModel)]="cronExp" name="cronExp">
-                    </div>
-                  </div>
-                </div>
-                <div *ngFor="let connector of this.dropdownList; let i=index">
-                  <div>
-                    <label style="padding-left: 30px;padding-top: 10px;">
-                      please select data range for {{connector.name}}
-                    </label>
-                  </div>
-                  <p style="margin-left:60px" class="setcolor">
-                    <i class="fa fa-info-circle"></i> One step means a 
partition size,and {{connector.name}} partition size = {{connector.size}}
-                  </p>
-                  <div class="col-md-11 col-lg-11 col-sm-11 center">
-                    begin :
-                    <input type="number" class="setborder" value="{{ 
someKeyboard[i][0] }}" [(ngModel)]="someKeyboard[i][0]" max="0" 
name="begin{{i}}" (ngModelChange)="changeRange(index,someKeyboard[i][0],i)"> 
end :
-                    <input type="number" class="setborder" max="0" value="{{ 
someKeyboard[i][1] }}" [(ngModel)]="someKeyboard[i][1]" name="end{{i}}" 
(ngModelChange)="changeRange(1,$event,i)">
-                  </div>
-                  <nouislider class="col-md-11 col-lg-11 col-sm-11 center" 
id="slider{{i}}" #sliderRef name="slider{{i}}" [config]="someKeyboardConfig[i]" 
[(ngModel)]="someKeyboard[i]" (ngModelChange)="rangeChange($event,i)" 
(keyup)="blinkKeyupLabel()" (keydown)="blinkKeydownLabel()" 
style="margin-bottom: 5rem"></nouislider>
-                </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)="prev()">
-              <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" (click)="submit(jobForm)">
-              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">
-              <div class="container-fluid" id="viewJobContent" 
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 " style="color: 
#fff">
-                          {{measure}}
-                          <!-- {{Measures}} -->
-                        </div>
-                      </div>
-                      <div class="row">
-                        <label class="col-md-4 col-lg-4 col-sm-4">
-                          Cron Expression:
-                        </label>
-                        <div class="col-md-8 col-lg-8 col-sm-8 " style="color: 
#fff">
-                          {{cronExp}}
-                        </div>
-                      </div>
-                      <div *ngFor="let connector of this.dropdownList; let 
i=index">
-                        <div class="row">
-                          <label class="col-md-12 col-lg-12 col-sm-12">
-                            {{connector.name}}:
-                          </label>
-                        </div>
-                        <div class="row">
-                          <label class="col-md-4 col-lg-4 col-sm-4">
-                            Begin:
-                          </label>
-                          <div class="col-md-8 col-lg-8 col-sm-8 " 
style="color: #fff">
-                            {{originBegin[i]}}
-                          </div>
-                        </div>
-                        <div class="row">
-                          <label class="col-md-4 col-lg-4 col-sm-4">
-                            Length:
-                          </label>
-                          <div class="col-md-8 col-lg-8 col-sm-8 " 
style="color: #fff">
-                            {{originLength[i]}}
-                          </div>
-                        </div>
-                      </div>
-                    </div>
-                  </div>
-                </div>
-                <br/>
-              </div>
-            </div>
-            <div class="modal-footer">
-              <button type="button" class="btn btn-default" 
data-dismiss="modal" (click)="hide()">Cancel</button>
-              <button type="button" id="save" 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/c1b90c1a/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
deleted file mode 100644
index 44292d5..0000000
--- a/ui/angular/src/app/job/create-job/create-job.component.spec.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
-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/c1b90c1a/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
deleted file mode 100644
index 2b97728..0000000
--- a/ui/angular/src/app/job/create-job/create-job.component.ts
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
-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, AfterViewChecked, ViewChildren } 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 { MatDatepickerModule } from "@angular/material";
-import { ServiceService } from "../../service/service.service";
-import { AngularMultiSelectModule } from 
"angular2-multiselect-dropdown/angular2-multiselect-dropdown";
-import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
-import { ToasterModule, ToasterService, ToasterConfig } from 
"angular2-toaster";
-import * as $ from "jquery";
-import { HttpParams } from "@angular/common/http";
-import { Router } from "@angular/router";
-import { NouisliderModule } from "ng2-nouislider";
-import { HttpClient } from "@angular/common/http";
-
-@Component({
-  selector: "app-create-job",
-  templateUrl: "./create-job.component.html",
-  providers: [ServiceService],
-  styleUrls: ["./create-job.component.css"]
-})
-export class CreateJobComponent implements OnInit, AfterViewChecked {
-  constructor(
-    toasterService: ToasterService,
-    private http: HttpClient,
-    private router: Router,
-    public serviceService: ServiceService
-  ) {
-    this.toasterService = toasterService;
-  }
-
-  @ViewChildren("sliderRef") sliderRefs;
-
-  someKeyboard = [];
-  someKeyboardConfig = [];
-  config: any;
-  baseline: string;
-  cronExp: string;
-  dropdownList = [];
-  currentStep = 1;
-  maskOpen = false;
-  keyupLabelOn = false;
-  keydownLabelOn = false;
-  createResult = "";
-  jobname: string;
-  Measures: object;
-  measure: string;
-  measureid: any;
-
-  newJob = {
-    "cron.expression": "",
-    "measure.id": "",
-    "job.name": "",
-    "cron.time.zone": "",
-    // "cron.time.zone": "GMT+8:00",
-    // "predicate.config": {
-    //   "interval": "1m",
-    //   "repeat": 2
-    // },
-    "data.segments": [
-      // {
-      //   "data.connector.index": "source[0]",
-      //   "segment.range": {
-      //     "begin": "",
-      //     "length": ""
-      //   }
-      // },
-      // {
-      //   "data.connector.index": "target[0]",
-      //   "segment.range": {
-      //     "begin": "",
-      //     "length": ""
-      //   }
-      // }
-    ]
-  };
-
-  beginTime = [];
-  timeLength = [];
-  originBegin = [];
-  originLength = [];
-
-  private toasterService: ToasterService;
-
-  public visible = false;
-  public visibleAnimate = false;
-
-  public hide(): void {
-    this.visibleAnimate = false;
-    setTimeout(() => (this.visible = false), 300);
-    this.originBegin = [];
-    this.originLength = [];
-    $("#save").removeAttr("disabled");
-  }
-
-  public onContainerClicked(event: MouseEvent): void {
-    if ((<HTMLElement>event.target).classList.contains("modal")) {
-      this.hide();
-    }
-  }
-
-  close() {
-    this.maskOpen = false;
-  }
-
-  prev() {
-    history.back();
-  }
-
-  submit(form) {
-    if (!form.valid) {
-      this.toasterService.pop("error", "Error!", "Please complete the form!");
-      return false;
-    }
-    this.measureid = this.getMeasureId();
-    let time = new Date().getTimezoneOffset() / 60;
-    let timezone = "GMT" + time + ":00";
-    this.newJob = {
-      "job.name": this.jobname,
-      "measure.id": this.measureid,
-      "cron.expression": this.cronExp,
-      "cron.time.zone": timezone,
-      // "cron.time.zone": "GMT+8:00",
-      // "predicate.config": {
-      // "interval": "1m",
-      // "repeat": 2
-      // },
-      "data.segments": [
-        // {
-        //   "data.connector.index": "source[0]",
-        //   "segment.range": {
-        //   "begin": "",
-        //   "length": ""
-        //   }
-        // },
-        // {
-        //   "data.connector.index": "target[0]",
-        //   "segment.range": {
-        //   "begin": "",
-        //   "length": ""
-        //   }
-        // }
-      ]
-    };
-    for (let i = 0; i < this.dropdownList.length; i++) {
-      var connector = this.dropdownList[i];
-      var begin = this.someKeyboard[i][0];
-      var length = this.someKeyboard[i][1] - this.someKeyboard[i][0];
-      var beginStr = this.getTimeByUnit(begin, connector.size);
-      var lengthStr = this.getTimeByUnit(length, connector.size);
-      this.newJob["data.segments"].push({
-        "data.connector.name": connector.connectorname,
-        "as.baseline": true,
-        "segment.range": {
-          begin: beginStr,
-          length: lengthStr
-        }
-      });
-      this.originBegin.push(beginStr);
-      this.originLength.push(lengthStr);
-    }
-    if (this.dropdownList.length == 2) {
-      delete this.newJob["data.segments"][1]["as.baseline"];
-    }
-    this.visible = true;
-    setTimeout(() => (this.visibleAnimate = true), 100);
-  }
-
-  save() {
-    var addJobs = this.serviceService.config.uri.addJobs;
-    $("#save").attr("disabled", "true");
-    this.http.post(addJobs, this.newJob).subscribe(
-      data => {
-        this.createResult = data["results"];
-        this.hide();
-        this.router.navigate(["/jobs"]);
-      },
-      err => {
-        let response = JSON.parse(err.error);
-        if(response.code === '40004'){
-          this.toasterService.pop("error", "Error!", "Job name already 
exists!");
-        } else {
-          this.toasterService.pop("error", "Error!", "Error when creating 
job");
-        }
-        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() -
-        200
-    );
-    $(".y-scrollable").css({
-      height: $("fieldset").height()
-    });
-    $("#data-asset-pie").css({
-      height: $("#data-asset-pie")
-        .parent()
-        .width(),
-      width: $("#data-asset-pie")
-        .parent()
-        .width()
-    });
-  }
-
-  setHeight() {
-    $("#md-datepicker-0").height(250);
-  }
-
-  getTimeByUnit(multiplier, unit) {
-    var regex = /^(\d+)([a-zA-Z]+)$/g;
-    var arr = regex.exec(unit);
-    if (arr.length > 2) {
-      var n = parseInt(arr[1]);
-      var unitStr = arr[2];
-      return ((n * multiplier).toString() + arr[2]);
-    } else {
-      return multiplier.toString();
-    }
-  }
-
-  getMeasureId() {
-    for (let index in this.Measures) {
-      if (this.measure == this.Measures[index].name) {
-        return this.Measures[index].id;
-      }
-    }
-  }
-
-  onChange(measure) {
-    this.dropdownList = [];
-    for (let index in this.Measures) {
-      var map = this.Measures[index];
-      if (measure == map.name) {
-        var source = map["data.sources"];
-        for (let i = 0; i < source.length; i++) {
-          var details = source[i].connectors;
-          for (let j = 0; j < details.length; j++) {
-            if (details[j]["data.unit"] != undefined) {
-              var table =
-                details[j].config.database +
-                "." +
-                details[j].config["table.name"];
-              var size = details[j]["data.unit"];
-              var connectorname = details[j]["name"];
-              var detail = {
-                id: i + 1,
-                name: table,
-                size: size,
-                connectorname: connectorname
-              };
-              this.dropdownList.push(detail);
-            }
-          }
-        }
-      }
-    }
-    for (let i = 0; i < this.dropdownList.length; i++) {
-      this.someKeyboard[i] = [-1, 0];
-      this.someKeyboardConfig[i] = JSON.parse(JSON.stringify(this.config));
-      if (this.sliderRefs._results[i]) {
-        this.sliderRefs._results[i].slider.updateOptions({
-          range: {
-            min: -10,
-            max: 0
-          }
-        });
-      }
-    }
-  }
-
-  changeRange(index, value, i) {
-    let newRange = [];
-    newRange[i] = [this.someKeyboard[i][0], this.someKeyboard[i][1]];
-    newRange[i][index] = value;
-    this.updateSliderRange(value, i);
-    this.someKeyboard[i] = newRange[i];
-  }
-
-  rangeChange(evt, i) {
-    var oldmin = this.sliderRefs._results[i].config.range.min;
-    if (evt[0] - oldmin <= 2) {
-      this.sliderRefs._results[i].slider.updateOptions({
-        range: {
-          min: oldmin - 10,
-          max: 0
-        }
-      });
-    }
-    if (evt[0] - oldmin >= 13) {
-      this.sliderRefs._results[i].slider.updateOptions({
-        range: {
-          min: oldmin + 10,
-          max: 0
-        }
-      });
-    }
-    this.someKeyboard[i] = evt;
-  }
-
-  updateSliderRange(value, i) {
-    // setTimeout(() => {
-    var oldmin = this.sliderRefs._results[i].config.range.min;
-    var oldmax = this.sliderRefs._results[i].config.range.max;
-    var newmin = Math.floor(value / 10);
-    if (value - oldmin <= 3) {
-      this.sliderRefs._results[i].slider.updateOptions({
-        range: {
-          min: newmin * 10,
-          max: 0
-        }
-      });
-    }
-    // }, 100)
-  }
-
-  blinkKeyupLabel() {
-    this.keyupLabelOn = true;
-    setTimeout(() => {
-      this.keyupLabelOn = false;
-    }, 450);
-  }
-
-  blinkKeydownLabel() {
-    this.keydownLabelOn = true;
-    setTimeout(() => {
-      this.keydownLabelOn = false;
-    }, 450);
-  }
-
-  ngOnInit() {
-    var allModels = this.serviceService.config.uri.allModels + '?type=griffin';
-    this.http.get(allModels).subscribe(data => {
-      this.Measures = data;
-    });
-    this.config = {
-      behaviour: "drag",
-      connect: true,
-      start: [-10, 0],
-      keyboard: true, // same as [keyboard]="true"
-      step: 1,
-      pageSteps: 0, // number of page steps, defaults to 10
-      range: {
-        min: -10,
-        max: 0
-      },
-      pips: {
-        mode: "steps",
-        density: 10,
-        // values: 1,
-        stepped: true
-      }
-    };
-  }
-
-  ngAfterViewChecked() {
-    this.resizeWindow();
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/c1b90c1a/ui/angular/src/app/job/create-job/streaming/streaming.component.css
----------------------------------------------------------------------
diff --git 
a/ui/angular/src/app/job/create-job/streaming/streaming.component.css 
b/ui/angular/src/app/job/create-job/streaming/streaming.component.css
new file mode 100644
index 0000000..6288f12
--- /dev/null
+++ b/ui/angular/src/app/job/create-job/streaming/streaming.component.css
@@ -0,0 +1,90 @@
+/*
+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.
+*/
+.job {
+    font-size: 20px;
+}
+
+.info {
+    color: #b2c831;
+}
+
+.btn-o {
+    background: 0 0 !important;
+}
+
+legend {
+    background-color: #000;
+    color: #007aff;
+    left: 10px;
+    padding: 0 10px;
+    position: absolute;
+    top: -12px;
+    font-weight: 400;
+    color: #fff;
+    margin-bottom: 20px;
+    font-size: 21px;
+    width: auto !important;
+    border: none !important;
+}
+fieldset {
+    border: 1px solid #e6e8e8;
+    border-radius: 5px;
+    margin: 20px 0;
+    padding: 25px;
+    position: relative;
+    min-width: 0;
+    display: block;
+    height: 320px;
+}
+
+.formStep {
+    background-color: #000;
+}
+.setcolor {
+    color: #b2c831;
+}
+.setgrey {
+    color: #888888;
+}
+.mat-calendar-table {
+    height: 400px;
+}
+.mat-datepicker-content {
+    overflow-y: auto;
+}
+
+#md-datepicker-0 {
+    height: 250px;
+}
+
+.center {
+    margin-left: 5%;
+}
+
+.range {
+    display: block;
+    width: 20%;
+    height: 10%;
+    margin-bottom: 5px;
+}
+.setborder {
+    border: 2px solid;
+    border-radius: 5px;
+    width: 8%;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/c1b90c1a/ui/angular/src/app/job/create-job/streaming/streaming.component.html
----------------------------------------------------------------------
diff --git 
a/ui/angular/src/app/job/create-job/streaming/streaming.component.html 
b/ui/angular/src/app/job/create-job/streaming/streaming.component.html
new file mode 100644
index 0000000..db85aa5
--- /dev/null
+++ b/ui/angular/src/app/job/create-job/streaming/streaming.component.html
@@ -0,0 +1,122 @@
+<!--
+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 Streaming Job</h5>
+  </div>
+  <!--//row-->
+  <div class="row">
+    <!-- <form name="Form" id="form" novalidate> -->
+    <form name="jobForm" 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">
+                      Job 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)]="jobname" name="jobName" #jobName="ngModel" placeholder="Please 
input the job name" required pattern="^[a-zA-Z0-9_-]*$" id="jobName">
+                      <span class="error text-small block " 
*ngIf="jobName.dirty && (jobName.errors?.required)">
+                        Job Name is required</span>
+                      <span class="error text-small block " 
*ngIf="jobName.dirty && (jobName.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 for="measureSelector" 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 ">
+                      <select id="measureSelector" class="form-control" 
ngControl="name" required name="measure.name" [(ngModel)]="measure" 
(ngModelChange)="onChange($event)">
+                        <option *ngFor="let row of Measures" 
value="{{row.name}}">{{row.name}}</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)="prev()">
+              <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" (click)="submit(jobForm)">
+              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">
+              <div class="container-fluid" id="viewJobContent" 
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 " style="color: 
#fff">
+                          {{measure}}
+                          <!-- {{Measures}} -->
+                        </div>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+                <br/>
+              </div>
+            </div>
+            <div class="modal-footer">
+              <button type="button" class="btn btn-default" 
data-dismiss="modal" (click)="hide()">Cancel</button>
+              <button type="button" id="save" 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/c1b90c1a/ui/angular/src/app/job/create-job/streaming/streaming.component.spec.ts
----------------------------------------------------------------------
diff --git 
a/ui/angular/src/app/job/create-job/streaming/streaming.component.spec.ts 
b/ui/angular/src/app/job/create-job/streaming/streaming.component.spec.ts
new file mode 100644
index 0000000..58bc51f
--- /dev/null
+++ b/ui/angular/src/app/job/create-job/streaming/streaming.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 { StreamingComponent } from './streaming.component';
+
+describe('StreamingComponent', () => {
+  let component: StreamingComponent;
+  let fixture: ComponentFixture<StreamingComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ StreamingComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(StreamingComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should be created', () => {
+    expect(component).toBeTruthy();
+  });
+});

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/c1b90c1a/ui/angular/src/app/job/create-job/streaming/streaming.component.ts
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/job/create-job/streaming/streaming.component.ts 
b/ui/angular/src/app/job/create-job/streaming/streaming.component.ts
new file mode 100644
index 0000000..4162d69
--- /dev/null
+++ b/ui/angular/src/app/job/create-job/streaming/streaming.component.ts
@@ -0,0 +1,273 @@
+/*
+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, AfterViewChecked, ViewChildren } 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 { 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 { HttpParams } from "@angular/common/http";
+import { Router } from "@angular/router";
+import { HttpClient } from "@angular/common/http";
+
+@Component({
+  selector: 'app-streaming',
+  templateUrl: './streaming.component.html',
+  styleUrls: ['./streaming.component.css']
+})
+export class StreamingComponent implements OnInit {
+
+  constructor(
+    toasterService: ToasterService,
+    private http: HttpClient,
+    private router: Router,
+    public serviceService: ServiceService
+  ) {
+    this.toasterService = toasterService;
+  }
+
+  @ViewChildren("sliderRef") sliderRefs;
+
+  someKeyboard = [];
+  someKeyboardConfig = [];
+  config: any;
+  baseline: string;
+  cronExp: string;
+  dropdownList = [];
+  currentStep = 1;
+  maskOpen = false;
+  keyupLabelOn = false;
+  keydownLabelOn = false;
+  createResult = "";
+  jobname: string;
+  Measures = [];
+  measure: string;
+  measureid: any;
+
+  newJob = {
+    "cron.expression": "",
+    "measure.id": "",
+    "job.name": "",
+    "cron.time.zone": "",
+    // "cron.time.zone": "GMT+8:00",
+    // "predicate.config": {
+    //   "interval": "1m",
+    //   "repeat": 2
+    // },
+    "data.segments": [
+      // {
+      //   "data.connector.index": "source[0]",
+      //   "segment.range": {
+      //     "begin": "",
+      //     "length": ""
+      //   }
+      // },
+      // {
+      //   "data.connector.index": "target[0]",
+      //   "segment.range": {
+      //     "begin": "",
+      //     "length": ""
+      //   }
+      // }
+    ]
+  };
+
+  beginTime = [];
+  timeLength = [];
+  originBegin = [];
+  originLength = [];
+
+  private toasterService: ToasterService;
+
+  public visible = false;
+  public visibleAnimate = false;
+
+  public hide(): void {
+    this.visibleAnimate = false;
+    setTimeout(() => (this.visible = false), 300);
+    this.originBegin = [];
+    this.originLength = [];
+    $("#save").removeAttr("disabled");
+  }
+
+  public onContainerClicked(event: MouseEvent): void {
+    if ((<HTMLElement>event.target).classList.contains("modal")) {
+      this.hide();
+    }
+  }
+
+  close() {
+    this.maskOpen = false;
+  }
+
+  prev() {
+    history.back();
+  }
+
+  submit(form) {
+    if (!form.valid) {
+      this.toasterService.pop("error", "Error!", "Please complete the form!");
+      return false;
+    }
+    this.measureid = this.getMeasureId();
+    let time = new Date().getTimezoneOffset() / 60;
+    let timezone = "GMT" + time + ":00";
+    this.newJob = {
+      "job.name": this.jobname,
+      "measure.id": this.measureid,
+      "cron.expression": this.cronExp,
+      "cron.time.zone": timezone,
+      // "cron.time.zone": "GMT+8:00",
+      // "predicate.config": {
+      // "interval": "1m",
+      // "repeat": 2
+      // },
+      "data.segments": [
+        // {
+        //   "data.connector.index": "source[0]",
+        //   "segment.range": {
+        //   "begin": "",
+        //   "length": ""
+        //   }
+        // },
+        // {
+        //   "data.connector.index": "target[0]",
+        //   "segment.range": {
+        //   "begin": "",
+        //   "length": ""
+        //   }
+        // }
+      ]
+    };
+    this.visible = true;
+    setTimeout(() => (this.visibleAnimate = true), 100);
+  }
+
+  save() {
+    var addJobs = this.serviceService.config.uri.addJobs;
+    $("#save").attr("disabled", "true");
+    this.http.post(addJobs, this.newJob).subscribe(
+      data => {
+        this.createResult = data["results"];
+        this.hide();
+        this.router.navigate(["/jobs"]);
+      },
+      err => {
+        let response = JSON.parse(err.error);
+        if(response.code === '40004'){
+          this.toasterService.pop("error", "Error!", "Job name already 
exists!");
+        } else {
+          this.toasterService.pop("error", "Error!", "Error when creating 
job");
+        }
+        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() -
+        200
+    );
+    $(".y-scrollable").css({
+      height: $("fieldset").height()
+    });
+    $("#data-asset-pie").css({
+      height: $("#data-asset-pie")
+        .parent()
+        .width(),
+      width: $("#data-asset-pie")
+        .parent()
+        .width()
+    });
+  }
+
+  getMeasureId() {
+    for (let index in this.Measures) {
+      if (this.measure == this.Measures[index].name) {
+        return this.Measures[index].id;
+      }
+    }
+  }
+
+  onChange(measure) {
+    this.dropdownList = [];
+    for (let index in this.Measures) {
+      var map = this.Measures[index];
+      if (measure == map.name) {
+        var source = map["data.sources"];
+        for (let i = 0; i < source.length; i++) {
+          var details = source[i].connectors;
+          for (let j = 0; j < details.length; j++) {
+            if (details[j]["data.unit"] != undefined) {
+              var table =
+                details[j].config.database +
+                "." +
+                details[j].config["table.name"];
+              var size = details[j]["data.unit"];
+              var connectorname = details[j]["name"];
+              var detail = {
+                id: i + 1,
+                name: table,
+                size: size,
+                connectorname: connectorname
+              };
+              this.dropdownList.push(detail);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  ngOnInit() {
+    var allModels = this.serviceService.config.uri.allModels + '?type=griffin';
+    this.http.get(allModels).subscribe(data => {
+      let originData = data;
+      for(let i in originData){
+        if(originData[i]["process.type"] === "STREAING"){
+          this.Measures.push(originData[i]);
+        }
+      }
+    });
+  }
+
+  ngAfterViewChecked() {
+    this.resizeWindow();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/c1b90c1a/ui/angular/src/app/job/job-detail/job-detail.component.css
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/job/job-detail/job-detail.component.css 
b/ui/angular/src/app/job/job-detail/job-detail.component.css
new file mode 100644
index 0000000..214f8c6
--- /dev/null
+++ b/ui/angular/src/app/job/job-detail/job-detail.component.css
@@ -0,0 +1,18 @@
+/*
+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.
+*/
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/c1b90c1a/ui/angular/src/app/job/job-detail/job-detail.component.html
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/job/job-detail/job-detail.component.html 
b/ui/angular/src/app/job/job-detail/job-detail.component.html
new file mode 100644
index 0000000..befa9ff
--- /dev/null
+++ b/ui/angular/src/app/job/job-detail/job-detail.component.html
@@ -0,0 +1,101 @@
+<!--
+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" id="viewruleContent">
+  <div class="row">
+    <h5 class="over-title margin-bottom-15">View Job</h5>
+  </div>
+  <div class="row y-scrollable" style="max-height: 350px;">
+    <div class="col-sm-6 col-xs-12">
+      <div id="viewruleDefinition" class="viewrule-content">
+        <div class="row">
+          <label class="col-xs-4">
+            Job Name:
+          </label>
+          <div class="col-xs-8 " style="color: #fff">
+            {{jobName}}
+          </div>
+        </div>
+        <div class="row">
+          <label class="col-xs-4">
+            Measure Name:
+          </label>
+          <div class="col-xs-8 " style="color: #fff">
+            {{measureName}}
+          </div>
+        </div>
+        <div class="row">
+          <label class="col-xs-4">
+            Measure Type:
+          </label>
+          <div class="col-xs-8 " style="color: #fff">
+            {{measureType}}
+          </div>
+        </div>
+        <div class="row">
+          <label class="col-xs-4">
+            Process Type:
+          </label>
+          <div class="col-xs-8 " style="color: #fff">
+            {{processType}}
+          </div>
+        </div>
+        <div class="row">
+          <label class="col-xs-4">
+            Cron Expression:
+          </label>
+          <div class="col-xs-8 " style="color: #fff">
+            {{cronExp}}
+          </div>
+        </div>
+        <div class="row">
+          <label class="col-xs-4">
+            Cron Time Zone:
+          </label>
+          <div class="col-xs-8 " style="color: #fff">
+            {{cronTimeZone}}
+          </div>
+        </div>
+        <div *ngIf="this.rangeConfig.length != 0">      
+          <div class="row" style="margin-left: 0px" *ngFor="let item of 
this.tableInfo;let i = index">
+            <div class="row">
+              <label class="col-xs-12">
+                {{item}}:
+              </label>
+            </div>
+            <div class="row">
+              <label class="col-xs-4">
+                Begin:
+              </label>
+              <div class="col-xs-8 " style="color: #fff">
+                {{this.rangeConfig[i].begin}}
+              </div>
+            </div>
+            <div class="row">
+              <label class="col-xs-4">
+                Length:
+              </label>
+              <div class="col-xs-8 " style="color: #fff">
+                {{this.rangeConfig[i].length}}
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/c1b90c1a/ui/angular/src/app/job/job-detail/job-detail.component.spec.ts
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/job/job-detail/job-detail.component.spec.ts 
b/ui/angular/src/app/job/job-detail/job-detail.component.spec.ts
new file mode 100644
index 0000000..5f2e168
--- /dev/null
+++ b/ui/angular/src/app/job/job-detail/job-detail.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { JobDetailComponent } from './job-detail.component';
+
+describe('JobDetailComponent', () => {
+  let component: JobDetailComponent;
+  let fixture: ComponentFixture<JobDetailComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ JobDetailComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(JobDetailComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should be created', () => {
+    expect(component).toBeTruthy();
+  });
+});

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/c1b90c1a/ui/angular/src/app/job/job-detail/job-detail.component.ts
----------------------------------------------------------------------
diff --git a/ui/angular/src/app/job/job-detail/job-detail.component.ts 
b/ui/angular/src/app/job/job-detail/job-detail.component.ts
new file mode 100644
index 0000000..e5c8a8d
--- /dev/null
+++ b/ui/angular/src/app/job/job-detail/job-detail.component.ts
@@ -0,0 +1,91 @@
+/*
+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 { ServiceService } from "../../service/service.service";
+import { HttpClient } from "@angular/common/http";
+import { Router, ActivatedRoute, ParamMap } from "@angular/router";
+
+@Component({
+  selector: 'app-job-detail',
+  templateUrl: './job-detail.component.html',
+  providers: [ServiceService],
+  styleUrls: ['./job-detail.component.css']
+})
+export class JobDetailComponent implements OnInit {
+  
+  currentId: string;
+  jobData: any;
+  measureData: any;
+  jobName: string;
+  cronExp: string;
+  cronTimeZone: string;
+  measureName: string;
+  measureType: string;
+  processType: string;
+  rangeConfig = [];
+  tableInfo = [];
+  constructor(
+       private route: ActivatedRoute,
+       private router: Router,
+       private http: HttpClient,
+    public serviceService: ServiceService) { }
+
+  getMeasureById(measureId) {
+    let url = this.serviceService.config.uri.getModel + "/" + measureId;
+    this.http.get(url).subscribe(
+      data => {
+        this.measureData = data;
+        this.measureName = this.measureData.name;
+        this.measureType = this.measureData["dq.type"].toLowerCase();
+        this.processType = this.measureData["process.type"].toLowerCase();
+        for(let item of this.measureData["data.sources"]){
+          let config = item.connectors[0].config;
+          let tableName = config.database + "." + config["table.name"];
+          this.tableInfo.push(tableName);
+        }
+      },
+      err => {
+        console.log("error");
+      }
+    );
+  }
+
+  ngOnInit() {
+       this.currentId = this.route.snapshot.paramMap.get("id");
+    var getJobById = this.serviceService.config.uri.getJobById + "?jobId=" + 
this.currentId;
+    this.http.get(getJobById).subscribe(
+      data => {
+        this.jobData = data;
+        this.jobName = this.jobData["job.name"];
+        this.cronExp = this.jobData["cron.expression"];
+        this.cronTimeZone = this.jobData["cron.time.zone"];
+        let mesureId = this.jobData["measure.id"];
+        this.getMeasureById(mesureId);
+        for(let item of this.jobData["data.segments"]){
+          this.rangeConfig.push(item["segment.range"]);
+        }
+      },
+      err => {
+        console.log("error");
+        // toaster.pop('error', 'Error when geting record', response.message);
+      }
+    );
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/c1b90c1a/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
index d8e7034..03977d3 100644
--- a/ui/angular/src/app/job/job.component.css
+++ b/ui/angular/src/app/job/job.component.css
@@ -37,6 +37,10 @@ under the License.
   border-top: 1px solid transparent;
 }
 
+.table > tbody > tr > td {
+  vertical-align: middle;
+}
+
 a {
   color: white;
 }
@@ -55,3 +59,12 @@ a {
 #pagination .pagination {
   margin: 20px 0 0 0;
 }
+
+.dropdown-menu {
+  top: 0;
+  left: 100%;
+}
+
+.btn-group {
+  margin: 0 0 10px;
+}

Reply via email to