aboutsummaryrefslogtreecommitdiffstats
path: root/demo-ui/app/views
diff options
context:
space:
mode:
Diffstat (limited to 'demo-ui/app/views')
-rw-r--r--demo-ui/app/views/cos-panel.html171
-rw-r--r--demo-ui/app/views/css/vcpe.css340
-rw-r--r--demo-ui/app/views/epl-panel.html187
-rw-r--r--demo-ui/app/views/less/vcpe.less365
-rw-r--r--demo-ui/app/views/mef-panel.html370
-rw-r--r--demo-ui/app/views/vcpe-portal.html71
6 files changed, 1504 insertions, 0 deletions
diff --git a/demo-ui/app/views/cos-panel.html b/demo-ui/app/views/cos-panel.html
new file mode 100644
index 0000000..682f154
--- /dev/null
+++ b/demo-ui/app/views/cos-panel.html
@@ -0,0 +1,171 @@
+<!--
+
+To Do
+ Change Bandwidth to drop down, with selected levels (10M, 100M, 1G, etc)
+ -->
+
+<div class="primary-lable ">Service Levels</div>
+<div class="cos-list">
+ <div class="list-item choosable"
+ ng-repeat="cos in cosList track by $index"
+
+ ng-class="{'selected-item-idle' : $index === selectedCosIdx &&
+ !cosActionInProgress(),
+ 'selected-item-update' : $index === selectedCosIdx &&
+ cosUpdateInProgress(),
+ 'selected-item-delete' : $index === selectedCosIdx &&
+ cosDelInProgress() }"
+ ng-click="onCosClick($index)">
+ {{ cos.id }}
+ </div>
+</div>
+
+<div class = "action-icon-container">
+
+ <span class="action-icon glyphicon glyphicon-plus"
+ ng-click="onAddCos()"
+ ng-class="{'action' : cosAddInProgress()}">
+ </span>
+
+ <span class="action-icon glyphicon glyphicon-pencil"
+ ng-click="onUpdateCos()"
+ ng-class="{'action' : cosUpdateInProgress()}">
+ </span>
+
+ <span class="action-icon glyphicon glyphicon-minus"
+ ng-click="onDelCos()"
+ ng-class="{'action' : cosDelInProgress()}">
+ </span>
+</div>
+
+<div class="cos-info-contaier">
+ <form role="form" ng-submit="onCosInputSubmit()">
+
+ <!-- Name -->
+
+ <div class="data-row">
+ <div class="label-col">Name:</div>
+ <div class="data-col" ng-show="showCosName()">
+ <span class="data-item">
+ {{ cosList[selectedCosIdx].id }}
+ </span>
+ </div>
+ <div class="data-col" ng-show="showCosNameInput()">
+ <input class="data-input" name="id"
+ type="text" ng-required="showCosInputs()"
+ ng-model="cosToEdit.id">
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="label-col">Bandwidth:</div>
+ <div class="data-col" ng-show="showCosValues()">
+
+ <span class="data-item">
+ {{ bwText(cosList[selectedCosIdx]) }}
+ </span>
+ </div>
+ <div class="data-col" ng-show="showCosInputs()">
+ <select class="cos-dd-input"
+ name="bandwidth"
+ ng-required="showCosInputs()"
+ ng-model="cosToEdit.bwSelected"
+ ng-options="bw.name for bw in availableBWs"
+ >
+ </option>
+ </select>
+ </div>
+ </div>
+
+ <!-- Availability -->
+
+ <div class="data-row">
+ <div class="label-col">Availability:</div>
+ <div class="data-col" ng-show="showCosValues()">
+ <span class="data-item">
+ {{ cosList[selectedCosIdx].availbility }}
+ </span>
+ <span class="data-unit">%</span>
+ </div>
+ <div class="data-col" ng-show="showCosInputs()">
+ <input class="data-input" name="availbility"
+ type="number" step="any" ng-required="showCosInputs()"
+ min="1" max="100"
+ ng-model="cosToEdit.availbility">
+ <span class="data-unit">%</span>
+ </div>
+ </div>
+
+ <!-- Frame Delay -->
+
+ <div class="data-row">
+ <div class="label-col">Frame Delay:</div>
+ <div class="data-col" ng-show="showCosValues()">
+ <span class="data-item">
+ {{ cosList[selectedCosIdx].frameDelay }}
+ </span>
+ <span class="data-unit">ms</span>
+ </div>
+ <div class="data-col" ng-show="showCosInputs()">
+ <input class="data-input" name="frameDelay"
+ type="number" step="any" ng-required="showCosInputs()"
+ min="0"
+ ng-model="cosToEdit.frameDelay">
+ <span class="data-unit">ms</span>
+ </div>
+ </div>
+
+ <!-- Jitter -->
+
+ <div class="data-row">
+ <div class="label-col">Jitter:</div>
+ <div class="data-col" ng-show="showCosValues()">
+ <span class="data-item">
+ {{ cosList[selectedCosIdx].jitter }}
+ </span>
+ <span class="data-unit">ms</span>
+ </div>
+ <div class="data-col" ng-show="showCosInputs()">
+ <input class="data-input" name="jitter"
+ type="number" step="any" ng-required="showCosInputs()"
+ min="0"
+ ng-model="cosToEdit.jitter">
+ <span class="data-unit">ms</span>
+ </div>
+ </div>
+
+ <!-- Frame Loss -->
+
+ <div class="data-row">
+ <div class="label-col">Frame Loss:</div>
+ <div class="data-col" ng-show="showCosValues()">
+ <span class="data-item">
+ {{ cosList[selectedCosIdx].frameLoss }}
+ </span>
+ <span class="data-unit">%</span>
+ </div>
+ <div class="data-col" name="frameLoss"ng-show="showCosInputs()">
+ <input class="data-input" name="frameLoss"
+ type="number" step="any" ng-required="showCosInputs()"
+ min="0" max="100"
+ ng-model="cosToEdit.frameLoss">
+ <span class="data-unit">%</span>
+ </div>
+ </div>
+
+
+ <div class="warning-container">
+ <div class="warning" ng-show="cosNameConflict()">Please Enter Unique Name</div>
+ </div>
+ <div class="button-container">
+ <button type="submit"
+ class="btn btn-sm my-btn-addon"
+ <div ng-class="{'btn-success' : cosAddInProgress(),
+ 'btn-warning' : cosUpdateInProgress(),
+ 'btn-danger' : cosDelInProgress()}"
+ ng-disabled="!activateCosActionButton()"
+ ng-show="showCosActionButton()")>
+ {{ cosActionButtonText }}</button>
+ </div>
+ </form>
+</div>
diff --git a/demo-ui/app/views/css/vcpe.css b/demo-ui/app/views/css/vcpe.css
new file mode 100644
index 0000000..0d08734
--- /dev/null
+++ b/demo-ui/app/views/css/vcpe.css
@@ -0,0 +1,340 @@
+input[type='number'] {
+ font-size: 12px;
+}
+.choosable {
+ cursor: pointer;
+}
+.gradient {
+ background: -webkit-linear-gradient(rgba(255, 255, 255, 0) 0%, #ffffff 100%);
+ background: linear-gradient(to bottom, #ffffff 0%, rgba(255, 255, 255, 0) 100%);
+}
+.my-btn-addon {
+ height: 30px;
+ width: 100px;
+}
+.primary-lable {
+ color: darkred;
+ font-size: large;
+ font-weight: bold;
+ text-align: center;
+}
+.list-item {
+ color: black;
+ font-size: small;
+ font-weight: normal;
+ text-align: left;
+ background-color: none;
+}
+.selected-item-idle {
+ background-color: #e3e3e3;
+}
+.selected-item-delete {
+ background-color: #FFE4E1;
+}
+.selected-item-update {
+ background-color: #FFEFD5;
+}
+.primary-container {
+ border: 3px solid black;
+ background-color: #e3e3e3;
+ border-radius: 15px;
+ padding: 10px;
+ height: 400px;
+}
+.secondary-container {
+ border: 1px solid darkgray;
+ background-color: white;
+ padding: 5px 10px;
+ margin: 10px 10px -1px 10px;
+ height: 125px;
+ overflow-y: scroll;
+}
+.action-icon-container {
+ border: 1px solid darkgray;
+ background: -webkit-linear-gradient(rgba(255, 255, 255, 0) 0%, #ffffff 100%);
+ background: linear-gradient(to bottom, #ffffff 0%, rgba(255, 255, 255, 0) 100%);
+ margin: 0px 10px;
+ padding: 2px 10px;
+}
+.action-icon {
+ cursor: pointer;
+ padding: 0px 1px;
+ font-size: small;
+ color: black;
+ padding: 2px;
+}
+.action {
+ color: blue !important;
+}
+.warning {
+ color: red !important;
+ font-size: small !important;
+}
+.data-row {
+ display: flex;
+ flex-flow: row nowrap;
+ height: 20px;
+ width: 300;
+}
+.label-col {
+ color: purple;
+ font-size: small;
+ font-weight: normal;
+ text-align: left;
+ flex: 0 0 auto;
+ order: 1;
+ width: 85px;
+}
+.data-col {
+ flex: 0 0 auto;
+ order: 2;
+ color: black;
+ font-size: small;
+ font-weight: normal;
+ text-align: left;
+}
+.data-label {
+ color: purple;
+ font-size: small;
+ font-weight: normal;
+ text-align: left;
+ vertical-align: middle;
+}
+.data-item {
+ color: black;
+ font-size: small;
+ font-weight: bold;
+ text-align: left;
+}
+.data-input {
+ height: 20px;
+ width: 70px;
+ border-radius: 5px;
+}
+.cos-dd-input {
+ height: 20px;
+ width: 70px;
+}
+.epl-dd-input {
+ height: 20px;
+ width: 150px;
+}
+.data-unit {
+ color: black;
+ font-size: small;
+ font-weight: normal;
+ text-align: left;
+ margin-left: 5px;
+ vertical-align: middle;
+}
+.header-container {
+ display: flex;
+ flex-flow: row nowrap;
+ justify-content: space-between;
+}
+.header-container .hdr {
+ flex: 1 1 auto;
+ order: 1;
+}
+.header-container .img {
+ flex: 1 1 auto;
+ order: 2;
+ align-self: flex-end;
+ margin-bottom: 12px;
+}
+.frame {
+ display: flex;
+ flex-flow: row nowrap;
+ border: 1px solid lightgray;
+ margin: 20px;
+ padding: 20px 0px;
+}
+.frame .left {
+ flex: 1 6 5%;
+ order: 1;
+}
+.frame .right {
+ flex: 1 6 5%;
+ order: 3;
+}
+.frame .content {
+ border: none;
+ flex: 1 6 90%;
+ order: 2;
+}
+.frame .content .action-container {
+ border: none;
+ display: flex;
+ flex-flow: row nowrap;
+}
+.frame .content .action-container .cos-container {
+ border: 3px solid black;
+ background-color: #e3e3e3;
+ border-radius: 15px;
+ padding: 10px;
+ height: 400px;
+ flex: 1 1 50%;
+ order: 1;
+ margin-right: 20px;
+}
+.frame .content .action-container .cos-container .cos-list {
+ border: 1px solid darkgray;
+ background-color: white;
+ padding: 5px 10px;
+ margin: 10px 10px -1px 10px;
+ height: 125px;
+ overflow-y: scroll;
+}
+.frame .content .action-container .cos-container .cos-info-contaier {
+ display: flex;
+ flex-flow: column nowrap;
+ margin: 10px 20px;
+}
+.frame .content .action-container .cos-container .cos-info-contaier .labelContainer {
+ flex: 1 1 33%;
+ order: 1;
+ min-width: 80px;
+ color: purple;
+ font-size: small;
+ font-weight: normal;
+ text-align: left;
+ vertical-align: middle;
+}
+.frame .content .action-container .cos-container .warning-container {
+ height: 15px;
+ margin-top: 10px;
+}
+.frame .content .action-container .epl-container {
+ border: 3px solid black;
+ background-color: #e3e3e3;
+ border-radius: 15px;
+ padding: 10px;
+ height: 400px;
+ flex: 1 1 50%;
+ order: 2;
+ margin-right: 20px;
+}
+.frame .content .action-container .epl-container .epl-list {
+ border: 1px solid darkgray;
+ background-color: white;
+ padding: 5px 10px;
+ margin: 10px 10px -1px 10px;
+ height: 125px;
+ overflow-y: scroll;
+}
+.frame .content .action-container .epl-container .epl-info-contaier {
+ display: flex;
+ flex-flow: column nowrap;
+ margin: 10px 20px;
+}
+.frame .content .action-container .epl-container .epl-info-contaier .labelContainer {
+ flex: 1 1 33%;
+ order: 1;
+ min-width: 80px;
+ color: purple;
+ font-size: small;
+ font-weight: normal;
+ text-align: left;
+ vertical-align: middle;
+}
+.frame .content .action-container .epl-container .warning-container {
+ height: 15px;
+ margin-top: 10px;
+}
+.frame .content .monitor-container .mef-container {
+ border: 3px solid black;
+ background-color: #e3e3e3;
+ border-radius: 15px;
+ padding: 10px;
+ height: 400px;
+ height: 450px;
+ background-color: #B0C4DE;
+ margin: 20px 20px 20px 0px;
+}
+.frame .content .monitor-container .mef-container .primary-mef-lable {
+ color: SteelBlue;
+ font-size: large;
+ font-weight: bold;
+ text-align: center;
+ margin-bottom: 10px;
+}
+.frame .content .monitor-container .mef-container .mef-panel-hdr {
+ border-bottom: 1px solid SlateGray;
+}
+.frame .content .monitor-container .mef-container .secondary-mef-label {
+ color: SlateGray;
+ font-size: small;
+ font-weight: bold;
+ text-align: center;
+ background-color: #e3e3e3;
+}
+.frame .content .monitor-container .mef-container .mef-data-label {
+ color: purple;
+ font-size: small;
+ font-weight: normal;
+ text-align: left;
+ vertical-align: middle;
+}
+.frame .content .monitor-container .mef-container .mef-label-col {
+ color: purple;
+ font-size: small;
+ font-weight: normal;
+ text-align: left;
+ flex: 0 0 auto;
+ order: 1;
+ padding-left: 10px;
+}
+.frame .content .monitor-container .mef-container .evc-label-col {
+ color: purple;
+ font-size: small;
+ font-weight: normal;
+ text-align: left;
+ flex: 0 0 auto;
+ order: 1;
+ padding-left: 10px;
+ width: 200px;
+}
+.frame .content .monitor-container .mef-container .uni-label-col {
+ color: purple;
+ font-size: small;
+ font-weight: normal;
+ text-align: left;
+ flex: 0 0 auto;
+ order: 1;
+ padding-left: 10px;
+ width: 100px;
+}
+.frame .content .monitor-container .mef-container .mef-info-container {
+ display: flex;
+ flex-flow: row nowrap;
+ justify-content: center;
+}
+.frame .content .monitor-container .mef-container .mef-info-container .mef-secondary-container {
+ border: 1px solid darkgray;
+ background-color: WhiteSmoke;
+ margin: 5px;
+}
+.frame .content .monitor-container .mef-container .mef-info-container .uni1-container {
+ border: 1px solid darkgray;
+ background-color: WhiteSmoke;
+ margin: 5px;
+ border: 2px solid SlateGray;
+ flex: 1 1 24%;
+ order: 1;
+}
+.frame .content .monitor-container .mef-container .mef-info-container .evc-container {
+ border: 1px solid darkgray;
+ background-color: WhiteSmoke;
+ margin: 5px;
+ border: 2px solid SlateGray;
+ flex: 1 1 38%;
+ order: 2;
+}
+.frame .content .monitor-container .mef-container .mef-info-container .uni2-container {
+ border: 1px solid darkgray;
+ background-color: WhiteSmoke;
+ margin: 5px;
+ border: 2px solid SlateGray;
+ flex: 1 1 24%;
+ order: 3;
+}
diff --git a/demo-ui/app/views/epl-panel.html b/demo-ui/app/views/epl-panel.html
new file mode 100644
index 0000000..3de2523
--- /dev/null
+++ b/demo-ui/app/views/epl-panel.html
@@ -0,0 +1,187 @@
+<!--
+
+To Do
+ construct default name based on UNIs and COS
+ display EVC params when clicked
+ changed currently hardcoded widths (150) of input fields/dd's to be set by a class
+ update config file based on watch (already have hit issue), rather than wait
+ update available cos list when new cos added (low priority)
+
+ -->
+
+<!-- List of existing EPLs -->
+
+<div class="primary-lable ">Ethernet Private Line Services</div>
+<div class="epl-list">
+ <div class="list-item choosable"
+ ng-repeat="epl in eplList track by $index"
+
+ ng-class="{'selected-item-idle' : $index === selectedEplIdx &&
+ !eplActionInProgress(),
+ 'selected-item-update' : $index === selectedEplIdx &&
+ eplUpdateInProgress(),
+ 'selected-item-delete' : $index === selectedEplIdx &&
+ eplDelInProgress() }"
+ ng-click="onEplClick($index)">
+ {{ epl.id }}
+ </div>
+</div>
+
+
+<!-- Action Icons (add/mod/del) -->
+
+<div class = "action-icon-container">
+
+ <span class="action-icon glyphicon glyphicon-plus"
+ ng-click="onAddEpl()"
+ ng-class="{'action' : eplAddInProgress()}">
+ </span>
+
+ <span class="action-icon glyphicon glyphicon-pencil"
+ ng-click="onUpdateEpl()"
+ ng-class="{'action' : eplUpdateInProgress()}">
+ </span>
+
+ <span class="action-icon glyphicon glyphicon-minus"
+ ng-click="onDelEpl()"
+ ng-class="{'action' : eplDelInProgress()}">
+ </span>
+</div>
+
+<!-- Data for EPL selected / being acted on -->
+
+<div class="epl-info-contaier">
+ <form role="form" ng-submit="onEplInputSubmit()">
+
+ <!-- Name -->
+
+ <div class="data-row">
+ <div class="label-col">Name:</div>
+ <div class="data-col" ng-show="showEplName()">
+ <span class="data-item">
+ {{ eplList[selectedEplIdx].id }}
+ </span>
+ </div>
+
+ <div class="data-col" ng-show="showEplNameInput()">
+ <input class="data-input" name="id"
+ style="width:150"
+ type="text" ng-required="showEplInputs()"
+ ng-model="eplToEdit.id">
+ </div>
+ </div>
+
+ <!-- Class of servce -->
+
+ <div class="data-row">
+ <div class="label-col">Service level</div>
+ <div class="data-col" ng-show="showEplValues()">
+ <span class="data-item">
+ {{ eplList[selectedEplIdx].cos }}</span>
+ </div>
+ <div class="data-col" ng-show="showEplInputs()">
+ <select class="dd-input"
+ style="width:150"
+ name="cos Id"
+ ng-required="showEplInputs()"
+ ng-model="eplToEdit.cos"
+ >
+ <option ng-repeat="cos in availableCosIds"
+ value="{{ cos }}"
+ ng-selected="{{cos == eplToEdit.cos}}"
+ >
+ {{ cos }}
+ </option>
+ </select>
+ </div>
+ </div>
+
+
+ <!-- UNI 1 -->
+
+ <div class="data-row">
+ <div class="label-col">UNI 1</div>
+ <div class="data-col" ng-show="showEplValues()">
+ <span class="data-item">
+ {{ eplList[selectedEplIdx].uniHostIpList[0] }}&nbsp
+ ( {{ eplList[selectedEplIdx].custAddressList[0] }} )
+ </span>
+ </div>
+
+ <div class="data-col" ng-show="showEplInputs()">
+ <select class="dd-input"
+ style="width:150"
+ name="uni 1"
+ ng-required="showEplInputs()"
+ ng-model="eplToEdit.uni1Selected"
+ ng-options="uni.ip + ' ( ' + uni.address + ' )' for uni in availableUnis"
+ >
+ </option>
+ </select>
+ </div>
+ </div>
+
+
+ <!-- UNI 2 -->
+
+ <div class="data-row">
+ <div class="label-col">UNI 2</div>
+ <div class="data-col" ng-show="showEplValues()">
+ <span class="data-item">
+ {{ eplList[selectedEplIdx].uniHostIpList[1] }}&nbsp
+ ( {{ eplList[selectedEplIdx].custAddressList[1] }} )
+ </span>
+ </div>
+
+ <div class="data-col" ng-show="showEplInputs()">
+ <select class="dd-input"
+ style="width:150"
+ name="uni 1"
+ ng-required="showEplInputs()"
+ ng-model="eplToEdit.uni2Selected"
+ ng-options="uni.ip + ' ( ' + uni.address + ' )' for uni in availableUnis"
+ >
+ </option>
+ </select>
+ </div>
+ </div>
+
+
+ <!-- Evc -->
+
+ <div class="data-row" >
+ <div class="label-col" ng-hide="eplAddInProgress()">Assoc Evc:</div>
+ <div class="data-col">
+ <span class="data-item" ng-hide="eplAddInProgress()">
+ {{ eplList[selectedEplIdx].evcId }}
+ </span>
+ </div>
+ </div>
+
+ <!-- Action Buttons -->
+
+ <div class="warning-container">
+ &nbsp<span class="warning" ng-show="eplNameConflict()">[Please Enter Unique Name]&nbsp&nbsp&nbsp</span>
+ <span class="warning" ng-show="uniConflict()">[UNI-1 and UNI-2 must be different]&nbsp&nbsp&nbsp</span>
+ <span class="warning" ng-show="cosConflict()">[Must create SL before creating EPL]&nbsp&nbsp&nbsp</span>
+ </div>
+ <div class="button-container">
+ <button type="submit"
+ class="btn btn-sm my-btn-addon"
+ <div ng-class="{'btn-success' : eplAddInProgress(),
+ 'btn-warning' : eplUpdateInProgress(),
+ 'btn-danger' : eplDelInProgress()}"
+ ng-disabled="!activateEplActionButton()"
+ ng-show="showEplActionButton()")>
+ {{ eplActionButtonText }}</button>
+ </div>
+
+ <!-- Debug -->
+
+<!--
+ <div>
+ </div>
+ -->
+
+ </form>
+</div>
diff --git a/demo-ui/app/views/less/vcpe.less b/demo-ui/app/views/less/vcpe.less
new file mode 100644
index 0000000..5598160
--- /dev/null
+++ b/demo-ui/app/views/less/vcpe.less
@@ -0,0 +1,365 @@
+@dbg-flg: false;
+
+@side-panel-width: 5%;
+@main-panel-width: 100%-(2*@side-panel-width);
+
+@backgroundGray: #E3E3E3;
+
+@cos-basis: 50%;
+@epl-basis: 100%-(@cos-basis);
+
+
+//
+// Utilities
+//
+
+.dbg-border( // show border if @dbg-flg is true
+ @dbg-bordersFlg,
+ @dbg-borderClr,
+ @dbg-borderStyle)
+ when (@dbg-bordersFlg=true) {
+ border: 3px @dbg-borderStyle @dbg-borderClr;
+ margin: 1px; padding: 1px;
+}
+
+.set-text(@color,
+ @font-size,
+ @font-weight,
+ @text-align) {
+ color:@color; font-size:@font-size;
+ font-weight:@font-weight; text-align:@text-align;
+}
+
+//
+// Common Styles
+//
+
+input[type='number'] { font-size: 12px; }
+
+.choosable {
+ cursor: pointer;
+}
+
+.gradient {
+ background: -webkit-linear-gradient(rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
+ background: linear-gradient(to bottom, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%);
+}
+
+.my-btn-addon {
+ height: 30px;
+ width: 100px;
+}
+
+.primary-lable {
+ .set-text(darkred, large, bold, center); }
+
+.list-item {
+ .set-text(black, small, normal, left);
+ background-color:none; }
+
+.selected-item-idle {
+ background-color: @backgroundGray; }
+
+.selected-item-delete {
+ background-color: #FFE4E1; }
+
+.selected-item-update {
+ background-color: #FFEFD5; }
+
+.primary-container {
+ border: 3px solid black;
+ .dbg-border(@dbg-flg, blue, solid);
+ background-color: @backgroundGray;
+ border-radius: 15px;
+ padding: 10px;
+ height: 400px;
+}
+
+.secondary-container {
+ border: 1px solid darkgray;
+ .dbg-border(@dbg-flg, green, solid);
+ background-color: white;
+ padding: 5px 10px; // TB RL
+ margin: 10px 10px -1px 10px; // T R B L
+ height: 125px;
+ overflow-y: scroll;
+}
+
+.action-icon-container {
+ border: 1px solid darkgray;
+ .dbg-border(@dbg-flg, magenta, solid);
+ .gradient;
+ margin: 0px 10px; // TB RL
+ padding: 2px 10px; // TB RL
+}
+
+.action-icon {
+ .choosable;
+ padding: 0px 1px; // TB RL
+ font-size: small;
+ color: black;
+ padding: 2px;
+}
+
+.action {
+ color: blue !important;
+}
+
+.warning {
+ color: red !important;
+ font-size: small !important;
+}
+
+.data-row {
+ .dbg-border(@dbg-flg, red, solid);
+ display: flex;
+ flex-flow:row nowrap;
+ height: 20px;
+ width: 300;
+ }
+.label-col {
+ .dbg-border(@dbg-flg, gray, solid);
+ .set-text(purple, small, normal, left);
+ flex: 0 0 auto; order: 1;
+ width: 85px;
+ }
+
+
+.data-col {
+ .dbg-border(@dbg-flg, gray, solid);
+ flex: 0 0 auto; order: 2;
+ .set-text(black, small, normal, left);
+
+ }
+
+.data-label {
+ .set-text(purple, small, normal, left);
+ vertical-align: middle;
+}
+.data-item {
+ .set-text(black, small, bold, left);
+}
+.data-input {
+ height: 20px;
+ width: 70px;
+ border-radius: 5px;
+}
+.cos-dd-input {
+ height: 20px;
+ width: 70px;
+}
+
+.epl-dd-input {
+ height: 20px;
+ width: 150px;
+}
+
+
+.data-unit {
+ .set-text(black, small, normal, left);
+ margin-left: 5px;
+ vertical-align: middle;
+}
+
+//
+// Page starts here
+//
+
+.header-container {
+ display: flex;
+ flex-flow:row nowrap;
+ justify-content: space-between;
+ .hdr {
+ flex: 1 1 auto; order: 1;
+ }
+ .img {
+ flex: 1 1 auto; order: 2;
+ align-self: flex-end;
+ margin-bottom: 12px;
+ }
+}
+
+
+.frame{
+ .dbg-border(@dbg-flg, lightgray, solid);
+ display: flex;
+ flex-flow:row nowrap;
+ border: 1px solid lightgray;
+
+ margin: 20px; // TBRL
+ padding: 20px 0px; // TB RL
+
+ .left { .dbg-border(@dbg-flg, lightgray, solid);
+ flex: 1 6 @side-panel-width; order: 1; }
+
+ .right{ .dbg-border(@dbg-flg, lightgray, solid);
+ flex: 1 6 @side-panel-width; order: 3; }
+
+ .content {
+ border: none;
+ .dbg-border(@dbg-flg, lightgray, solid);
+ flex: 1 6 @main-panel-width; order: 2;
+
+ .action-container {
+ border: none;
+ .dbg-border(@dbg-flg, yellow, solid);
+
+ display: flex;
+ flex-flow:row nowrap;
+
+ .cos-container {
+ .primary-container;
+ flex: 1 1 @cos-basis; order: 1;
+ margin-right: 20px;
+
+ .cos-list {
+ .secondary-container;
+ }
+ .cos-info-contaier {
+ .dbg-border(@dbg-flg, green, solid);
+ display: flex;
+ flex-flow:column nowrap;
+ margin: 10px 20px; // TB RL
+ .labelContainer {
+ .dbg-border(@dbg-flg, yellow, solid);
+ flex: 1 1 33%; order: 1;
+ min-width: 80px;
+ .data-label;
+ }
+ }
+ .warning-container {
+ .dbg-border(@dbg-flg, magenta, solid);
+ height: 15px;
+ margin-top: 10px;
+ }
+ .button-container {
+ .dbg-border(@dbg-flg, magenta, solid);
+ }
+ }
+ .epl-container {
+ .primary-container;
+ flex: 1 1 @epl-basis; order: 2;
+ margin-right: 20px;
+
+ .epl-list {
+ .secondary-container;
+ }
+ .epl-info-contaier {
+ .dbg-border(@dbg-flg, green, solid);
+ display: flex;
+ flex-flow:column nowrap;
+ margin: 10px 20px; // TB RL
+ .labelContainer {
+ .dbg-border(@dbg-flg, yellow, solid);
+ flex: 1 1 33%; order: 1;
+ min-width: 80px;
+ .data-label;
+ }
+ }
+ .warning-container {
+ .dbg-border(@dbg-flg, magenta, solid);
+ height: 15px;
+ margin-top: 10px;
+ }
+ .button-container {
+ .dbg-border(@dbg-flg, magenta, solid);
+ }
+ }
+ }
+
+ .monitor-container {
+ .dbg-border(@dbg-flg, yellow, solid);
+
+
+ .mef-container {
+ .primary-container;
+ height: 450px;
+
+ .dbg-border(@dbg-flg, blue, solid);
+ background-color: #B0C4DE;
+ margin: 20px 20px 20px 0px; // T R B L
+
+ .primary-mef-lable {
+ .set-text(SteelBlue, large, bold, center);
+ margin-bottom: 10px;
+ }
+
+ @mef-container-border-color: SlateGray;
+
+ .mef-panel-hdr {
+ border-bottom: 1px solid @mef-container-border-color;
+ .dbg-border(@dbg-flg, blue, solid);
+ }
+
+ .secondary-mef-label {
+ .set-text(SlateGray, small, bold, center);
+ background-color: @backgroundGray;
+ }
+
+ .mef-data-label {
+ .set-text(purple, small, normal, left);
+ vertical-align: middle;
+
+ }
+ .mef-label-col {
+ .dbg-border(@dbg-flg, gray, solid);
+ .set-text(purple, small, normal, left);
+ flex: 0 0 auto; order: 1;
+ padding-left: 10px;
+ }
+
+ .evc-label-col {
+ .mef-label-col;
+ width: 200px;
+
+ }
+ .uni-label-col {
+ .mef-label-col;
+ width: 100px;
+ }
+
+ .mef-info-container {
+ display: flex;
+ flex-flow:row nowrap;
+ justify-content: center;
+
+ .mef-secondary-container {
+ border: 1px solid darkgray;
+ .dbg-border(@dbg-flg, green, solid);
+ background-color: WhiteSmoke;
+ //padding: 5px 30px; // TB RL
+ margin: 5px;
+ }
+
+ @evc-basis: 38%;
+ @uni-basis: 100%-(2*@evc-basis);
+
+ .uni1-container {
+ .mef-secondary-container;
+ border: 2px solid @mef-container-border-color;
+ .dbg-border(@dbg-flg, darkred, solid);
+ flex: 1 1 @uni-basis; order: 1;
+
+ }
+ .evc-container {
+ .mef-secondary-container;
+ border: 2px solid @mef-container-border-color;
+ .dbg-border(@dbg-flg, darkred, solid);
+ flex: 1 1 @evc-basis; order: 2;
+
+ }
+ .uni2-container {
+ .mef-secondary-container;
+ border: 2px solid @mef-container-border-color;
+ .dbg-border(@dbg-flg, darkred, solid);
+ flex: 1 1 @uni-basis; order: 3;
+
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
diff --git a/demo-ui/app/views/mef-panel.html b/demo-ui/app/views/mef-panel.html
new file mode 100644
index 0000000..df9f60b
--- /dev/null
+++ b/demo-ui/app/views/mef-panel.html
@@ -0,0 +1,370 @@
+<!--
+
+To Do
+ Use cases to handle properly RE EVC/UNI displaying info
+ - EPL exist at start up
+ - no EPL at start up
+ - delete an EPL
+ - delete last EPL
+ -->
+
+<div class="primary-mef-lable">MEF EPL Data</div>
+<div class="mef-info-container">
+
+
+ <!-- UNI 1 -->
+
+ <div class="uni1-container">
+ <div class="mef-panel-hdr">
+ <div class="secondary-mef-label">UNI-1 MEF Attributes</div>
+ <div class="secondary-mef-label"
+ style="font-size: xx-small; font-weight: normal; color: #b3b3b3;">
+ (Source = ODL UNI Mgr DB)
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="uni-label-col">Uni ID:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEvcUnis[0].uni[0]["id"] }}
+ </span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="uni-label-col">IP Address:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEvcUnis[0].uni[0]["ip-address"] }}
+ </span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="uni-label-col">MAC Address:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEvcUnis[0].uni[0]["mac-address"] }}
+ </span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="uni-label-col">Speed:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ uniToSpeedString(currentEvcUnis[0]) }}
+ </span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="uni-label-col">Mac Layer:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEvcUnis[0].uni[0]["mac-layer"] }}
+ </span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="uni-label-col">Phys Medium:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEvcUnis[0].uni[0]["physical-medium"] }}
+ </span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="uni-label-col">MTU Size:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEvcUnis[0].uni[0]["mtu-size"] }}
+ </span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="uni-label-col">Mode:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEvcUnis[0].uni[0]["mode"] }}
+ </span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="uni-label-col">Type:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEvcUnis[0].uni[0]["type"] }}
+ </span>
+ </div>
+ </div>
+
+ </div>
+
+ <!-- EVC -->
+
+ <div class="evc-container">
+
+ <div class="mef-panel-hdr">
+ <div class="secondary-mef-label">EVC MEF Attributes</div>
+ <div class="secondary-mef-label"
+ style="font-size: xx-small; font-weight: normal; color: #b3b3b3;">
+ (Source = EVC Mgr DB)</div>
+ </div>
+ <div class="data-row">
+ <div class="evc-label-col">Evc ID:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEplEvc.id }}
+ </span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="evc-label-col">CoS ID:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEplEvc.cosId }}
+ </span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="evc-label-col">Uni-1/2 IDs:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+
+ <span class="data-item">
+ {{ "[" + currentEplEvc.uniIdList[0] + "] | [" + currentEplEvc.uniIdList[1] + "]"}}
+ </span>
+
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="evc-label-col">Uni-1/2 IPs:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEplEvc.uniIpList[0] }}
+ </span>
+ </div>
+ </div>
+ <div class="data-row">
+ <div class="evc-label-col"></div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEplEvc.uniIpList[1] }}
+ </span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="evc-label-col">Uni-1/2 MACs:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEplEvc.uniMacList[0] }}
+ </span>
+ </div>
+ </div>
+ <div class="data-row">
+ <div class="evc-label-col"></div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEplEvc.uniMacList[1] }}
+ </span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="evc-label-col">1-Way Availability:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEplEvc.oneWayAvailability }}
+ </span>
+ <span class="data-unit">%</span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="evc-label-col">1-Way Frame Delay:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEplEvc.oneWayFrameDelay }}
+ </span>
+ <span class="data-unit">ms</span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="evc-label-col">1-Way Frame Loss Ratio:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEplEvc.oneWayFrameLossRatio }}
+ </span>
+ <span class="data-unit">%</span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="evc-label-col">EVC Type:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEplEvc.evcType }}
+ </span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="evc-label-col">Unicast Frame Delivery:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEplEvc.unicastFrameDelivery }}
+ </span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="evc-label-col">Broadcast Frame Delivery:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEplEvc.broadcastFrameDelivery }}
+ </span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="evc-label-col">Multicast Frame Delivery:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEplEvc.multicastFrameDelivery }}
+ </span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="evc-label-col">CE VLAN ID Preservation:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEplEvc.ceVLanIdPreservation }}
+ </span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="evc-label-col">CE VLAN CoS Preservation:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEplEvc.ceVlanCosPreservation }}
+ </span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="evc-label-col">Max Service Frame Size:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEplEvc.evcMaxSvcFrameSize }}
+ </span>
+ <span class="data-unit">bytes</span>
+ </div>
+ </div>
+ </div>
+
+ <!-- UNI 2 -->
+
+ <div class="uni2-container">
+ <div class="mef-panel-hdr">
+ <div class="secondary-mef-label">UNI-2 MEF Attributes</div>
+ <div class="secondary-mef-label"
+ style="font-size: xx-small; font-weight: normal; color: #b3b3b3;">
+ (Source = ODL UNI Mgr DB)
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="uni-label-col">Uni ID:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEvcUnis[1].uni[0]["id"] }}
+ </span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="uni-label-col">IP Address:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEvcUnis[1].uni[0]["ip-address"] }}
+ </span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="uni-label-col">MAC Address:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEvcUnis[1].uni[0]["mac-address"] }}
+ </span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="uni-label-col">Speed:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ uniToSpeedString(currentEvcUnis[1]) }}
+ </span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="uni-label-col">Mac Layer:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEvcUnis[1].uni[0]["mac-layer"] }}
+ </span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="uni-label-col">Phys Medium:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEvcUnis[1].uni[0]["physical-medium"] }}
+ </span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="uni-label-col">MTU Size:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEvcUnis[0].uni[0]["mtu-size"] }}
+ </span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="uni-label-col">Mode:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEvcUnis[1].uni[0]["mode"] }}
+ </span>
+ </div>
+ </div>
+
+ <div class="data-row">
+ <div class="uni-label-col">Type:</div>
+ <div class="data-col" ng-show="showEvcValues()">
+ <span class="data-item">
+ {{ currentEvcUnis[1].uni[0]["type"] }}
+ </span>
+ </div>
+ </div>
+
+ </div>
+</div> \ No newline at end of file
diff --git a/demo-ui/app/views/vcpe-portal.html b/demo-ui/app/views/vcpe-portal.html
new file mode 100644
index 0000000..437485f
--- /dev/null
+++ b/demo-ui/app/views/vcpe-portal.html
@@ -0,0 +1,71 @@
+<!--
+
+TODO
+ - Use watchers to trigger changes aftger config file reads as opposed
+ to the current "sleep for a bit" approach
+
+ -->
+
+<html ng-app="vcpe">
+<head ng-controller="MainController">
+
+ <script src="../../bower_components/angular/angular.min.js"></script>
+
+ <link rel="stylesheet" href="../../bower_components/bootstrap/dist/css/bootstrap.min.css">
+ <link rel="stylesheet" href="../../bower_components/bootstrap/dist/css/bootstrap-theme.min.css">
+
+ <link rel="stylesheet" href="css/vcpe.css" />
+ <script src="../controllers/MainController.js"></script>
+ <script src="../controllers/CosController.js"></script>
+ <script src="../controllers/EplController.js"></script>
+ <script src="../controllers/MefController.js"></script>
+ <script src="../services/cosServices.js"></script>
+ <script src="../services/eplServices.js"></script>
+ <script src="../services/mefServices.js"></script>
+ <script src="../services/model.js"></script>
+ <script src="../services/dbg.js"></script>
+
+</head>
+
+<body>
+<div class="frame">
+<div class="left"></div>
+
+<div class="content">
+
+ <div class="header-container">
+ <div class="hdr">
+ <h2>Virtual Business CPE Demo</h2>
+ </div>
+ </div>
+
+ <div class="action-container">
+
+ <div class="cos-container"
+ ng-controller="CosController"
+ ng-include="'cos-panel.html'">
+ </div>
+
+ <div class="epl-container"
+ ng-controller="EplController"
+ ng-include="'epl-panel.html'">
+ </div>
+
+ </div>
+
+ <div class="monitor-container">
+
+ <div class="mef-container"
+ ng-controller="MefController"
+ ng-include="'mef-panel.html'">
+ </div>
+
+
+ </div>
+
+</div>
+
+<div class="right"></div>
+</div>
+</body>
+</html>