4 * Copyright 2016 RIFT.IO Inc
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 import React from 'react';
20 import {Tab, Tabs, TabList, TabPanel} from 'react-tabs';
21 import DashboardCard from 'widgets/dashboard_card/dashboard_card.jsx';
22 import MonitoringParamsCarousel from '../monitoring_params/monitoringParamsCarousel.jsx';
23 import VnfrCard from '../vnfr/vnfrCard.jsx';
24 import {LaunchpadCard, LpCardNfviMetrics, EpaParams, NsrPrimitiveJobList} from '../launchpad_card/launchpadCard.jsx';
25 import VnfrConfigPrimitives from '../launchpad_card/vnfrConfigPrimitives.jsx';
26 import NsrConfigPrimitives from '../launchpad_card/nsrConfigPrimitives.jsx';
27 import NsrScalingGroups from '../launchpad_card/nsrScalingGroups.jsx';
28 import LoadingIndicator from 'widgets/loading-indicator/loadingIndicator.jsx';
29 import NfviMetricBars from 'widgets/nfvi-metric-bars/nfviMetricBars.jsx';
30 import ParseMP from '../monitoring_params/monitoringParamComponents.js';
31 import PlacementGroupsInfo from './placementGroupsInfo.jsx';
32 import JobListCard from '../launchpad_card/jobListCard.jsx';
33 import NSVirtualLinks from '../virtual_links/nsVirtualLinks.jsx';
34 import LaunchpadFleetStore from '../launchpadFleetStore.js';
35 import _forEach from 'lodash/forEach';
36 import Prism from 'prismjs';
37 import 'prismjs/themes/prism.css';
38 import SkyquakeComponent from 'widgets/skyquake_container/skyquakeComponent.jsx';
40 import {SkyquakeRBAC, isRBACValid} from 'widgets/skyquake_rbac/skyquakeRBAC.jsx';
41 import ROLES from 'utils/roleConstants.js';
43 const PROJECT_ROLES = ROLES.PROJECT;
45 class RecordCard extends React.Component {
50 handleSelect = (index, last) => {
51 // console.log('Selected tab is', index, 'last index is', last);
54 openConsole = (url, event) => {
55 event.preventDefault();
56 LaunchpadFleetStore.getVDUConsoleLink(url);
66 let configPrimitivesProps = {};
67 let displayConfigPrimitives = false;
68 let configPrimitiveComponent = null;
69 let scalingGroupsProps = {};
70 let displayScalingGroups = false;
71 let scalingGroupComponent = null;
72 let consoleUrlsComponent = null;
73 let consoleUrlsList = [];
75 let displayNSVirtualLinks = false;
76 let nsVirtualLinksProps = {};
77 let nsVirtualLinksComponent = null;
78 let displayVolumesTab = false;
85 let hasAccess = isRBACValid(this.context.userProfile, [PROJECT_ROLES.LCM_ADMIN, PROJECT_ROLES.PROJECT_ADMIN]);
87 switch(this.props.type) {
89 cardData = this.props.data[0];
90 // Disabling config primitives for VNF
91 configPrimitivesProps = [cardData];
92 displayConfigPrimitives = cardData['service-primitives-present'];
93 if (displayConfigPrimitives) {
94 configPrimitiveComponent = (
95 <div className="flex vnfrConfigPrimitiveContainer">
96 <VnfrConfigPrimitives data={configPrimitivesProps} hasAccess={hasAccess} />
97 {/* <NsrPrimitiveJobList jobs={cardData['config-agent-job']}/> */}
98 <div style={{display:'flex', flexDirection: 'column', flex: '1 1 40%'}}>
99 <div className="launchpadCard_title">
102 <div className="scrollContainer">
104 //Sort for recent on top
107 return parseInt(b['job-id']) - parseInt(a['job-id']);
110 //Return only vnfr configs
111 if(job["triggered-by"] == 'vnf-primitive') {
112 return job.vnfr.map(function(v){
113 //That match the currently selected job id
114 if(v.id == cardData.id) {
115 return v.primitive.map(function(p, i) {
116 return <JobListCard type="vnfr" job-id={job['job-id']} cardData={cardData} key={job['job-id'] + '-' + i} {...p} />
128 if (cardData['vdur']) {
129 cardData['vdur'].map((vdur, index) => {
130 let consoleLink = vdur['console-url'] ? 'Obtain Token And Open VM Console' : 'None';
131 consoleUrlsList.push(
134 {vdur['name'] + '-' + vdur.id.substr(0,4)}
136 <span className='consoleLink' onClick={self.openConsole.bind(self, vdur["console-url"])}>
141 notice = <li className='notice'>* If a separate browser window does not open, please check if the popup was blocked and allow it.</li>
142 if(vdur.hasOwnProperty('volumes') && (vdur.volumes.length > 0)) {
143 displayVolumesTab = true;
144 vdur.volumes.map((volume, vi) => {
145 // let html = Prism.highlight(JSON.stringify(volume), Prism.languages.javascript, 'javascript');
147 // <pre className="language-js" key={index + '-' + vi}>
148 // <code dangerouslySetInnerHTML={{__html: html}} />
150 function buildProperties(obj) {
152 _forEach(obj, function(v, k) {
157 <div style={{margin: '0.5rem 0.5rem'}} key={k + '-' + vi}>
158 <div style={{margin: '0 0.5rem', fontWeight: 'bold', textTransform: 'uppercase', color: '#5b5b5b'}}>{k}</div>
159 <div style={{margin: '0 0.5rem'}}>{(v.constructor.name == 'String' || v.constructor.name == 'Number') ? v : buildProperties(v)}</div>
166 <div key={index + vi}>
167 <div className="launchpadCard_title">
168 VOLUME ({vdur['name']})
170 <div style={{display: 'flex', flexDirection: 'column'}}>
172 buildProperties(volume)
180 consoleUrlsComponent = (
181 <div className="consoleUrlsComponent">
182 <ul className="consoleUrlsList">
189 components = ParseMP.call(this, cardData["monitoring-param"], "vnfr-id");
192 cardData = this.props.data.nsrs[0];
193 configPrimitivesProps = cardData;
194 scalingGroupsProps = cardData;
195 displayConfigPrimitives = cardData['service-primitive'];
196 displayScalingGroups = cardData['scaling-group-descriptor'] ? true : false;
197 let sortedJobs = this.props.jobData.sort(function(a,b){
198 return parseInt(b['job-id']) - parseInt(a['job-id']);
200 if (displayConfigPrimitives) {
201 configPrimitiveComponent = (
202 <div className="flex nsConfigPrimitiveContainer">
203 <NsrConfigPrimitives data={configPrimitivesProps} hasAccess={hasAccess} />
204 <div style={{display:'flex', flexDirection: 'column', flex: '1 1 40%'}}>
205 <div className="launchpadCard_title">
208 <div className="scrollContainer">
209 {sortedJobs.map(function(job, i){
210 if(job["triggered-by"] == 'ns-primitive') {
211 return <JobListCard type="nsr" job-id={job['job-id']} cardData={cardData} key={job['job-id'] + '-' + 'nsr'} {...job} />
214 .concat(sortedJobs.map(function(job) {
215 if(!job.hasOwnProperty('job-name') && (job["triggered-by"] == 'ns-primitive')) {
216 return job.vnfr.map(function(v, h){
217 //That match the currently selected job id
218 if(v.id == cardData.id) {
219 return v.primitive.map(function(p, i) {
220 return <JobListCard type="vnfr" job-id={job['job-id']} cardData={cardData} key={job['job-id'] + '-' + 'vnfr' + '-' + h} {...p} />
232 if (displayScalingGroups) {
233 scalingGroupComponent = (
234 <div className="flex nsrScalingGroupContainer">
235 <NsrScalingGroups data={scalingGroupsProps} />
240 // Virtual Links tab content
241 displayNSVirtualLinks = true;
242 nsVirtualLinksProps = cardData;
243 if (displayNSVirtualLinks) {
244 nsVirtualLinksComponent = (
245 <div className='flex nsVirtualLinksContainer'>
246 <NSVirtualLinks data={nsVirtualLinksProps} />
251 components = ParseMP.call(this, cardData["monitoring-param"], "vnfr-id");
254 let mgmt_interface = cardData["dashboard-url"];
256 let metricsAndParams = [];
259 let nfviMetrics = null //<LpCardNfviMetrics data={cardData["nfvi-metrics"]} />;
260 metricsAndParams.push(<div className="monitoringParams" key="mp">
261 {components.map(function(c, k) {
262 return <div key={k} className="mpSlide">{c.title}{c.component}</div>
265 metricsAndParams.push((<div key="nvfi" className="nfvi-metrics">
267 <EpaParams data={cardData["epa-params"]} />
273 mgmtHTML = <a href={mgmt_interface} target="_blank">Open Application Dashboard</a>;
275 if(this.props.isLoading) {
276 html = <DashboardCard className="loading" showHeader={true} title={cardData["short-name"]}><LoadingIndicator size={10} show={true} /></DashboardCard>
278 let glyphValue = (!this.props.recordDetailsToggleValue) ? "chevron-left" : "chevron-right";
280 if (this.props.type == 'nsr') {
282 <Tab key={cardData.id}>NS Data</Tab>
284 } else if (this.props.type == 'vnfr') {
286 <Tab key={cardData.id}>VNF Data</Tab>
291 <TabPanel key={cardData.id + '-panel'}>
293 <div className="launchpadCard_title" style={{textAlign:'right'}}><span style={{float:'left'}}>MONITORING PARAMETERS</span>
297 <div className="cardSectionFooter">
303 if (this.props.type == 'nsr') {
304 if (scalingGroupComponent) {
306 <Tab key={cardData.id + '-sg'}>Scaling Groups</Tab>
310 <TabPanel key={cardData.id + '-sg-panel'}>
312 {scalingGroupComponent}
314 <div className="cardSectionFooter">
319 if(cardData.hasOwnProperty('vnfd-placement-group-maps')
320 || cardData.hasOwnProperty('nsd-placement-group-maps')) {
322 <Tab key='placement_groups'>
327 <TabPanel key='placement_groups_panel'>
329 <PlacementGroupsInfo nsr={cardData} navRef={this.props.navRef} />
336 if (configPrimitiveComponent) {
337 let primitivesTabTitle = '';
338 if (this.props.type == 'nsr') {
339 primitivesTabTitle = 'Service Primitive';
340 } else if (this.props.type == 'vnfr') {
341 primitivesTabTitle = 'Config Primitive'
345 <Tab key={cardData.id + '-cp'}>{primitivesTabTitle}</Tab>
349 <TabPanel key={cardData.id + '-cp-panel'}>
350 <div className="configPrimitives">
351 {configPrimitiveComponent}
353 <div className="cardSectionFooter">
359 if (nsVirtualLinksComponent) {
360 let nsVirtualLinksTabTitle = 'Virtual Links';
362 <Tab key={cardData.id + '-nsvl'}>{nsVirtualLinksTabTitle}</Tab>
366 <TabPanel key={cardData.id + '-nsvl-panel'}>
367 <div className='nsVirtualLinks'>
368 {nsVirtualLinksComponent}
370 <div className="cardSectionFooter">
376 if (consoleUrlsComponent) {
377 let consoleUrlsTabTitle = '';
378 consoleUrlsTabTitle = 'VDU Console Links';
381 <Tab key={cardData.id + '-vducl'}>{consoleUrlsTabTitle}</Tab>
385 <TabPanel key={cardData.id + '-vducl-panel'}>
386 <div className="consoleUrls">
387 {consoleUrlsComponent}
389 <div className="cardSectionFooter">
395 if (displayVolumesTab) {
398 <Tab key={cardData.id + '-volumes'}>Volumes</Tab>
402 <TabPanel key={cardData.id + '-volumes-panel'}>
404 <div className="cardSectionFooter">
411 <DashboardCard className="recordCard" showHeader={true} title={cardData["short-name"]}>
412 <a onClick={this.props.recordDetailsToggleFn} className={"recordViewToggle " + (this.props.recordDetailsToggleValue ? "on": null)}><span className="oi" data-glyph={glyphValue} title="Toggle Details Panel" aria-hidden="true"></span></a>
413 <Tabs onSelect={this.handleSelect}>
425 RecordCard.defaultProps = {
431 RecordCard.contextTypes = {
432 router: React.PropTypes.object,
433 userProfile: React.PropTypes.object
436 export default SkyquakeComponent(RecordCard);