Service instance topology front-end development 30/82230/1
authorguochuyicmri <guochuyi@chinamobile.com>
Thu, 14 Mar 2019 09:32:28 +0000 (17:32 +0800)
committerguochuyicmri <guochuyi@chinamobile.com>
Thu, 14 Mar 2019 09:32:49 +0000 (17:32 +0800)
Change-Id: Ie39ede5583468def6ddfdbf6aa15b44aca61b982
Issue-ID: USECASEUI-224
Signed-off-by: guochuyicmri <guochuyi@chinamobile.com>
18 files changed:
usecaseui-portal/src/app/app.module.ts
usecaseui-portal/src/app/ccvpn-creation/ccvpn-creation.component.css
usecaseui-portal/src/app/ccvpn-creation/ccvpn-creation.component.html
usecaseui-portal/src/app/ccvpn-creation/ccvpn-creation.component.ts
usecaseui-portal/src/app/components/e2e-creation/e2e-creation.component.html
usecaseui-portal/src/app/components/e2e-creation/e2e-creation.component.less
usecaseui-portal/src/app/components/e2e-creation/e2e-creation.component.ts
usecaseui-portal/src/app/components/e2e-detail/e2e-detail.component.html [new file with mode: 0644]
usecaseui-portal/src/app/components/e2e-detail/e2e-detail.component.less [new file with mode: 0644]
usecaseui-portal/src/app/components/e2e-detail/e2e-detail.component.spec.ts [new file with mode: 0644]
usecaseui-portal/src/app/components/e2e-detail/e2e-detail.component.ts [new file with mode: 0644]
usecaseui-portal/src/app/services/services-list/services-list.component.html
usecaseui-portal/src/app/services/services-list/services-list.component.ts
usecaseui-portal/src/assets/images/create-e2e.png [new file with mode: 0644]
usecaseui-portal/src/assets/images/create-ns.png [new file with mode: 0644]
usecaseui-portal/src/assets/images/create-vnf.png [new file with mode: 0644]
usecaseui-portal/src/assets/images/domain1.png [new file with mode: 0644]
usecaseui-portal/src/assets/images/site.png

index 8926bad..76fe5d4 100644 (file)
@@ -50,6 +50,7 @@ import { HomesService } from './homes.service';
 import { onboardService } from './onboard.service';
 import { networkHttpservice } from './networkHttpservice.service';
 import { PerformanceDetailsComponent } from './components/performance-details/performance-details.component';
+import { E2eDetailComponent } from './components/e2e-detail/e2e-detail.component';
 
 @NgModule({
   providers   : [ 
@@ -83,6 +84,7 @@ import { PerformanceDetailsComponent } from './components/performance-details/pe
     CcvpnNetworkComponent,
     CcvpnDetailComponent,
     CcvpnCreationComponent,
+    E2eDetailComponent,
     PerformanceDetailsComponent,
   ],
   imports: [
index ceaaaf3..e0ce4b9 100644 (file)
@@ -294,13 +294,17 @@ hr {
     color: #06A7E2;
     font-size: 16px;
     font-weight: 500;
-    border-left: 10px solid #f3f3f3;
     margin-bottom: 30px;
-    box-shadow: 0px 10px 15px 2px rgba(222, 222, 222, 0.5);
+    /*box-shadow: 0px 10px 15px 2px rgba(222, 222, 222, 0.5);*/
+    /*background: url("../../../assets/images/ccvpn-createbanner.png") no-repeat;*/
+    /*background-size: 100% 100%;*/
+    background:linear-gradient(180deg,rgba(183, 230, 247, 1) 0%,rgba(214, 240, 254, 1) 100%);
+    /*background-color:rgba(188, 231, 248, 1);*/
+    border-radius:4px;
 }
 .model .chart #createChart {
     width: 100%;
-    /*height: 50vh;*/
+    height: 220px;
     margin-top: 20px;
     position: relative;
 }
@@ -317,5 +321,5 @@ hr {
 }
 .model .creation .sotnvpn,.model .creation .site,.model .creation .sitegroup{
     background: #fff;
-    padding: 30px;
+    padding: 30px 30px 0 30px;
 }
index 05a29a7..f190628 100644 (file)
     </div>
     <!-- chart -->
     <div class="chart">
-        Create Service
+       <span style="padding: 25px;display: inline-block;">
+            Create Service
         {{createParams.commonParams.templateType}}
+       </span>
         <div id="createChart">
             <svg width="100%" height="100%">
-                <line *ngFor="let item of lines" x1=50% y1="45%" [attr.x2]="item.x2" y2="72%"
-                      style="stroke:#3fa8eb;stroke-width:2"/>
-                <image xlink:href="./assets/images/cloud-site.png"
-                       x="25%" y="30%" width="50%"/>
-                <!-- <text dx="42%" dy="45%" style="font:700 18px 'Arial';fill:#666">{{createParams.commonParams.templateType}}</text> -->
-                <text dx="42%" dy="45%" style="font:700 18px 'Arial';fill:#666"></text>
-                <g *ngFor="let item of siteImage"
-                   (mouseover)="showSite($event,item)"
-                   (mousemove)="moveSite($event,item)"
-                   (mouseout)="hideSite($event)">
-                    <image
-                            xlink:href="./assets/images/site.png"
-                            [attr.x]="item.x" y="65%" width="80px"/>
-                    <text [attr.dx]="item.x + 25" dy="72%" style="font:700 16px 'Arial';fill:#666">{{ item.name }}
-                    </text>
-                </g>
+                <image id="domain"  xlink:href="../../assets/images/domain1.png" style="width: 15%"
+                       x="40%" y="0" />
+                <!--<line *ngFor="let item of lines" [attr.x1]="item.x1" [attr.y1]="item.y1" [attr.x2]="item.x2" [attr.y2]="item.y2"-->
+                      <!--style="stroke:#3fa8eb;stroke-width:2"/>-->
+
+                <!--&lt;!&ndash; <text dx="42%" dy="45%" style="font:700 18px 'Arial';fill:#666">{{createParams.commonParams.templateType}}</text> &ndash;&gt;-->
+                <!--&lt;!&ndash;<text dx="42%" dy="45%" style="font:700 18px 'Arial';fill:#666"></text>&ndash;&gt;-->
+                <!--<g *ngFor="let item of siteImage"-->
+                   <!--(mouseover)="showSite($event,item)"-->
+                   <!--(mousemove)="moveSite($event,item)"-->
+                   <!--(mouseout)="hideSite($event)">-->
+                    <!--<image-->
+                            <!--xlink:href="../../assets/images/site.png"-->
+                            <!--[attr.x]="item.x" [attr.y]="item.y" width="50px"/>-->
+                    <!--&lt;!&ndash;<text [attr.dx]="item.x + 25" dy="72%" style="font:700 16px 'Arial';fill:#666">{{ item.name }}&ndash;&gt;-->
+                    <!--&lt;!&ndash;</text>&ndash;&gt;-->
+                <!--</g>-->
+                <!--<g *ngFor="let item of siteImage"-->
+                   <!--(mouseover)="showSite($event,item)"-->
+                   <!--(mousemove)="moveSite($event,item)"-->
+                   <!--(mouseout)="hideSite($event)">-->
+                    <!--<image-->
+                            <!--xlink:href="../../assets/images/site.png"-->
+                            <!--[attr.x]="item.x" [attr.y]="item.y" width="50px"/>-->
+                    <!--&lt;!&ndash;<text [attr.dx]="item.x + 25" dy="72%" style="font:700 16px 'Arial';fill:#666">{{ item.name }}&ndash;&gt;-->
+                    <!--&lt;!&ndash;</text>&ndash;&gt;-->
+                <!--</g>-->
 
             </svg>
             <!-- <p class="siteNameP" [ngStyle]="siteNameStyle">{{ siteName }}</p> -->
@@ -81,9 +94,6 @@
                                 <nz-option nzValue="standard" nzLabel="standard"></nz-option>
                             </nz-select>
                         </li>
-                        <li><span style="width: 130px">Reroute Enabled:</span>
-                            <nz-switch [(ngModel)]="sotnInfo.reroute"></nz-switch>
-                        </li>
                         <li><span>Service Level Specification:</span> <input nz-input [(ngModel)]="sotnInfo.SLS"></li>
                         <li><span>Dual Link:</span>
                             <nz-select style="width: 234px;height: 40px" [(ngModel)]="sotnInfo.dualLink" nzAllowClear
                         <li><span>EIR:</span> <input nz-input [(ngModel)]="sotnInfo.EIR"></li>
                         <li><span>CBS:</span> <input nz-input [(ngModel)]="sotnInfo.CBS"></li>
                         <li><span>EBS:</span> <input nz-input [(ngModel)]="sotnInfo.EBS"></li>
+                        <li><span style="width: 130px">Reroute Enabled:</span>
+                            <nz-switch [(ngModel)]="sotnInfo.reroute"></nz-switch>
+                        </li>
                         <li><span>Color Aware:</span>
                             <nz-switch [(ngModel)]="sotnInfo.colorAware"></nz-switch>
                         </li>
index 3a478e0..40ea977 100644 (file)
@@ -13,7 +13,9 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 */
-import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
+import {Component, OnInit, Input, Output, EventEmitter} from '@angular/core';
+import * as d3 from 'd3';
+import * as $ from 'jquery';
 import { MyhttpService } from '../myhttp.service';
 
 @Component({
@@ -294,25 +296,134 @@ export class CcvpnCreationComponent implements OnInit {
     // this.deleteGroupSite(groupIndex + 1); //The first line number is 1 when deleting
   }
 
-  // site Node graphic depiction
-  lines=[];
-  siteImage=[];
-  drawImage(sitelist){
-    let cx = 200;
-    let cy = 200;
-    let r = 180;
-    let startAngle = -210 * (Math.PI/180);
-    let step = sitelist.length > 1 ? 120/(sitelist.length-1) * (Math.PI/180) : 1;
-
-    this.lines = sitelist.map((item,index)=>{
-      let x = cx + Math.cos(startAngle - step*index)*r;
-      let y = cy + Math.sin(startAngle - step*index)*r;
-      return {img:"line",site:item.baseData.name,x1:cx,y1:cy,x2:x,y2:y}
-    })
-    this.siteImage = this.lines.map((item)=>{
-      return {img:"site",name:item.site,x:item.x2 - 40,y:item.y2 - 40}
-    })
-  }
+// Site node graphic depiction
+    lines = [];
+    siteImage = [];
+    tpImage = [];
+    imgmap = {
+        '1': './assets/images/domain1.png',
+        '2': './assets/images/site.png'
+    };
+
+    drawImage(sitelist) {
+        let cx = 550;
+        let cy = 0;
+        let innerx1 = 720;
+        let innery1 = 80;
+        let ox = 950;
+        let oy = 0;
+        let innerx2 = 780;
+        let innery2 = 60;
+        let lateX1 = Math.random() * 30 + 55;
+        let lateY1 = Math.random() * -20 + 10;
+        let lateX2 = 15;
+        let lateY2 = 20;
+        // let step = sitelist.length > 1 ?sitelist.length: 1;
+
+        this.lines = sitelist.map((item, index) => {
+            let step = index + 1;
+            let x = cx;
+            let y = cy;
+            let innerX = innerx1;
+            let innerY = innery1;
+            if (step % 2 != 0) {
+                x = cx;
+                y = cy;
+                innerX = innerx1;
+                innerY = innery1;
+                if (step == 1) {
+                    innerX = innerx1;
+                    innerY = innery1;
+                } else {
+                    x = cx - lateX1 * Math.ceil((step / 2)) >= 0 ? cx - lateX1 * Math.ceil((step / 2)) : -(cx - lateX1 * Math.ceil((step / 2)));
+                    y = cy + lateY1 * step >= 0 ? cy + lateY1 * step : -(cy + lateY1 * step);
+                    innerX = this.lines[step - 3].innerX - lateX2;
+                    innerY = this.lines[step - 3].innerY + lateY2;
+                }
+            } else {
+                x = ox;
+                y = oy;
+                innerX = innerx2;
+                innerY = innery2;
+                if (step / 2 == 1) {
+                    innerX = innerx2;
+                    innerY = innery2;
+                } else {
+                    x = ox + lateX1 * (step / 2) >= 0 ? ox + lateX1 * (step / 2) : -(ox + lateX1 * (step / 2));
+                    y = oy + lateY1 * step >= 0 ? oy + lateY1 * step : -(oy + lateY1 * step);
+                    innerX = this.lines[step - 3].innerX + lateX2;
+                    innerY = this.lines[step - 3].innerY + lateY2;
+                }
+            }
+            return {
+                img: "line",
+                site: item.baseData.name,
+                x1: x + 25,
+                y1: y + 25,
+                x2: innerX,
+                y2: innerY,
+                innerX: innerX,
+                innerY: innerY
+            }
+        });
+
+        console.log(this.lines)
+        this.render(this.imgmap, this.lines);
+    }
+
+    render(imgmap, lines) {
+
+        //enter
+        var svg = d3.select("svg"),
+            _g_lines = svg.selectAll('line.line')
+                .data(lines)
+                .enter()
+                .append('line')
+                .style('stroke', '#3fa8eb'
+                )
+                .style('stroke-width', 2)
+                .attr('class', 'line')
+                .attr("x1", function (d) {
+                    return d.x1;
+                })
+                .attr("y1", function (d) {
+                    return d.y1;
+                })
+                .attr("x2", function (d) {
+                    return d.x2;
+                })
+                .attr("y2", function (d) {
+                    return d.y2;
+                }),
+            _g_site = svg.selectAll('g.g-site')
+                .data(lines)
+                .enter()
+                .append('g')
+                .style('cursor', 'pointer')
+                .attr('class', 'g-site');
+        _g_site.append('image')
+            .style("width", "50px")
+            .attr('xlink:href', function (d) {
+                return imgmap[2];
+            })
+            .attr("x", function (d) {
+                return d.x1 - 25;
+            })
+            .attr("y", function (d) {
+                return d.y1 - 25;
+            })
+
+        //quit
+        svg.selectAll("g.g-site")
+            .data(lines)
+            .exit() //Select a picture without bound data
+            .remove();
+        svg.selectAll("line.line")
+            .data(lines)
+            .exit() //Select the connection without binding data
+            .remove();
+
+    }
 
   siteName=null;
   siteNameStyle = {
index 4a2f2f6..d85eb16 100644 (file)
@@ -15,7 +15,7 @@
 -->
 <!--<h3 class="title"> Services List </h3>-->
 <div class="model creation-model">
-  
+  <!-- Create data -->
     <div class="top-title">
         <h3 class="title fl">{{createParams.commonParams.templateType}} Instance Creation</h3>
         <div class="fl" style="width: 20%">
         <div id="createChart">
             <svg width="100%" height="100%">
 
-                <image xlink:href="./assets/images/cloud-site.png"
-                       x="25%" y="30%" width="50%"/>
+                <!--<image xlink:href="./assets/images/create-e2e.png"-->
+                       <!--x="40%" y="16%" />-->
 
             </svg>
 
index ea7c5ba..c2b441c 100644 (file)
@@ -138,5 +138,14 @@ hr {
         height: 95%;
         box-shadow: 0px 10px 35px 10px rgba(222, 222, 222, 0.5);
         margin-right: 40px;
+        //background: url("../../../assets/images/ccvpn-createbanner2.png") no-repeat -45px -10px;
+        //background-size: 110% 110%;
+        background:linear-gradient(180deg,rgba(183, 230, 247, 1) 0%,rgba(214, 240, 254, 1) 100%);
+        //background-color: rgba(188, 231, 248, 1);
+        border-radius: 4px;
+        #createChart{
+            height: 100%;
+            width: 100%;
+        }
     }
 }
index 261aa3f..289d122 100644 (file)
@@ -15,6 +15,7 @@
 */
 import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
 import { MyhttpService } from '../../myhttp.service';
+import * as d3 from 'd3';
 
 @Component({
   selector: 'app-e2e-creation',
@@ -29,6 +30,7 @@ export class E2eCreationComponent implements OnInit {
     this.getTemParameters();
     this.getVimInfo();
     this.getSdnControllers();
+    // this.drawImage("e2e");
     console.log(this.createParams);
   }
 
@@ -82,6 +84,7 @@ export class E2eCreationComponent implements OnInit {
         console.log(this.nsTemplateParameters);
       }
 
+      this.drawImage(type)
 
     })
   }
@@ -211,4 +214,158 @@ export class E2eCreationComponent implements OnInit {
     this.e2eCloseCreate.emit(); 
   }
 
+    roote2e = {
+        "name": "e2e",
+        "type": "e2e",
+        "children":
+            [
+                {
+                    "name": "ns",
+                    "type": "ns",
+                    "children":
+                        [
+                            {
+                                "name": "vnf",
+                                "type": "vnf",
+                            },
+                            {
+                                "name": "vnf",
+                                "type": "vnf",
+                            }
+                        ]
+                },
+                {
+                    "name": "ns",
+                    "type": "ns",
+                    "children":
+                        [
+                            {
+                                "name": "vnf",
+                                "type": "vnf",
+                            },
+                            {
+                                "name": "vnf",
+                                "type": "vnf",
+                            }
+                        ]
+                }]
+    }
+
+    rootns = {
+                "name": "ns",
+                "type": "ns",
+                "children":
+                    [
+                        {
+                            "name": "vnf",
+                            "type": "vnf",
+                        },
+                        {
+                            "name": "vnf",
+                            "type": "vnf",
+                        }
+                    ]
+            }
+
+    imgmap = {
+        '1': './assets/images/create-e2e.png',
+        '2': './assets/images/create-ns.png',
+        '3': './assets/images/create-vnf.png',
+    };
+
+    drawImage(type) {
+        if (type == "e2e") {
+            this.render(this.roote2e, this.imgmap)
+        } else if (type == "ns") {
+            this.render(this.rootns, this.imgmap)
+        }
+
+
+    }
+
+    render(data, imgmap) {
+        var width = document.getElementById("createChart").clientWidth,
+            height = document.getElementById("createChart").clientHeight;
+        var cluster = d3.layout.tree()
+            .size([width, height]);
+        var diagonal = d3.svg.diagonal()
+            .projection(function (d) {
+                return [d.x-18, d.y+40];
+            });
+        console.log(diagonal)
+        var svg = d3.select("svg");
+
+        //marker
+        var marker =
+            svg.append("marker")
+                .attr("id", "resolved")
+                .attr("markerUnits", "strokeWidth")
+                .attr("markerUnits", "userSpaceOnUse")
+                .attr("viewBox", "0 -5 10 10")
+                .attr("refX", 22)
+                .attr("refY", 0)
+                .attr("markerWidth", 20)
+                .attr("markerHeight", 20)
+                .attr("orient", "auto")
+                .attr("stroke-width", 1)
+                .append("circle")
+                .attr("cx", 5)
+                .attr("cy", 0)
+                .attr("r", 2)
+                .attr("stroke-width", 1)
+                .style("stroke", "#2F8BF7")
+                .attr('fill', 'white');
+        var i = 0;
+        var nodes = cluster.nodes(data).reverse();
+        nodes.forEach(function (d) {
+            d.y = d.depth * 200+100;
+
+        });
+
+        var links = cluster.links(nodes);
+
+        var linkEnter = svg.selectAll("path.link")
+            .data(links);
+
+        linkEnter.enter().append("path")
+            .attr("class", "link")
+            .attr("d", diagonal)
+            .style("stroke", "#2F8BF7")
+            .style('stroke-width', '1px')
+            .attr("marker-end", "url(#resolved)")
+            .style("fill", "none")
+            // .style("fill-opacity", 1)
+            .attr("id", function (d, i) {
+                return "mypath" + i;
+            });
+
+        var node = svg.selectAll(".node")
+            .data(nodes)
+            .enter()
+            .append("g")
+            .attr("class", "node")
+            .attr("transform", function (d) {
+                return "translate(" + (d.x + -50) + "," + (d.y) + ")";
+            });
+
+        node.append('image')
+            .attr('xlink:href', function (d) {
+                if(d.type=="e2e"){
+                    return imgmap[1];
+                }else if(d.type=="ns"){
+                    return imgmap[2];
+                }else if(d.type=="vnf"){
+                    return imgmap[3];
+                }
+
+            })
+            .style('width', '12%')
+            .style("cursor","pointer")
+            .attr("x", 0)
+            .attr("y", 0)
+            .attr("rx", 3);
+
+
+    }
+
 }
diff --git a/usecaseui-portal/src/app/components/e2e-detail/e2e-detail.component.html b/usecaseui-portal/src/app/components/e2e-detail/e2e-detail.component.html
new file mode 100644 (file)
index 0000000..ce5b97c
--- /dev/null
@@ -0,0 +1,186 @@
+<!--
+    Copyright (C) 2019 CMCC, Inc. and others. All rights reserved.
+
+    Licensed 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.
+-->
+<!--<h3 class="title"> Services List </h3>-->
+<div class="model creation-model">
+
+  <div class="top-title">
+    <h3 class="title fl">{{serviceInstanceName}} Instance Detail</h3>
+    <div class="fl" style="width: 20%">
+      <button class="back" nz-button (click)="goback()">
+        <i class="anticon anticon-arrow-left" style="transform: scale(1.5)"></i>
+      </button>
+    </div>
+  </div>
+  <div class="detaildata fl">
+    <div *ngIf="detailParams.serviceDomain == 'E2E Service'" class="baseparms clearfix">
+      <!--2019.02.21 add-->
+      <div class="vnf-box">
+        <h3>Base</h3>
+        <ul class="clearfix">
+          <li><span>Name:</span>Sont L2</li>
+          <li><span>Description:</span>Typen asaa</li>
+          <li><span>COS:</span>standard</li>
+          <li><span>EBS:</span>fince in felis nec e</li>
+          <li>
+            <span style="vertical-align: top;">checkbox</span>
+            <nz-checkbox-wrapper style="width: 100%;" >
+              <div nz-row>
+                <div nz-col style="margin-bottom: 10px"><label nz-checkbox nzValue="A"
+                                                               [nzDisabled]="true">Mauris rutrum quam p
+                </label></div>
+                <div nz-col><label nz-checkbox nzValue="B" [ngModel]="true" [nzDisabled]="true">fince in felis nec e
+                </label></div>
+              </div>
+            </nz-checkbox-wrapper>
+          </li>
+        </ul>
+      </div>
+      <div class="vnf-box">
+        <h3>VNF1</h3>
+        <ul class="clearfix">
+          <li><span>Name:</span>Sont L2</li>
+          <li><span>Description:</span>Typen asaa</li>
+          <li>
+            <span style="vertical-align: top;">radio button</span>
+            <nz-radio-group [(ngModel)]="radioValue1" nzName="radiogroup">
+              <label nz-radio [ngStyle]="{'margin-bottom':'10px'}" nzValue="Selected" [ngModel]="true" [nzDisabled]="true">Selected</label>
+              <br>
+              <label nz-radio [ngStyle]="style" nzValue="Disaled" [nzDisabled]="true">Disaled</label>
+            </nz-radio-group>
+          </li>
+          <li><span>pull down:</span>Heresanoption</li>
+        </ul>
+      </div>
+      <div class="vnf-box">
+        <h3>VNF2</h3>
+        <ul class="clearfix">
+          <li><span>Name:</span>Sont L2</li>
+          <li><span>Description:</span>Typen asaa</li>
+          <li>
+            <span style="vertical-align: top;margin-top: 3px;" nzName="radiogroup2">radio button</span>
+            <nz-radio-group [(ngModel)]="radioValue2">
+              <label nz-radio [ngStyle]="{'margin-bottom':'10px'}" nzValue="Selected2" [ngModel]="true" [nzDisabled]="true">Selected2</label>
+              <br>
+              <label nz-radio [ngStyle]="style" nzValue="Disaled2" [nzDisabled]="true">Disaled2</label>
+            </nz-radio-group>
+          </li>
+        </ul>
+      </div>
+      <!--<div class="vnf-box">-->
+      <!--<h3>template Inputs</h3>-->
+      <!--<ul>-->
+      <!--<li *ngFor="let parameter of templateParameters.inputs; let i = index;">-->
+      <!--<span *ngIf="parameter.type !== 'vf_location' && parameter.type !== 'sdn_controller'">{{parameter.name}}:</span>-->
+      <!--<input *ngIf="parameter.type !== 'vf_location' && parameter.type !== 'sdn_controller'" nz-input-->
+      <!--[(ngModel)]="parameter.value">-->
+
+      <!--<h5 *ngIf="parameter.type === 'vf_location'" style="padding-left:10px;">id:-->
+      <!--{{parameter.name}}</h5>-->
+      <!--<span *ngIf="parameter.type === 'vf_location'"> vf_location: </span>-->
+      <!--<nz-select *ngIf="parameter.type === 'vf_location'" style="width: 165px;"-->
+      <!--[(ngModel)]="parameter.value" nzAllowClear>-->
+      <!--<nz-option *ngFor="let vim of vimInfos" [nzValue]="vim" [nzLabel]="vim.name"></nz-option>-->
+      <!--</nz-select>-->
+      <!--&lt;!&ndash; <nz-select *ngIf="parameter.type === 'sdn_controller'" style="width: 165px;" [(ngModel)]="parameter.value" nzAllowClear >-->
+      <!--<nz-option *ngFor="let control of sdnControllers" [nzValue]="control" [nzLabel]="control.name"></nz-option>-->
+      <!--</nz-select> &ndash;&gt;-->
+      <!--</li>-->
+      <!--</ul>-->
+      <!--<h4>nestedTemplate Inputs</h4>-->
+      <!--<div *ngFor="let template of templateParameters.nestedTemplates;">-->
+      <!--<h4 style="font:400 14px 'Arial';color:#aaa;">templateName: {{template.name}}</h4>-->
+      <!--<ul>-->
+      <!--<li *ngFor="let input of template.inputs; let i = index;">-->
+      <!--<span *ngIf="input.type !== 'vf_location' && input.type !== 'sdn_controller'"> {{input.name}}: </span>-->
+      <!--<input *ngIf="input.type !== 'vf_location' && input.type !== 'sdn_controller'" nz-input-->
+      <!--[(ngModel)]="input.value">-->
+
+      <!--<h5 *ngIf="input.type === 'vf_location'" style="padding-left:10px;">id: {{input.name}}</h5>-->
+      <!--<span *ngIf="input.type === 'vf_location'"> vf_location: </span>-->
+      <!--<nz-select *ngIf="input.type === 'vf_location'" style="width: 165px;"-->
+      <!--[(ngModel)]="input.value"-->
+      <!--nzAllowClear>-->
+      <!--<nz-option *ngFor="let vim of vimInfos" [nzValue]="vim"-->
+      <!--[nzLabel]="vim.name"></nz-option>-->
+      <!--</nz-select>-->
+      <!--&lt;!&ndash; <nz-select *ngIf="input.type === 'sdn_controller'" style="width: 165px;" [(ngModel)]="input.value" nzAllowClear >-->
+      <!--<nz-option *ngFor="let control of sdnControllers" [nzValue]="control" [nzLabel]="control.name"></nz-option>-->
+      <!--</nz-select> &ndash;&gt;-->
+      <!--</li>-->
+      <!--</ul>-->
+      <!--</div>-->
+      <!--</div>-->
+    </div>
+
+    <!--<div *ngIf="detailParams.serviceDomain=='Network Service'" class="baseparms clearfix">-->
+    <!--<div class="vnf-box">-->
+    <!--<h3>Base</h3>-->
+    <!--<ul class="clearfix">-->
+    <!--<li><span>Name:</span> <input nz-input [(ngModel)]="ns_service.nsName"></li>-->
+    <!--<li><span>Description:</span> <input nz-input [(ngModel)]="ns_service.description"></li>-->
+    <!--</ul>-->
+    <!--</div>-->
+    <!--<div class="vnf-box">-->
+    <!--<h3>Template Parameters</h3>-->
+    <!--<h4>template Inputs</h4>-->
+    <!--<ul>-->
+    <!--<li *ngFor="let parameter of nsTemplateParameters.inputs2; let i = index;">-->
+    <!--<span *ngIf="parameter.type !== 'vf_location' && parameter.type !== 'sdn_controller'">{{parameter.name}}:</span>-->
+    <!--<input *ngIf="parameter.type !== 'vf_location' && parameter.type !== 'sdn_controller'" nz-input-->
+    <!--[(ngModel)]="parameter.value">-->
+
+    <!--<h5 *ngIf="parameter.type === 'vf_location'" style="padding-left:10px;">id:-->
+    <!--{{parameter.name}}</h5>-->
+    <!--<span *ngIf="parameter.type === 'vf_location'"> vf_location: </span>-->
+    <!--<nz-select *ngIf="parameter.type === 'vf_location'" style="width: 165px;"-->
+    <!--[(ngModel)]="parameter.value" nzAllowClear>-->
+    <!--<nz-option *ngFor="let vim of vimInfos" [nzValue]="vim" [nzLabel]="vim.name"></nz-option>-->
+    <!--</nz-select>-->
+    <!--&lt;!&ndash; <nz-select *ngIf="parameter.type === 'sdn_controller'" style="width: 165px;" [(ngModel)]="parameter.value" nzAllowClear >-->
+    <!--<nz-option *ngFor="let control of sdnControllers" [nzValue]="control" [nzLabel]="control.name"></nz-option>-->
+    <!--</nz-select> &ndash;&gt;-->
+    <!--</li>-->
+    <!--</ul>-->
+
+    <!--<h4>vnfs Inputs</h4>-->
+
+    <!--<ul>-->
+    <!--<li *ngFor="let vnf of nsTemplateParameters.vnfs;">-->
+    <!--<h5 style="padding-left:10px;">id: {{vnf.vnf_id}}</h5>-->
+    <!--<span> vf_location: </span>-->
+    <!--<nz-select style="width: 165px;" [(ngModel)]="vnf.value" nzAllowClear>-->
+    <!--<nz-option *ngFor="let vim of vimInfos" [nzValue]="vim" [nzLabel]="vim.name"></nz-option>-->
+    <!--</nz-select>-->
+    <!--</li>-->
+    <!--</ul>-->
+    <!--</div>-->
+    <!--</div>-->
+  </div>
+
+  <!-- chart -->
+  <div class="chart fr">
+    <div id="createChart">
+      <svg width="100%" height="100%">
+
+        <!--<image xlink:href="./assets/images/create-e2e.png"-->
+        <!--x="40%" y="16%" />-->
+
+      </svg>
+
+    </div>
+  </div>
+
+</div>
diff --git a/usecaseui-portal/src/app/components/e2e-detail/e2e-detail.component.less b/usecaseui-portal/src/app/components/e2e-detail/e2e-detail.component.less
new file mode 100644 (file)
index 0000000..63b6c03
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+    Copyright (C) 2019 CMCC, Inc. and others. All rights reserved.
+
+    Licensed 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.
+*/
+.title {
+  font: 700 18px/18px "思源黑体";
+  color: #4c5e70;
+  margin-bottom: 18px;
+}
+hr {
+  border: none;
+  height: 2px;
+  background-color: #dce1e7;
+  margin-bottom: 10px;
+}
+.creation-model{
+  position: relative;
+}
+.model {
+  background-color: #F7F8FC;
+  height: 100%;
+  overflow-y: auto;
+  position: relative;
+  .top-title{ /*2019.01.22 add*/
+    width: 100%;
+    padding: 20px;
+    position: relative;
+    display: inline-block;
+  }
+  .back {
+    position: absolute;
+    top: 10px;
+    right: 20px;
+    display: inline-block;
+    width: 35px;
+    height: 35px;
+    background:#ffffff!important;
+    border-radius:4px;
+    color: #D7D7D7;
+  }
+  .back:hover{
+    background:#ffffff;
+    color: #3F9CFF;
+    border:1px solid #3F9CFF;
+  }
+  .top-title h3.title {
+    height: 35px;
+    width: 80%;
+    font-size:16px;
+    font-family:ArialMT;
+    color:#3C4F8C;
+    line-height:35px;
+    display: inline-block;
+    /*top:10px;*/
+
+  }
+  .detaildata{
+    position: relative;
+    width: 58%;
+    height: 100%;
+    overflow-y: auto;
+    border-radius: 5px;
+    padding: 20px;
+    background: #fff;
+    margin-left: 30px;
+    box-shadow:0px 10px 15px 2px rgba(222,222,222,0.5);
+    .baseparms {
+      h3 {
+        color: #06A7E2;
+        width: 96%;
+        height: 40px;
+        line-height: 35px;
+        font-size: 18px;
+        font-weight: 500;
+        margin: 10px auto;
+        border-bottom: 2px solid;
+        border-image: -webkit-linear-gradient(#07A9E1,#30D9C4) 100 100;
+        border-image: -moz-linear-gradient(#07A9E1,#30D9C4) 100 100;
+        border-image: linear-gradient(#07A9E1,#30D9C4) 100 100;
+        border-radius:2px;
+      }
+      h4 {
+        font: 700 16px "Arial";
+        margin-left: 25px;
+      }
+      ul{
+        margin-left: 30px;
+      }
+      ul li {
+        // display: inline-block;
+        margin: 10px 0;
+        width: 40%;
+        float: left;
+        text-align: left;
+        color:rgba(60,79,140,1);
+        font-size: 14px;
+        span {
+          display: inline-block;
+          width: 30%;
+          font: 700 14px "Arial";
+          vertical-align: middle;
+          overflow: hidden;
+          text-overflow: ellipsis;
+          text-align: left;
+          color:rgba(60,79,140,0.5);
+        }
+        input,nz-select{
+          width: 170px;
+        }
+      }
+    }
+  }
+  .chart {
+    width: 35%;
+    padding: 10px;
+    height: 95%;
+    box-shadow: 0px 10px 35px 10px rgba(222, 222, 222, 0.5);
+    margin-right: 40px;
+    //background: url("../../../assets/images/ccvpn-createbanner2.png") no-repeat -45px -10px;
+    //background-size: 110% 110%;
+    background:linear-gradient(180deg,rgba(183, 230, 247, 1) 0%,rgba(214, 240, 254, 1) 100%);
+    //background-color: rgba(188, 231, 248, 1);
+    border-radius: 4px;
+    #createChart{
+      height: 100%;
+      width: 100%;
+    }
+  }
+}
diff --git a/usecaseui-portal/src/app/components/e2e-detail/e2e-detail.component.spec.ts b/usecaseui-portal/src/app/components/e2e-detail/e2e-detail.component.spec.ts
new file mode 100644 (file)
index 0000000..ad24a47
--- /dev/null
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { E2eDetailComponent } from './e2e-detail.component';
+
+describe('E2eDetailComponent', () => {
+  let component: E2eDetailComponent;
+  let fixture: ComponentFixture<E2eDetailComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ E2eDetailComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(E2eDetailComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/usecaseui-portal/src/app/components/e2e-detail/e2e-detail.component.ts b/usecaseui-portal/src/app/components/e2e-detail/e2e-detail.component.ts
new file mode 100644 (file)
index 0000000..a592e16
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+    Copyright (C) 2019 CMCC, Inc. and others. All rights reserved.
+
+    Licensed 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, Input, Output, EventEmitter} from '@angular/core';
+import {MyhttpService} from '../../myhttp.service';
+import * as d3 from 'd3';
+
+@Component({
+  selector: 'app-e2e-detail',
+  templateUrl: './e2e-detail.component.html',
+  styleUrls: ['./e2e-detail.component.less']
+})
+export class E2eDetailComponent implements OnInit {
+
+  constructor(private myhttp: MyhttpService) {
+  }
+
+  ngOnInit() {
+    // this.getDetails();
+    this.dataInit();
+    this.drawImage("E2E Service");
+  }
+
+  @Input() detailParams;
+  @Input() namesTranslate;
+  @Output() closeDetail = new EventEmitter();
+  templateParameters: any;
+  serviceInstanceName: any;
+  serviceType: any;
+
+  dataInit() {
+    console.log(this.detailParams);
+    this.serviceInstanceName = this.detailParams['service-instance-name'];
+  }
+
+  goback() {
+    this.closeDetail.emit();
+  }
+
+
+  roote2e = {
+    "name": "e2e",
+    "type": "e2e",
+    "children":
+      [
+        {
+          "name": "ns",
+          "type": "ns",
+          "children":
+            [
+              {
+                "name": "vnf",
+                "type": "vnf",
+              },
+              {
+                "name": "vnf",
+                "type": "vnf",
+              }
+            ]
+        },
+        {
+          "name": "ns",
+          "type": "ns",
+          "children":
+            [
+              {
+                "name": "vnf",
+                "type": "vnf",
+              },
+              {
+                "name": "vnf",
+                "type": "vnf",
+              }
+            ]
+        }]
+  }
+
+  rootns = {
+    "name": "ns",
+    "type": "ns",
+    "children":
+      [
+        {
+          "name": "vnf",
+          "type": "vnf",
+        },
+        {
+          "name": "vnf",
+          "type": "vnf",
+        }
+      ]
+  }
+
+  imgmap = {
+    '1': './assets/images/create-e2e.png',
+    '2': './assets/images/create-ns.png',
+    '3': './assets/images/create-vnf.png',
+  };
+
+  drawImage(type) {
+    if (type == "E2E Service") {
+      this.render(this.roote2e, this.imgmap)
+    } else if (type == "Network Service") {
+      this.render(this.rootns, this.imgmap)
+    }
+
+
+  }
+
+  render(data, imgmap) {
+    var width = document.getElementById("createChart").clientWidth,
+      height = document.getElementById("createChart").clientHeight;
+    var cluster = d3.layout.tree()
+      .size([width, height]);
+    var diagonal = d3.svg.diagonal()
+      .projection(function (d) {
+        return [d.x-18, d.y+40];
+      });
+    console.log(diagonal)
+    var svg = d3.select("svg");
+
+    //marker
+    var marker =
+      svg.append("marker")
+        .attr("id", "resolved")
+        .attr("markerUnits", "strokeWidth")
+        .attr("markerUnits", "userSpaceOnUse")
+        .attr("viewBox", "0 -5 10 10")
+        .attr("refX", 22)
+        .attr("refY", 0)
+        .attr("markerWidth", 20)
+        .attr("markerHeight", 20)
+        .attr("orient", "auto")
+        .attr("stroke-width", 1)
+        .append("circle")
+        .attr("cx", 5)
+        .attr("cy", 0)
+        .attr("r", 2)
+        .attr("stroke-width", 1)
+        .style("stroke", "#2F8BF7")
+        .attr('fill', 'white');
+    var i = 0;
+    var nodes = cluster.nodes(data).reverse();
+    nodes.forEach(function (d) {
+      d.y = d.depth * 200+100;
+
+    });
+
+    var links = cluster.links(nodes);
+
+    var linkEnter = svg.selectAll("path.link")
+      .data(links);
+
+    linkEnter.enter().append("path")
+      .attr("class", "link")
+      .attr("d", diagonal)
+      .style("stroke", "#2F8BF7")
+      .style('stroke-width', '1px')
+      .attr("marker-end", "url(#resolved)")
+      .style("fill", "none")
+      // .style("fill-opacity", 1)
+      .attr("id", function (d, i) {
+        return "mypath" + i;
+      });
+
+    var node = svg.selectAll(".node")
+      .data(nodes)
+      .enter()
+      .append("g")
+      .attr("class", "node")
+      .attr("transform", function (d) {
+        return "translate(" + (d.x + -50) + "," + (d.y) + ")";
+      });
+
+    node.append('image')
+      .attr('xlink:href', function (d) {
+        if(d.type=="e2e"){
+          return imgmap[1];
+        }else if(d.type=="ns"){
+          return imgmap[2];
+        }else if(d.type=="vnf"){
+          return imgmap[3];
+        }
+
+      })
+      .style('width', '12%')
+      .style("cursor","pointer")
+      .attr("x", 0)
+      .attr("y", 0)
+      .attr("rx", 3);
+
+
+  }
+
+
+}
index 48cd38a..57e7446 100644 (file)
 
     <div class="detailComponent" *ngIf="detailshow">
         <app-ccvpn-detail [namesTranslate]="namesTranslate" [detailParams]="detailData"
-                          (closeDetail)="detailshow = false;"></app-ccvpn-detail>
+                          (closeDetail)="detailshow = false;listDisplay = false;"></app-ccvpn-detail>
+    </div>
+    <div class="detailComponent" *ngIf="detailshow2">
+        <app-e2e-detail  [namesTranslate]="namesTranslate" [detailParams]="detailData"
+                        (closeDetail)="detailshow2 = false;listDisplay = false;"></app-e2e-detail>
     </div>
     <div class="createComponent" *ngIf="createshow">
         <app-ccvpn-creation
index 163aa9c..4263c20 100644 (file)
@@ -419,6 +419,7 @@ export class ServicesListComponent implements OnInit {
 
   // show detail
   detailshow = false;
+    detailshow2 = false;
   detailData:Object;
   serviceDetail(service){
     service["siteSer"]=[];
@@ -433,7 +434,12 @@ export class ServicesListComponent implements OnInit {
         service.sdwanSer.push(item);
       }
     })
-    this.detailshow = true;
+        if(service["serviceDomain"]=='CCVPN' ||service["serviceDomain"]=='SOTN' ){
+            this.detailshow = true;
+        }else if(service["serviceDomain"]=='E2E Service' || service["serviceDomain"]=='Network Service'){
+            this.detailshow2 = true;
+        }
+        this.listDisplay = true;
     this.detailData = service;
     console.log(service);
   }
diff --git a/usecaseui-portal/src/assets/images/create-e2e.png b/usecaseui-portal/src/assets/images/create-e2e.png
new file mode 100644 (file)
index 0000000..8ff6c4f
Binary files /dev/null and b/usecaseui-portal/src/assets/images/create-e2e.png differ
diff --git a/usecaseui-portal/src/assets/images/create-ns.png b/usecaseui-portal/src/assets/images/create-ns.png
new file mode 100644 (file)
index 0000000..3a2b2bc
Binary files /dev/null and b/usecaseui-portal/src/assets/images/create-ns.png differ
diff --git a/usecaseui-portal/src/assets/images/create-vnf.png b/usecaseui-portal/src/assets/images/create-vnf.png
new file mode 100644 (file)
index 0000000..6d2c4b7
Binary files /dev/null and b/usecaseui-portal/src/assets/images/create-vnf.png differ
diff --git a/usecaseui-portal/src/assets/images/domain1.png b/usecaseui-portal/src/assets/images/domain1.png
new file mode 100644 (file)
index 0000000..372acfe
Binary files /dev/null and b/usecaseui-portal/src/assets/images/domain1.png differ
index b63bc2e..f50a886 100644 (file)
Binary files a/usecaseui-portal/src/assets/images/site.png and b/usecaseui-portal/src/assets/images/site.png differ