Merge pull request #138 from vincent99/d3-graph

Bug fixes, restyle container
This commit is contained in:
Vincent Fiduccia 2015-04-30 00:50:49 -07:00
commit dd8cda4ab8
13 changed files with 190 additions and 55 deletions

View File

@ -20,7 +20,7 @@ export default Ember.Component.extend({
this.set('addInput',''); this.set('addInput','');
this.send('addObject', info); this.send('addObject', info);
}).catch(() => { }).catch(() => {
this.sendAction('onError','User or or organizatio not found: ' + input); this.sendAction('onError','User or organization not found: ' + input);
}).finally(() => { }).finally(() => {
this.set('checking', false); this.set('checking', false);
}); });

View File

@ -2,6 +2,10 @@ import Ember from 'ember';
import Cattle from 'ui/utils/cattle'; import Cattle from 'ui/utils/cattle';
var ContainerController = Cattle.TransitioningResourceController.extend({ var ContainerController = Cattle.TransitioningResourceController.extend({
mountError: null,
relatedVolumes: null,
ports: null,
actions: { actions: {
restart: function() { restart: function() {
return this.doAction('restart'); return this.doAction('restart');

View File

@ -9,7 +9,8 @@ export default OverlayRoute.extend({
}, },
model: function() { model: function() {
var model = this.modelFor('container'); var data = this.modelFor('container');
var model = data.get('container');
return Ember.RSVP.all([ return Ember.RSVP.all([
model.followLink('ports'), model.followLink('ports'),
model.followLink('instanceLinks'), model.followLink('instanceLinks'),

View File

@ -3,8 +3,14 @@ import Ember from 'ember';
export default Ember.Route.extend({ export default Ember.Route.extend({
model: function(params) { model: function(params) {
var store = this.get('store'); var store = this.get('store');
var ports;
return store.find('container', params.container_id).then(function(container) { return store.find('container', params.container_id).then(function(container) {
return container.followLink('ports').then(function(p) {
ports = p;
return container;
});
}).then(function(container) {
var opt = { var opt = {
include: ['volume'], include: ['volume'],
filter: {instanceId: container.get('id')} filter: {instanceId: container.get('id')}
@ -60,18 +66,32 @@ export default Ember.Route.extend({
return volumes; return volumes;
}); });
}).then(function(volumesWithInstances) { }).then(function(volumesWithInstances) {
container.set('relatedVolumes', volumesWithInstances); return Ember.Object.create({
return container; container: container,
relatedVolumes: volumesWithInstances,
ports: ports,
});
}).catch(function(err) { }).catch(function(err) {
container.set('mountError',err); return Ember.Object.create({
container.set('mounts',[]); container: container,
container.set('relatedVolumes',[]); mountError: err,
return container; relatedVolumes: [],
ports: [],
});
}); });
}); });
}, },
setupController: function(controller, data) {
this._super(controller, data.get('container'));
controller.setProperties({
mountError: data.get('mountError'),
relatedVolumes: data.get('relatedVolumes'),
ports: data.get('ports'),
});
},
activate: function() { activate: function() {
this.send('setPageLayout', {label: 'Container', backPrevious: true}); this.send('setPageLayout', {label: 'Container', backPrevious: true, hasAside: 'nav-containers active'});
}, },
}); });

View File

@ -1,36 +1,98 @@
{{partial "transitioning-progress"}} <aside>
<label>Container</label>
{{resource-actions-menu model=this choices=availableActions classNames="pull-right"}}
<h3 class="force-wrap">{{displayName}}</h3>
<section> <hr/>
<div class="row">
<div class="col-sm-6">
<h3>{{displayName}}</h3>
<div class="text-muted">
{{displayIp}} {{zero-clipboard text=displayIp}}
</div>
<div class="text-muted">{{imageUuid}} {{zero-clipboard text=imageUuid}}</div>
</div>
<div class="col-sm-6 text-right">
<h3 {{bind-attr class=":instance-status stateColor"}}>
<i {{bind-attr class="stateIcon"}}></i> {{displayState}}
</h3>
<div {{bind-attr class=":force-wrap isError:text-danger:text-muted showTransitioningMessage::hide"}}>
{{transitioningMessage}}
</div>
<div class="instance-actions">
{{resource-actions model=this choices=availableActions}}
</div>
</div>
</div>
</section>
{{#if description}} {{#if description}}
<label style="margin-top: 10px;">Description</label>
<p>{{description}}</p>
<hr/>
{{/if}}
<div class="clearfix">
<label>Info</label>
</div>
<ul class="list-circles">
<li>
<i {{bind-attr class=":fa-fw stateIcon"}}></i>
{{displayState}}
{{#if isTransitioning}}
<div class="progress progress-striped active" style="height: 10px; border: 0;">
<div class="progress-bar" role="progressbar" aria-valuemin="0" aria-valuemax="100" {{bind-attr aria-valuenow=displayProgress style=progressStyle}}>
<span class="sr-only">{{displayProgress}}% Complete</span>
</div>
</div>
{{/if}}
{{#if showTransitioningMessage}}
<div class="force-wrap">
{{transitioningMessage}}
</div>
{{/if}}
</li>
<li>
<i class="fa-fw ss-link"></i>
{{displayIp}}
</li>
</ul>
</aside>
<section>
<div class="text-muted">{{imageUuid}} {{zero-clipboard text=imageUuid}}</div>
</section>
<section>
{{partial "stats-cpu-memory"}}
</section>
<section> <section>
<div class="well"> <div class="well">
<label>Description</label> <label>Ports</label>
{{description}} <table class="grid fixed">
<thead>
<tr>
<th width="120">State</th>
<th>IP Address</th>
<th>Public (on Host)</th>
<th>Private (in Container)</th>
<th>Protocol</th>
</tr>
</thead>
<tbody>
{{#each port in ports itemController="port"}}
<tr>
<td>
<span {{bind-attr class=":badge :state port.stateBackground"}}>
{{port.displayState}}
</span>
</td>
<td>
{{port.displayPublicIp}}
</td>
<td>
{{port.publicPort}}
</td>
<td>
{{port.privatePort}}
</td>
<td>
{{upper-case port.protocol}}
</td>
</tr>
{{else}}
<tr>
<td colspan="5">
<div class="text-muted text-center">This container has no ports.</div>
</td>
</tr>
{{/each}}
</tbody>
</table>
</div> </div>
</section> </section>
{{/if}}
<section> <section>
<div class="well"> <div class="well">
@ -93,7 +155,3 @@
</table> </table>
</div> </div>
</section> </section>
<section>
{{partial "stats-cpu-memory"}}
</section>

View File

@ -1,7 +1,7 @@
<aside> <aside>
<label>Host</label> <label>Host</label>
{{resource-actions-menu model=this choices=availableActions classNames="pull-right"}} {{resource-actions-menu model=this choices=availableActions classNames="pull-right"}}
<h3>{{displayName}}</h3> <h3 class="force-wrap">{{displayName}}</h3>
<hr/> <hr/>

View File

@ -55,9 +55,16 @@ export function initialize(/* container, application */) {
var args = []; var args = [];
var info; var info;
for ( var i = 0 ; i < infos.length - 1 ; i++ ) var max = infos.length - 1;
if (infos[infos.length - 1].name === infos[infos.length-2].name+'.index' )
{
max--;
}
for ( var i = 0 ; i < max ; i++ )
{ {
info = infos[i]; info = infos[i];
if ( info._names && info._names.length ) if ( info._names && info._names.length )
{ {
for ( var j = 0 ; j < info._names.length ; j++ ) for ( var j = 0 ; j < info._names.length ; j++ )

41
app/port/controller.js Normal file
View File

@ -0,0 +1,41 @@
import Cattle from 'ui/utils/cattle';
var PortController = Cattle.TransitioningResourceController.extend({
_publicIp: null,
_publicIpState: 0,
displayPublicIp: function() {
var ip = this.get('_publicIp');
if ( ip )
{
return ip;
}
else if ( this && this.get('_publicIpState') === 2 )
{
return '(Unknown IP)';
}
else if ( this && this.get('_publicIpState') === 0 )
{
this.set('_publicIpState', 1);
this.get('store').find('ipaddress', this.get('publicIpAddressId')).then((ip) => {
this.set('_publicIp', ip.get('address'));
}).catch(() => {
this.set('_publicIpState', 2);
});
return 'Loading...';
}
return null;
}.property('_publicIpState','_publicIp','publicIpAddressId'),
});
PortController.reopenClass({
stateMap: {
'active': {icon: 'ss-record', color: 'text-success'},
'inactive': {icon: 'fa fa-circle',color: 'text-danger'},
'removed': {icon: 'ss-trash', color: 'text-danger'},
'purged': {icon: 'ss-tornado', color: 'text-danger'}
},
});
export default PortController;

View File

@ -169,6 +169,9 @@ HEADER {
line-height: $header-height - 1; line-height: $header-height - 1;
color: $header-text; color: $header-text;
padding-left: 20px; padding-left: 20px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
A, A,
A:visited, A:visited,
@ -322,6 +325,11 @@ SECTION {
&.tab-section { &.tab-section {
padding: 20px; padding: 20px;
} }
.well,
.well .grid {
margin-bottom: 0;
}
} }
.overlay SECTION { .overlay SECTION {

View File

@ -24,6 +24,10 @@
} }
&.hover { &.hover {
A.clip {
padding-right: 27px;
}
.resource-actions { .resource-actions {
display: block; display: block;
} }

View File

@ -5,7 +5,7 @@
<div class="links"> <div class="links">
{{#each env in this itemController="environment"}} {{#each env in this itemController="environment"}}
<div class="link-with-actions resource-action-hover"> <div class="link-with-actions resource-action-hover">
{{#link-to "environment" env.id}}<i class="ss-globe"></i> {{env.displayName}}{{/link-to}} {{#link-to "environment" env.id classNames="clip"}}<i class="ss-globe"></i> {{env.displayName}}{{/link-to}}
{{resource-actions-menu model=env choices=env.availableActions}} {{resource-actions-menu model=env choices=env.availableActions}}
</div> </div>
{{/each}} {{/each}}

View File

@ -1,5 +1,5 @@
<label class="section">Storage</label>
<div class="well"> <div class="well">
<label class="section">Storage</label>
{{#if view.stats.available}} {{#if view.stats.available}}
{{#if view.stats.active}} {{#if view.stats.active}}
<table class="grid fixed" width="100%"> <table class="grid fixed" width="100%">

View File

@ -80,15 +80,7 @@ export default Ember.Object.extend({
function success(body, textStatus, xhr) { function success(body, textStatus, xhr) {
Ember.run(function() { Ember.run(function() {
// @TODO GitHub proxy doesn't return correct status code: #575
if ( body && body.id )
{
resolve(body,'AJAX Reponse: '+url + '(' + xhr.status + ')'); resolve(body,'AJAX Reponse: '+url + '(' + xhr.status + ')');
}
else
{
reject({xhr: xhr, textStatus: textStatus, err: 'Not Found'}, 'AJAX Error:' + url + '(' + xhr.status + ')');
}
}); });
} }