2 import React from 'react';
3 import { Link } from 'react-router';
5 import DashboardCard from 'widgets/dashboard_card/dashboard_card.jsx';
6 import LaunchpadFleetActions from'../launchpadFleetActions';
7 import LaunchpadFleetStore from '../launchpadFleetStore';
8 import UpTime from 'widgets/uptime/uptime.jsx';
9 import {SkyquakeRBAC, isRBACValid} from 'widgets/skyquake_rbac/skyquakeRBAC.jsx';
10 import ROLES from 'utils/roleConstants.js';
11 const PROJECT_ROLES = ROLES.PROJECT;
13 * TODO: Handle when page is loading. See recordView for ref
18 * key - NSR property name
19 * label - Text to display for the header column label
20 * colClass - class to add for rendering this column
21 * transform: function to call to display the value for the property
25 // was using 'short-name'
28 colClass: 'nsColNsName',
29 transform: function(nsr, key) {
31 let title = '"' + val + '" Click to open the viewport dashboard.';
32 let sdnpresent = nsr['sdn-account'] ? true: false;
34 <Link className="nsViewportLink"
35 to={{pathname: '/viewport', query: {id: nsr.id,
36 sdnpresent: sdnpresent}}}
46 colClass: 'nsColNsdName',
47 transform: function(nsr, key) {
50 <span title={val}>{val}</span>
55 key: 'operational-status',
57 colClass: 'nsColStatus',
58 transform: function(nsr, key, isLoading) {
61 if (nsr['operational-status'] == 'running') {
62 if(nsr['config-status'] == 'configuring') {
65 val = 'Configuration Failed'
68 val = nsr['operational-status'];
74 <span title={val} style={{'textTransform': 'capitalize'}}>{val}</span>);
80 colClass: 'nsColUptime',
81 transform: function(nsr, key) {
83 return (<UpTime initialTime={val} run={true} />);
89 * Render the network service grid header row
91 class NsListHeader extends React.Component {
94 const {fieldKeys, ...props} = this.props;
96 <div className="nsListHeaderRow">
97 {fieldKeys.map( (field, index) =>
98 <div className={"nsListHeaderField " + field.colClass}
103 <div className="nsListHeaderField nsColAction"></div>
110 * Render a row for the network service
112 class NsListItem extends React.Component {
117 this.state.isLoading = this.isLoading(props)
118 this.state.failed = false;
121 renderFieldBody(nsr, field, isLoading) {
122 return field.transform(nsr, field.key, isLoading);
131 classNames(isCardOpen) {
132 return "nsListItemRow" + (isCardOpen ? " openedCard" : "");
136 openDashboard(nsr_id) {
137 window.location.href = '//' + window.location.hostname +
138 ':' + window.location.port + '/index.html' +
139 window.location.search +
140 window.location.hash + '/' + nsr_id + '/detail';
141 launchpadFleetStore.closeSocket();
144 componentWillReceiveProps(props) {
146 isLoading: this.isLoading(props)
150 return !((props.nsr['operational-status'] == 'running') && (props.nsr['config-status'] == 'configured'))
152 actionButton(glyphValue, title, onClick) {
154 <div className="actionButton" onClick={onClick}>
155 <span className="oi" data-glyph={glyphValue}
156 title={title} aria-hidden="true"></span>
162 let failed = this.state.failed;
163 let isLoading = this.state.isLoading || failed;
164 const {nsr, isCardOpen, fieldKeys, ...props} = this.props;
167 <div className={this.classNames(isCardOpen)} data-id={nsr.id}>
168 {fieldKeys.map( (field, index) =>
169 <div className={"nsListItemField " + field.colClass}
171 <div className="cellValue">
172 {self.renderFieldBody(nsr, field, isLoading)}
176 <div className="nsListItemField nsColAction">
177 <div className="cellValue">
180 ? this.actionButton("circle-x",
181 "Close network service card",
183 LaunchpadFleetActions.closeNsrCard(nsr.id);
185 : this.actionButton("arrow-circle-right",
186 "Open network service card",
188 LaunchpadFleetActions.openNsrCard(nsr.id);
199 * Used for development/debugging layout
201 class EmptyNsListItem extends React.Component {
203 const {fieldKeys, ...props} = this.props;
205 <div className={"nsListItemRow"} >
206 {fieldKeys.map( (field, index) =>
207 <div className={"nsListItemField " + field.colClass}
211 <div className="nsListItemField nsColAction">
219 * Used for development/debugging layout
221 class MockNsListItem extends React.Component {
226 nsd_name: 'Dungeon X',
227 'operational-status': 'Hunting',
228 'create-time': 1163507750
232 const {fieldKeys, mockNsr, isCardOpen, ...props} = this.props;
237 return (<NsListItem nsr={nsr}
238 fieldKeys={fieldKeys}
239 isCardOpen={isCardOpen}
244 MockNsListItem.defaultProps = {
249 class NsList extends React.Component {
253 for (var i=0; i < count; i++) {
255 <EmptyNsListItem key={ "empty_"+i}
256 fieldKeys={this.props.fieldKeys} />
264 let isCardOpen = false;
265 for (var i=0; i < count; i++) {
266 isCardOpen = !isCardOpen;
268 <MockNsListItem key={ "empty_"+i}
269 fieldKeys={this.props.fieldKeys} isCardOpen={isCardOpen} />
276 const {nsrs, openedNsrIDs, fieldKeys, ...props} = this.props;
278 <div className="nsList">
279 <NsListHeader fieldKeys={fieldKeys} />
280 <div className="nsList-body">
281 <div className="nsList-body_content">
282 {nsrs.map((nsr, index) =>
283 <NsListItem key={nsr.id} nsr={nsr}
284 fieldKeys={fieldKeys}
285 isCardOpen={openedNsrIDs.includes(nsr.id)} />
287 {this.mockNsRows(this.props.mockNsRows)}
288 {this.emptyRows(this.props.emptyRows)}
296 NsList.defaultProps = {
302 export default class NsListPanel extends React.Component {
304 handleInstantiateNetworkService = () => {
305 this.context.router.push({pathname:'instantiate'});
307 handleShowHideToggle(newState) {
309 LaunchpadFleetActions.setNsListPanelVisible(newState);
313 let plusButton = require("style/img/launchpad-add-fleet-icon.png");
316 <div className="nsListPanelToolbar">
318 <div className="button"
319 onClick={this.handleInstantiateNetworkService} >
320 <img src={plusButton}/>
321 <span>Instantiate Service</span>
328 const {nsrs, openedNsrIDs, emptyRows, isVisible, ...props} = this.props;
329 const fieldKeys = FIELD_KEYS;
330 let glyphValue = (isVisible) ? "chevron-left" : "chevron-right";
332 let totalNSRs = nsrs && nsrs.length;
335 let scalingOutNSRs = 0;
336 let scalingInNSRs = 0;
337 let initializingNSRs = 0;
339 nsrs && nsrs.map((nsr) => {
340 nsr['operational-status'] == 'running' && runningNSRs++;
341 nsr['operational-status'] == 'failed' && failedNSRs++;
342 nsr['operational-status'] == 'scaling-out' && scalingOutNSRs++;
343 nsr['operational-status'] == 'scaling-in' && scalingInNSRs++;
345 nsr['operational-status'] == 'init' ||
346 nsr['operational-status'] == 'vl-init-phase' ||
347 nsr['operational-status'] == 'vnf-init-phase'
348 ) && initializingNSRs++;
357 <div className='nsrSummary'>
358 <span className='nsrSummaryItem'>Total: {totalNSRs}</span>
359 <span className='nsrSummaryItem'>Running: {runningNSRs}</span>
360 <span className='nsrSummaryItem'>Failed: {failedNSRs}</span>
361 <span className='nsrSummaryItem'>Scaling Out: {scalingOutNSRs}</span>
362 <span className='nsrSummaryItem'>Scaling In: {scalingInNSRs}</span>
363 <span className='nsrSummaryItem'>Initializing: {initializingNSRs}</span>
370 <DashboardCard className="nsListPanel" showHeader={true}
372 {isRBACValid(this.context.userProfile, [PROJECT_ROLES.LCM_ADMIN, PROJECT_ROLES.PROJECT_ADMIN]) ? this.panelToolbar() : null}
373 <a onClick={this.handleShowHideToggle(!isVisible)}
374 className={"nsListPanelToggle"}>
376 data-glyph={glyphValue}
377 title="Toggle Details Panel"
378 aria-hidden="true"></span></a>
379 <NsList nsrs={nsrs} openedNsrIDs={openedNsrIDs}
380 fieldKeys={fieldKeys} emptyRows={emptyRows} />
387 <DashboardCard className="leftMinimizedNsListPanel" showHeader={true}
389 <a onClick={this.handleShowHideToggle(!isVisible)}
390 className={"nsListPanelToggle"}>
392 data-glyph={glyphValue}
393 title="Toggle Details Panel"
394 aria-hidden="true"></span></a>
400 NsListPanel.contextTypes = {
401 router: React.PropTypes.object,
402 userProfile: React.PropTypes.object
404 NsListPanel.defaultProps = {