Repository: incubator-griffin Updated Branches: refs/heads/master 5255d71c7 -> 2aa58c0b3
[GRIFFIN-121] UI-JIRA- Add publish measure create process on UI UI-JIRA-GRIFFIN-121 Add publish measure create process on UI Author: jenny <[email protected]> Closes #246 from icesmartjuan/ui_addpublish. Project: http://git-wip-us.apache.org/repos/asf/incubator-griffin/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-griffin/commit/2aa58c0b Tree: http://git-wip-us.apache.org/repos/asf/incubator-griffin/tree/2aa58c0b Diff: http://git-wip-us.apache.org/repos/asf/incubator-griffin/diff/2aa58c0b Branch: refs/heads/master Commit: 2aa58c0b3e94f4c778f749bb6b8d80c48fbd0060 Parents: 5255d71 Author: jenny <[email protected]> Authored: Mon Apr 9 12:02:00 2018 +0800 Committer: Lionel Liu <[email protected]> Committed: Mon Apr 9 12:02:00 2018 +0800 ---------------------------------------------------------------------- .../core/measure/entity/ExternalMeasure.java | 2 +- ui/angular/src/app/app.module.ts | 6 + ui/angular/src/app/health/health.component.ts | 5 +- .../create-measure.component.html | 31 ++ .../create-measure/pub/pub.component.css | 506 +++++++++++++++++++ .../create-measure/pub/pub.component.html | 211 ++++++++ .../create-measure/pub/pub.component.spec.ts | 43 ++ .../measure/create-measure/pub/pub.component.ts | 216 ++++++++ .../measure-detail.component.html | 8 + .../measure-detail/measure-detail.component.ts | 1 + .../src/app/measure/measure.component.css | 12 + ui/angular/src/app/metric/metric.component.html | 9 +- ui/angular/src/app/metric/metric.component.ts | 3 +- ui/angular/src/app/sidebar/sidebar.component.ts | 3 +- 14 files changed, 1044 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/2aa58c0b/service/src/main/java/org/apache/griffin/core/measure/entity/ExternalMeasure.java ---------------------------------------------------------------------- diff --git a/service/src/main/java/org/apache/griffin/core/measure/entity/ExternalMeasure.java b/service/src/main/java/org/apache/griffin/core/measure/entity/ExternalMeasure.java index 2339df0..b6a9f0b 100644 --- a/service/src/main/java/org/apache/griffin/core/measure/entity/ExternalMeasure.java +++ b/service/src/main/java/org/apache/griffin/core/measure/entity/ExternalMeasure.java @@ -43,7 +43,7 @@ public class ExternalMeasure extends Measure { super(); } - public ExternalMeasure(String name, String description, String organization, String owner, String metricName,VirtualJob vj) { + public ExternalMeasure(String name, String description, String organization, String owner, String metricName, VirtualJob vj) { super(name, description, organization, owner); this.metricName = metricName; this.virtualJob = vj; http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/2aa58c0b/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 7a26d6a..d2b5995 100644 --- a/ui/angular/src/app/app.module.ts +++ b/ui/angular/src/app/app.module.ts @@ -42,6 +42,7 @@ import { DataassetComponent } from './dataasset/dataasset.component'; import { CreateJobComponent } from './job/create-job/create-job.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'; import { LoginComponent } from './login/login.component'; import { AngularMultiSelectModule } from 'angular2-multiselect-dropdown/angular2-multiselect-dropdown'; import { RuleComponent } from './measure/create-measure/pr/rule/rule.component'; @@ -89,6 +90,10 @@ const appRoutes: Routes = [ component:PrComponent }, { + path: 'createmeasurepub', + component:PubComponent + }, + { path: 'detailed/:name', component:DetailMetricComponent }, @@ -132,6 +137,7 @@ const appRoutes: Routes = [ CreateJobComponent, AcComponent, PrComponent, + PubComponent, LoginComponent, RuleComponent, TruncatePipe, http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/2aa58c0b/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 bbba430..622a0ec 100644 --- a/ui/angular/src/app/health/health.component.ts +++ b/ui/angular/src/app/health/health.component.ts @@ -175,8 +175,7 @@ export class HealthComponent implements OnInit { for (let mesName in this.mesWithJob) { var metricData = this.mesWithJob[mesName][0]; if ( - metricData.metricValues[0] != undefined && - metricData.type == "accuracy" + metricData.metricValues[0] != undefined && metricData.type == "accuracy" ) { var jobs = this.mesWithJob[mesName]; var node = null; @@ -196,7 +195,7 @@ export class HealthComponent implements OnInit { metricNode.details = JSON.parse( JSON.stringify(jobs[i].metricValues) ); - metricNode.name = jobs[i].name; + metricNode.name = mesName; //jobs[i].name;// to avoid same metricName metricNode.timestamp = jobs[i].metricValues[0].tmst; metricNode.dq = jobs[i].metricValues[0].value.matched / http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/2aa58c0b/ui/angular/src/app/measure/create-measure/create-measure.component.html ---------------------------------------------------------------------- diff --git a/ui/angular/src/app/measure/create-measure/create-measure.component.html b/ui/angular/src/app/measure/create-measure/create-measure.component.html index ab9909b..c3aa6a9 100644 --- a/ui/angular/src/app/measure/create-measure/create-measure.component.html +++ b/ui/angular/src/app/measure/create-measure/create-measure.component.html @@ -148,6 +148,37 @@ under the License. </div> </section> </div> + <div class="col-lg-6 col-md-6 col-sm-6 ruletypes"> + <section id="panel-3" class="panel panel-green" (click)="click('pub')"> + <div class="panel-heading"> + <span style="font-size:20px">Publish</span> + <span class="pull-right" style="font-size:20px"> + <span class="fa fa-arrow-circle-right"></span> + </span> + </div> + <div class="swMain panel-body"> + <label class="label-definition">Definition: Publish is the process of storing user's own quality data and visualizing it</label> + <ul style="border-radius:0; background: none"> + <li> + <div class="selected1child" style="cursor:default"> + <div class="stepNumber"> + 1 + </div> + <span class="stepDesc text-small"> Configuration </span> + </div> + </li> + </ul> + <div> + <ol> + <li>Set basic configuration for your model(name, system, threshold, etc.)</li> + </ol> + </div> + </div> + <div class="panel-footer stepDesc"> + <label>Example: any data</label> ... + </div> + </section> + </div> </div> <!--//row--> </div> http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/2aa58c0b/ui/angular/src/app/measure/create-measure/pub/pub.component.css ---------------------------------------------------------------------- diff --git a/ui/angular/src/app/measure/create-measure/pub/pub.component.css b/ui/angular/src/app/measure/create-measure/pub/pub.component.css new file mode 100644 index 0000000..194a251 --- /dev/null +++ b/ui/angular/src/app/measure/create-measure/pub/pub.component.css @@ -0,0 +1,506 @@ +/* +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'); */ + +.selected-list .c-list .c-token { + background: #6faece; +} + +div.tree div.tree-children::before, +div.tree::before { + content: ""; + position: absolute; + border-left: 1px dotted #23527c; + height: 100%; + top: -14px; + left: 12px +} + +tree-root { + color: #999; +} + +div.tree { + padding-left: 0; + margin-left: -5px +} + +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 +} + +label { + font-weight: normal; +} + +.container { + max-height: 40vh; + overflow-y: scroll; +} + +/* +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:nth-of-type(even) { + background-color: #1f1f1f; +} + +.table-striped>tbody>tr:nth-of-type(odd) { + background-color: #080808; +} + +.icon { + color: #fff; + position: absolute; + left: 50%; + top: 20%; +} + +#measureTable { + font-size: 18px; +} + +.po { + cursor: pointer; +} + +.ng2-st-actions-title .ng2-smart-title { + color: #1e6bb8; +} + +#measureTable .ng2-smart-titles { + background-color: #7D95CC; +} + +.pagination>li>a { + cursor: pointer; +} + +.swMain>ul { + display: table; + list-style: none; + margin: 0 0 20px; + padding: 10px 0; + position: relative; + width: 100%; + background: #f7f7f8; + border-radius: 5px +} + +.formStep { + background-color: #000000; + border-radius: 5px; + padding: 10px; + /*height:800px;*/ +} + +.swMain>ul li { + display: table-cell; + text-align: center; + width: 1% +} + +.swMain>ul li>a:before { + border-top: 4px solid #c8c7cc; + /* content: ""; */ + display: block; + font-size: 0; + height: 1px; + overflow: hidden; + position: relative; + top: 21px; + width: 100%; + z-index: 1 +} + +.onlyone:before { + left: 0 !important; + max-width: 100% !important; + width: 100% !important; +} + +.swMain>ul .stepNumber { + background-color: #fff; + border: 5px solid #c8c7cc; + border-radius: 100%; + color: #546474; + display: inline-block; + font-size: 15px; + height: 40px; + line-height: 30px; + position: relative; + text-align: center; + width: 40px; + z-index: 2 +} + +.swMain>ul li>a.selected .stepNumber { + border-color: #007AFF +} + +.swMain ul li>a.done .stepNumber { + border-color: #007AFF; + background-color: #007AFF; + color: #fff; + text-indent: -9999px +} + +.swMain ul li>a.done .stepNumber:before { + content: "\f00c"; + display: inline; + float: right; + font-family: FontAwesome; + font-weight: 300; + height: auto; + text-shadow: none; + margin-right: 7px; + text-indent: 0 +} + +.swMain ul li>a.done.wait .stepNumber { + background-color: #F6F6F6!important; + color: #CCC!important; + text-indent: 0!important +} + +.swMain ul li>a.done.wait .stepNumber:before { + content: ""!important +} + +.swMain>ul li .stepDesc { + color: #8e8e93; + display: block; + font-size: 14px; + margin-top: 4px; + max-width: 100%; + table-layout: fixed; + text-align: center; + word-wrap: break-word; + z-index: 104 +} + +.swMain li>a.done .stepDesc, +.swMain>ul li>a.selected .stepDesc { + /*color: #2B3D53*/ + color: #007AFF +} + +.swMain>ul li>a.disabled { + cursor: default +} + +.swMain .progress { + margin-bottom: 30px +} + +.swMain .stepContainer { + height: auto!important +} + +.swMain .y-scrollable { + overflow-y: auto; + overflow-x: hidden; + max-height: 600px; +} + +fieldset { + border: 1px solid #e6e8e8; + border-radius: 5px; + margin: 20px 0; + padding: 25px; + position: relative; + min-width: 0; + display: block; +} + +fieldset legend { + background-color: #000000; + left: 10px; + padding: 0 10px; + position: absolute; + top: -12px; + color: #fff; + font-weight: 400; + width: auto!important; + border: none!important; +} + +.btn-o { + background: 0 0!important; +} + +.btn-wide { + min-width: 120px; +} + +.highlight { + background: rgba(255, 230, 0, 0.5); + padding: 3px 5px; + margin: -3px -5px; + line-height: 1.7; + word-break: break-word; + /*border-radius: 3px;*/ + /*display:inline-block;*/ +} + +.label-definition { + color: #fff; +} + +.formStep>.stepDesc { + color: #b2c831; +} + +.formStep>.container-fluid { + /*position:relative;*/ +} + +.btn-container { + height: 50px; + /*position: absolute; + bottom: 10;*/ +} + +.panel-disabled { + border-color: #B9D3DF; +} + +.panel-disabled>.panel-heading { + background-color: #B9D3DF; + border-color: #B9D3DF; +} + +.panel-body>ul { + border-radius: 0; + background: none; + margin: 0; +} + + +.panel-green { + border-color: #5cb85c; +} + +.panel-green .panel-heading { + border-color: #5cb85c; + color: #fff; + background-color: #5cb85c; +} + +.panel-green a { + color: #5cb85c; +} + +.panel-green a:hover { + color: #3d8b3d; +} + +.panel-red { + border-color: #d9534f; +} + +.panel-red .panel-heading { + border-color: #d9534f; + color: #fff; + background-color: #d9534f; +} + +.panel-red a { + color: #d9534f; +} + +.panel-red a:hover { + color: #b52b27; +} + +.panel-yellow { + border-color: #f0ad4e; +} + +.panel-yellow .panel-heading { + border-color: #f0ad4e; + color: #fff; + background-color: #f0ad4e; +} + +.panel-yellow a { + color: #f0ad4e; +} + +.panel-yellow a:hover { + color: #df8a13; +} + +.viewrule-content { + border: 1px solid #fff; + border-radius: 4px; + padding: 10px; +} + +.ruletypes>.panel { + cursor: pointer +} + +.ruletypes>.panel:hover { + box-shadow: 3px 3px 5px 6px #ccc; + /* Opera 10.5, IE 9, Firefox 4+, Chrome 6+, iOS 5 */ + -webkit-box-shadow: 3px 3px 5px 6px #ccc; + /* Safari 3-4, iOS 4.0.2 - 4.2, Android 2.3+ */ + -moz-box-shadow: 3px 3px 5px 6px #ccc; + /* Firefox 3.5 - 3.6 */ +} + +.createrule-hint { + color: #b2c831; + padding-top: 10px; +} + + +::-webkit-scrollbar { + width: 6px; +} + +::-webkit-scrollbar-track { + background-color: #eaeaea; + /*background-color: #0a0a0a;*/ + border-left: 1px solid #ccc; +} + +::-webkit-scrollbar-thumb { + background-color: #ccc; +} + +::-webkit-scrollbar-thumb:hover { + background-color: #aaa; +} + +.disabled { + pointer-events: none; + cursor: default; + opacity: 0.6; +} + +.test-result { + border-radius: 5px; + padding: 1px 5px; +} + +.delete-alert { + text-align: left; + color: white; + font-size: 150%; +} + +a { + color: white; +} http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/2aa58c0b/ui/angular/src/app/measure/create-measure/pub/pub.component.html ---------------------------------------------------------------------- diff --git a/ui/angular/src/app/measure/create-measure/pub/pub.component.html b/ui/angular/src/app/measure/create-measure/pub/pub.component.html new file mode 100644 index 0000000..b6e847f --- /dev/null +++ b/ui/angular/src/app/measure/create-measure/pub/pub.component.html @@ -0,0 +1,211 @@ +<!-- +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" #prForm="ngForm" novalidate> + <div id="wizard" class="swMain"> + <ul> + <li> + <a class="selected"> + <div class="stepNumber"> + 1 + </div> + <span class="stepDesc text-small"> Configuration </span> + </a> + </li> + </ul> + </div> + <div id="step-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" style="margin-top:30px;"> + <div class="form-group" [ngClass]="{'has-error':prName.dirty&&prName.invalid, 'has-success':prName.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)]="newMeasure.name" #prName="ngModel" name="prName" placeholder="Please input the measure name" required pattern="^[a-zA-Z0-9_-]*$"> + <span class="error text-small block " *ngIf="prName.dirty && (prName.errors?.required)">Measure Name is required</span> + <span class="error text-small block " *ngIf="prName.dirty && (prName.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" [ngClass]="{'has-error':mName.dirty&&mName.invalid, 'has-success':mName.valid}"> + <label class="col-md-2 col-lg-2 col-sm-2 control-label"> + Metric 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)]="newMeasure.metricName" #mName="ngModel" name="mName" placeholder="Please input the metric name" required pattern="^[a-zA-Z0-9_-]*$"> + <span class="error text-small block " *ngIf="mName.dirty && (mName.errors?.required)">Metric Name is required</span> + <span class="error text-small block " *ngIf="mName.dirty && (mName.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" [ngClass]="{'has-error':mName.dirty&&mName.invalid, 'has-success':mName.valid}"> + <label class="col-md-2 col-lg-2 col-sm-2 control-label"> + Dq Type<span class="symbol required"></span>: + </label> + <div class="col-md-10 col-lg-10 col-sm-10 "> + <select [(ngModel)]="newMeasure.dqType" name="dqTypeOptions[{{i}}]" class="form-control input-sm" placeholder="Visual Type" required> + <option *ngFor="let t of dqTypeOptions" value="{{t}}">{{t}}</option> + </select> + <span class="error text-small block " *ngIf="mName.dirty && (mName.errors?.required)">Metric Name is required</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)]="newMeasure.description" 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)]="newMeasure.measureType" disabled required name="type"> + <option>{{newMeasure.measureType}}</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"> + Owner: + </label> + <div class="col-md-10 col-lg-10 col-sm-10"> + <input type="text" class="form-control" name="owner" disabled [(ngModel)]="newMeasure.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" (click)="submit(prForm)" 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" (click)="hide()">×</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 "> + {{newMeasure.name}} + </div> + </div> + <div class="row"> + <label class="col-md-4 col-lg-4 col-sm-4"> + Metric Name: + </label> + <div class="col-md-8 col-lg-8 col-sm-8 "> + {{newMeasure.metricName}} + </div> + </div> + <div class="row"> + <label class="col-md-4 col-lg-4 col-sm-4"> + Dq Type: + </label> + <div class="col-md-8 col-lg-8 col-sm-8 "> + {{newMeasure.dqType}} + </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 "> + {{newMeasure.description}} + </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 "> + {{newMeasure.measureType}} + </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"> + {{newMeasure.owner}} + </div> + </div> + </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/2aa58c0b/ui/angular/src/app/measure/create-measure/pub/pub.component.spec.ts ---------------------------------------------------------------------- diff --git a/ui/angular/src/app/measure/create-measure/pub/pub.component.spec.ts b/ui/angular/src/app/measure/create-measure/pub/pub.component.spec.ts new file mode 100644 index 0000000..0b74802 --- /dev/null +++ b/ui/angular/src/app/measure/create-measure/pub/pub.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 { PubComponent } from './pub.component'; + +describe('PrComponent', () => { + let component: PubComponent; + let fixture: ComponentFixture<PubComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ PubComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(PubComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should be created', () => { + expect(component).toBeTruthy(); + }); +}); http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/2aa58c0b/ui/angular/src/app/measure/create-measure/pub/pub.component.ts ---------------------------------------------------------------------- diff --git a/ui/angular/src/app/measure/create-measure/pub/pub.component.ts b/ui/angular/src/app/measure/create-measure/pub/pub.component.ts new file mode 100644 index 0000000..99871eb --- /dev/null +++ b/ui/angular/src/app/measure/create-measure/pub/pub.component.ts @@ -0,0 +1,216 @@ +/* +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 { ServiceService } from "../../../service/service.service"; +import { TREE_ACTIONS, KEYS, IActionMapping, ITreeOptions } from "angular-tree-component"; +import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; +import { ToasterModule, ToasterService, ToasterContainerComponent } from "angular2-toaster"; +import * as $ from "jquery"; +import { HttpClient } from "@angular/common/http"; +import { Router } from "@angular/router"; +import { DataTableModule } from "angular2-datatable"; +import { AfterViewChecked, ElementRef } from "@angular/core"; +import { AngularMultiSelectModule } from "angular2-multiselect-dropdown/angular2-multiselect-dropdown"; +import { ConfigurationComponent } from "../configuration/configuration.component"; + +interface pubMeasure { + name: string; + metricName: string; + description: string; + measureType: string; + dqType: string; + owner: string +} +export function createPubMeasure(name: string, + metricName: string, + description: string, + measureType: string, + dqType: string, + owner: string) { + return { + name, + metricName, + description, + measureType, + dqType, + owner + } +} +@Component({ + selector: "app-pub", + templateUrl: "./pub.component.html", + providers: [ServiceService], + styleUrls: ["./pub.component.css"] +}) +export class PubComponent implements AfterViewChecked, OnInit { + newMeasure = createPubMeasure("", "", "","external","accuracy","test"); + dqTypeOptions =["accuracy"]; + createResult: any; + 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(); + } + } + + onResize(event) { + this.resizeWindow(); + } + + resizeWindow() { + var stepSelection = ".formStep"; + $(stepSelection).css({ + height: window.innerHeight - $(stepSelection).offset().top + }); + $("fieldset").height( + $(stepSelection).height() - + $(stepSelection + ">.stepDesc").height() - + $(".btn-container").height() - + 130 + ); + $(".y-scrollable").css({ + height: $("fieldset").height() + }); + } + + + formValidation = function(step) { + if (step == undefined) { + step = this.currentStep; + } + if (step == 1) { + return this.selection && this.selection.length > 0; + } else if (step == 2) { + var len = 0; + var selectedlen = 0; + for (let key in this.selectedItems) { + selectedlen++; + len = this.selectedItems[key].length; + if (len == 0) { + return false; + } + } + return this.selection.length == selectedlen ? true : false; + } else if (step == 3) { + return true; + } else if (step == 4) { + } + return false; + }; + + submit(form) { + if (!form.valid) { + this.toasterService.pop( + "error", + "Error!", + "please complete the form in this step before proceeding" + ); + return false; + } + this.visible = true; + setTimeout(() => (this.visibleAnimate = true), 100); + } + + + + save() { + var measure2Save ={ + name:this.newMeasure.name, + metricName: this.newMeasure.metricName, + "measure.type":this.newMeasure.measureType, + description:this.newMeasure.description, + "dq.type":this.newMeasure.dqType, + owner:this.newMeasure.owner + } + var addModels = this.serviceService.config.uri.addModels; + this.http.post(addModels, measure2Save).subscribe( + data => { + this.createResult = data; + this.hide(); + this.router.navigate(["/measures"]); + }, + err => { + let response = JSON.parse(err.error); + if(response.code === '40901'){ + this.toasterService.pop("error", "Error!", "Measure name already exists!"); + } else { + this.toasterService.pop("error", "Error!", "Error when creating measure"); + } + console.log("Error when creating measure"); + } + ); + } + + options: ITreeOptions = { + displayField: "name", + isExpandedField: "expanded", + idField: "id", + actionMapping: { + mouse: { + click: (tree, node, $event) => { + if (node.hasChildren) { + + TREE_ACTIONS.TOGGLE_EXPANDED(tree, node, $event); + } else if (node.data.cols) { + + + } + } + } + }, + animateExpand: true, + animateSpeed: 30, + animateAcceleration: 1.2 + }; + + nodeList: object[]; + nodeListTarget: object[]; + + constructor( + private elementRef: ElementRef, + toasterService: ToasterService, + private http: HttpClient, + private router: Router, + public serviceService: ServiceService + ) { + this.toasterService = toasterService; + } + + ngOnInit() { + var allDataassets = this.serviceService.config.uri.dataassetlist; + this.http.get(allDataassets).subscribe(data => { + this.nodeList = new Array(); + + }); + + } + ngAfterViewChecked() { + this.resizeWindow(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/2aa58c0b/ui/angular/src/app/measure/measure-detail/measure-detail.component.html ---------------------------------------------------------------------- diff --git a/ui/angular/src/app/measure/measure-detail/measure-detail.component.html b/ui/angular/src/app/measure/measure-detail/measure-detail.component.html index e6ccacb..fc7d1df 100644 --- a/ui/angular/src/app/measure/measure-detail/measure-detail.component.html +++ b/ui/angular/src/app/measure/measure-detail/measure-detail.component.html @@ -48,6 +48,14 @@ under the License. {{ruleData.type}} </div> </div> + <div class="row" *ngIf="ruleData.dqType"> + <label class="col-xs-4"> + Dq Type: + </label> + <div class="col-xs-8 " style="color: #fff"> + {{ruleData.dqType}} + </div> + </div> <div class="row" *ngIf="ruleData.type=='accuracy'"> <label class="col-xs-4"> Source: http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/2aa58c0b/ui/angular/src/app/measure/measure-detail/measure-detail.component.ts ---------------------------------------------------------------------- diff --git a/ui/angular/src/app/measure/measure-detail/measure-detail.component.ts b/ui/angular/src/app/measure/measure-detail/measure-detail.component.ts index 42c41af..56d982a 100644 --- a/ui/angular/src/app/measure/measure-detail/measure-detail.component.ts +++ b/ui/angular/src/app/measure/measure-detail/measure-detail.component.ts @@ -85,6 +85,7 @@ export class MeasureDetailComponent implements OnInit { this.ruleData = data; if (this.ruleData["measure.type"] === "external") { this.ruleData.type = this.ruleData["measure.type"]; + this.ruleData.dqType = this.ruleData["dq.type"]; } else{ this.ruleData.type = this.ruleData["dq.type"]; this.currentrule = this.ruleData["evaluate.rule"].rules; http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/2aa58c0b/ui/angular/src/app/measure/measure.component.css ---------------------------------------------------------------------- diff --git a/ui/angular/src/app/measure/measure.component.css b/ui/angular/src/app/measure/measure.component.css index d9218f6..7381878 100644 --- a/ui/angular/src/app/measure/measure.component.css +++ b/ui/angular/src/app/measure/measure.component.css @@ -385,3 +385,15 @@ fieldset legend { a { color: white; } + +.swMain li>div.done .stepDesc, +.swMain>ul li>div.selected1child .stepDesc { + color: #007AFF +} +.swMain li>div.done:before, +.swMain>ul li>div.selected1child:before { + border-color: #007AFF +} +.swMain>ul li>div.selected1child .stepNumber { + border-color: #007AFF +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/2aa58c0b/ui/angular/src/app/metric/metric.component.html ---------------------------------------------------------------------- diff --git a/ui/angular/src/app/metric/metric.component.html b/ui/angular/src/app/metric/metric.component.html index bab752c..52023ca 100644 --- a/ui/angular/src/app/metric/metric.component.html +++ b/ui/angular/src/app/metric/metric.component.html @@ -29,14 +29,15 @@ under the License. </span> </div> </div> - <div *ngFor="let outerItems of finalData;let parent=index"> - <div class="row"> - <div class="col-sm-12 col-md-12 col-lg-12"> + <div class="col-sm-5 chartItem" *ngFor="let outerItems of finalData;let parent=index" style="margin-bottom:30px;margin-right:15px;"> + <div class="row"> + <div style="text-align: center;" > <h4>{{outerItems.name}}</h4> </div> </div> <div class="row"> - <div class="col-sm-6 col-md-4 col-xs-12 col-lg-3 chartItem" *ngFor="let items of outerItems.metrics;let i=index;" style="margin-bottom:30px;"> + <!-- <div class="col-sm-6 col-md-4 col-xs-12 col-lg-3 chartItem" *ngFor="let items of outerItems.metrics;let i=index;" style="margin-bottom:30px;"> --> + <div *ngFor="let items of outerItems.metrics;let i=index;"> <div class="row-fluid" style="cursor: pointer;"> <div id="thumbnail{{parent}}-{{i}}" class="thumb-chart" style="border: 2px solid;" echarts [options]="getOption(parent,i)" (click)="goTo(parent,i)"></div> </div> http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/2aa58c0b/ui/angular/src/app/metric/metric.component.ts ---------------------------------------------------------------------- diff --git a/ui/angular/src/app/metric/metric.component.ts b/ui/angular/src/app/metric/metric.component.ts index 7df1f84..63bc8ae 100644 --- a/ui/angular/src/app/metric/metric.component.ts +++ b/ui/angular/src/app/metric/metric.component.ts @@ -57,8 +57,7 @@ export class MetricComponent implements OnInit { for (let mesName in this.mesWithJob) { var metricData = this.mesWithJob[mesName][0]; if ( - metricData.metricValues[0] != undefined && - metricData.type == "accuracy" + metricData.metricValues[0] != undefined && metricData.type == "accuracy" ) { var jobs = this.mesWithJob[mesName]; var node = null; http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/2aa58c0b/ui/angular/src/app/sidebar/sidebar.component.ts ---------------------------------------------------------------------- diff --git a/ui/angular/src/app/sidebar/sidebar.component.ts b/ui/angular/src/app/sidebar/sidebar.component.ts index 30ae045..8a6fef5 100644 --- a/ui/angular/src/app/sidebar/sidebar.component.ts +++ b/ui/angular/src/app/sidebar/sidebar.component.ts @@ -105,8 +105,7 @@ export class SidebarComponent implements OnInit { for (let mesName in this.mesWithJob) { var metricData = this.mesWithJob[mesName][0]; if ( - metricData.metricValues[0] != undefined && - metricData.type == "accuracy" + metricData.metricValues[0] != undefined && metricData.type == "accuracy" ) { var jobs = this.mesWithJob[mesName]; var node = null;
