mirror of https://github.com/rancher/ui.git
Merge pull request #17 from vincent99/update-ember
Update ember, cli, handlebars and deprecations
This commit is contained in:
commit
a6cdf94f93
|
|
@ -29,5 +29,5 @@ indent_size = 2
|
|||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.md]
|
||||
[*.{diff,md}]
|
||||
trim_trailing_whitespace = false
|
||||
|
|
|
|||
17
README.md
17
README.md
|
|
@ -8,24 +8,27 @@ Perhaps you like managing cattle.
|
|||
## Usage
|
||||
|
||||
Prerequisites:
|
||||
* [Bower](from http://bower.io/)
|
||||
* [Git](http://git-scm.com/)
|
||||
* [Node.js](http://nodejs.org/) (with NPM)
|
||||
* [Bower](http://bower.io/)
|
||||
|
||||
If you're on a Mac and use Homebrew, you can follow these steps:
|
||||
```bash
|
||||
brew install node watchman
|
||||
npm install -g bower
|
||||
```
|
||||
|
||||
Setup:
|
||||
```bash
|
||||
git clone 'https://github.com/rancherio/ui'
|
||||
cd 'ui'
|
||||
git submodule init
|
||||
git submodule update
|
||||
brew install node
|
||||
npm install
|
||||
npm install -g bower
|
||||
bower install
|
||||
brew install watchman # (or https://facebook.github.io/watchman/docs/install.html)
|
||||
```
|
||||
|
||||
Run development server
|
||||
Run development server:
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
|
|
@ -46,6 +49,10 @@ The built-in cattle server expects to be run from `/static/` and hosted on a CDN
|
|||
|
||||
### Running Tests
|
||||
|
||||
```bash
|
||||
npm install -g ember-cli
|
||||
```
|
||||
|
||||
* `ember test`
|
||||
* `ember test`
|
||||
* `ember test --server`
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import Ember from 'ember';
|
||||
import Resolver from 'ember/resolver';
|
||||
import loadInitializers from 'ember/load-initializers';
|
||||
import config from 'ui/config/environment';
|
||||
import config from './config/environment';
|
||||
|
||||
Ember.MODEL_FACTORY_INJECTIONS = true;
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,19 @@ var ApikeyController = Cattle.TransitioningResourceController.extend({
|
|||
this.transitionToRoute('apikey.delete',this.get('model'));
|
||||
},
|
||||
},
|
||||
|
||||
availableActions: function() {
|
||||
var a = this.get('actions');
|
||||
|
||||
return [
|
||||
{ tooltip: 'Edit', icon: 'fa-edit', action: 'edit', enabled: !!a.update },
|
||||
{ tooltip: 'Activate', icon: 'fa-play', action: 'activate', enabled: !!a.activate },
|
||||
{ tooltip: 'Deactivate', icon: 'fa-pause', action: 'deactivate', enabled: !!a.deactivate },
|
||||
{ tooltip: 'Restore', icon: 'fa-ambulance', action: 'restore', enabled: !!a.restore },
|
||||
{ tooltip: 'Delete', icon: 'fa-trash-o', action: 'promptDelete', enabled: !!a.remove, altAction: 'delete' },
|
||||
{ tooltip: 'Purge', icon: 'fa-fire', action: 'purge', enabled: !!a.purge },
|
||||
];
|
||||
}.property('actions.{update,activate,deactivate,restore,remove,purge}'),
|
||||
});
|
||||
|
||||
ApikeyController.reopenClass({
|
||||
|
|
|
|||
|
|
@ -4,6 +4,14 @@ export default Cattle.CollectionController.extend({
|
|||
needs: ['application'],
|
||||
itemController: 'apikey',
|
||||
endpoint: function() {
|
||||
return this.get('controllers.application.absoluteEndpoint').replace(/\/+$/,'') + this.get('app.apiEndpoint');
|
||||
// Strip trailing slash off of the absoluteEndpoint
|
||||
var url = this.get('controllers.application.absoluteEndpoint').replace(/\/+$/,'');
|
||||
// Add a single slash
|
||||
url += '/';
|
||||
|
||||
// And strip leading slashes off the API endpoint
|
||||
url += this.get('app.apiEndpoint').replace(/^\/+/,'');
|
||||
|
||||
return url;
|
||||
}.property('controllers.application.absoluteEndpoint','app.apiEndpoint')
|
||||
});
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
<th width="140"> </th>
|
||||
</tr>
|
||||
{{#each key in dataSource itemController="apikey"}}
|
||||
<tr>
|
||||
<tr class="resource-action-hover">
|
||||
<td {{bind-attr class="key.stateColor"}}>
|
||||
<i {{bind-attr class=":fa key.stateIcon"}}></i> {{key.displayState}}
|
||||
</td>
|
||||
|
|
@ -44,12 +44,7 @@
|
|||
<div>{{#if key.publicValue}}{{key.publicValue}}{{else}}<span class="text-muted text-italic">No public value</span>{{/if}}</div>
|
||||
</td>
|
||||
<td align="right">
|
||||
<button {{bind-attr class=":btn :btn-sm :btn-info key.actions.update::hide"}} {{action "edit"}} tooltip="Edit"><i class="fa fa-edit"></i></button>
|
||||
<button {{bind-attr class=":btn :btn-sm :btn-info key.actions.activate::hide"}} {{action "activate"}} tooltip="Activate"><i class="fa fa-play"></i></button>
|
||||
<button {{bind-attr class=":btn :btn-sm :btn-info key.actions.deactivate::hide"}} {{action "deactivate"}} tooltip="Deactivate"><i class="fa fa-pause"></i></button>
|
||||
<button {{bind-attr class=":btn :btn-sm :btn-info key.actions.remove::hide"}} {{action "delete"}} tooltip="Delete"><i class="fa fa-trash-o"></i></button>
|
||||
<button {{bind-attr class=":btn :btn-sm :btn-info key.actions.restore::hide"}} {{action "restore"}} tooltip="Restore"><i class="fa fa-ambulance"></i></button>
|
||||
<button {{bind-attr class=":btn :btn-sm :btn-info key.actions.purge::hide"}} {{action "purge"}} tooltip="Purge"><i class="fa fa-fire"></i></button>
|
||||
{{resource-actions model=key}}
|
||||
</td>
|
||||
</tr>
|
||||
{{else}}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ export default Ember.Controller.extend({
|
|||
|
||||
absoluteEndpoint: function() {
|
||||
var url = this.get('app.endpoint');
|
||||
|
||||
// If the URL is relative, add on the current base URL from the browser
|
||||
if ( url.indexOf('http') !== 0 )
|
||||
{
|
||||
url = window.location.origin + '/' + url.replace(/^\/+/,'');
|
||||
|
|
@ -25,6 +27,9 @@ export default Ember.Controller.extend({
|
|||
url = url + "/";
|
||||
}
|
||||
|
||||
// Url must end in a single slash
|
||||
url = url.replace(/\/+$/,'') + '/';
|
||||
|
||||
return url;
|
||||
}.property('app.endpoint'),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ export default Ember.Component.extend({
|
|||
icon: 'fa-square',
|
||||
tooltip: '',
|
||||
enabled: true,
|
||||
actionArg: null,
|
||||
altActionArg: null,
|
||||
|
||||
tagName: 'button',
|
||||
type: 'button',
|
||||
|
|
@ -12,13 +14,13 @@ export default Ember.Component.extend({
|
|||
attributeBindings: ['tooltip'],
|
||||
|
||||
click : function(event) {
|
||||
if ( event.altKey )
|
||||
if ( event.altKey && this.get('altActionArg'))
|
||||
{
|
||||
this.sendAction('altAction');
|
||||
this.sendAction('action', this.get('altActionArg'));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.sendAction();
|
||||
this.sendAction('action', this.get('actionArg'));
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
model: null,
|
||||
classNames: ['instance','resource-action-hover'],
|
||||
});
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<div {{bind-attr class=":instance-name model.stateColor"}}>
|
||||
<i {{bind-attr class=":fa model.stateIcon" tooltip=model.displayState}}></i>
|
||||
{{#link-to "container" model.id}}{{model.displayName}}{{/link-to}}
|
||||
</div>
|
||||
{{resource-actions model=model}}
|
||||
|
||||
<div {{bind-attr class="isOn::text-muted"}}>{{model.displayIp}}</div>
|
||||
|
||||
<div {{bind-attr class=":force-wrap model.isError:text-danger:text-muted model.showTransitioningMessage::hide"}}>
|
||||
{{model.transitioningMessage}}
|
||||
</div>
|
||||
|
||||
<div {{bind-attr class="model.isTransitioning::hide :progress :progress-striped :active"}}>
|
||||
<div class="progress-bar" role="progressbar" aria-valuemin="0" aria-valuemax="100" {{bind-attr aria-valuenow=model.displayProgress style=model.progressStyle}}>
|
||||
<span class="sr-only">{{model.displayProgress}}% Complete</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
model: null,
|
||||
classNames: ['host','resource-action-hover'],
|
||||
});
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<div class="host-header resource-action-hover">
|
||||
<div {{bind-attr class=":host-name model.stateColor"}}>
|
||||
<i {{bind-attr class=":fa model.stateIcon" tooltip=model.displayState}}></i>
|
||||
{{#link-to "host.index" model.id}}
|
||||
{{model.displayName}}
|
||||
{{/link-to}}
|
||||
<div class="host-ip">{{model.displayIp}}</div>
|
||||
</div>
|
||||
{{resource-actions model=model}}
|
||||
</div>
|
||||
|
||||
<div class="no-resource-action-hover">
|
||||
{{#each item in model.instances itemController="container"}}
|
||||
{{container-widget model=item}}
|
||||
{{else}}
|
||||
<div class="text-center text-muted">No containers yet.</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
|
||||
{{#link-to "hosts.containerNew" (query-params hostId=model.id tab="basic") tagName="div" classNames="add-to-host" tooltip="Create Container"}}
|
||||
<span class="fa-stack fa-lg">
|
||||
<i class="fa fa-circle-thin fa-stack-2x"></i>
|
||||
<i class="fa fa-plus fa-stack-1x"></i>
|
||||
</span>
|
||||
{{/link-to}}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
model: null,
|
||||
isDetail: false,
|
||||
|
||||
classNames: ['resource-actions'],
|
||||
|
||||
activeActions: function() {
|
||||
var detailed = this.get('isDetail');
|
||||
return (this.get('model.availableActions')||[]).filter(function(act) {
|
||||
return Ember.get(act,'enabled') && (detailed || !Ember.get(act,'detail'));
|
||||
});
|
||||
}.property('model.availableActions.[]','model.availableActions.@each.enabled','isDetail'),
|
||||
|
||||
actions: {
|
||||
clicked: function(actionName) {
|
||||
this.get('model').send(actionName);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{{#each item in activeActions}}
|
||||
{{action-button
|
||||
tooltip=item.tooltip
|
||||
icon=item.icon
|
||||
action="clicked"
|
||||
actionArg=item.action
|
||||
altActionArg=item.altAction
|
||||
}}
|
||||
{{/each}}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
import Ember from 'ember';
|
||||
import Cattle from 'ui/utils/cattle';
|
||||
|
||||
var ContainerController = Cattle.TransitioningResourceController.extend({
|
||||
|
|
@ -29,19 +30,46 @@ var ContainerController = Cattle.TransitioningResourceController.extend({
|
|||
return this.doAction('purge');
|
||||
},
|
||||
|
||||
redirectTo: function(name) {
|
||||
// @TODO Fix this hackery for nested components...
|
||||
// http://emberjs.jsbin.com/mecesakase
|
||||
if ( Ember.Component.detectInstance(this.get('target')) )
|
||||
{
|
||||
this.set('target', window.l('router:main'));
|
||||
}
|
||||
|
||||
this.transitionToRoute(name, this.get('id'));
|
||||
},
|
||||
|
||||
shell: function() {
|
||||
this.transitionToRoute('container.shell', this.get('model'));
|
||||
this.send('redirectTo','container.shell');
|
||||
},
|
||||
|
||||
edit: function() {
|
||||
this.transitionToRoute('container.edit', this.get('model'));
|
||||
this.send('redirectTo','container.edit');
|
||||
},
|
||||
|
||||
promptDelete: function() {
|
||||
this.transitionToRoute('container.delete', this.get('model'));
|
||||
this.send('redirectTo','container.delete');
|
||||
},
|
||||
},
|
||||
|
||||
availableActions: function() {
|
||||
var a = this.get('actions');
|
||||
|
||||
return [
|
||||
{ tooltip: 'Edit', icon: 'fa-edit', action: 'edit', enabled: !!a.update },
|
||||
{ tooltip: 'View in API', icon: 'fa-external-link', action: 'goToApi', enabled: true, detail: true },
|
||||
{ tooltip: 'Execute Shell', icon: 'fa-terminal', action: 'shell', enabled: !!a.execute },
|
||||
{ tooltip: 'Restart', icon: 'fa-refresh', action: 'restart', enabled: !!a.restart },
|
||||
{ tooltip: 'Start', icon: 'fa-arrow-up', action: 'start', enabled: !!a.start },
|
||||
{ tooltip: 'Stop', icon: 'fa-arrow-down', action: 'stop', enabled: !!a.stop },
|
||||
{ tooltip: 'Restore', icon: 'fa-ambulance', action: 'restore', enabled: !!a.restore },
|
||||
{ tooltip: 'Delete', icon: 'fa-trash-o', action: 'promptDelete', enabled: this.get('canDelete'), altAction: 'delete' },
|
||||
{ tooltip: 'Purge', icon: 'fa-fire', action: 'purge', enabled: !!a.purge },
|
||||
];
|
||||
}.property('actions.{update,execute,restart,start,stop,restore,purge}','canDelete'),
|
||||
|
||||
isOn: function() {
|
||||
return ['running','updating-running','migrating','restarting'].indexOf(this.get('state')) >= 0;
|
||||
}.property('state'),
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
{{transitioningMessage}}
|
||||
</div>
|
||||
<div class="instance-actions">
|
||||
{{partial "container/actions"}}
|
||||
{{resource-actions model=this isDetail=true}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,16 +2,39 @@ import Cattle from 'ui/utils/cattle';
|
|||
|
||||
var HostController = Cattle.TransitioningResourceController.extend({
|
||||
actions: {
|
||||
activate: function() { return this.doAction('activate'); },
|
||||
deactivate: function() { return this.doAction('deactivate'); },
|
||||
delete: function() { return this.delete(); },
|
||||
purge: function() { return this.doAction('purge'); },
|
||||
activate: function() {
|
||||
return this.doAction('activate');
|
||||
},
|
||||
|
||||
deactivate: function() {
|
||||
return this.doAction('deactivate');
|
||||
},
|
||||
|
||||
delete: function() {
|
||||
return this.delete();
|
||||
},
|
||||
|
||||
purge: function() {
|
||||
return this.doAction('purge');
|
||||
},
|
||||
|
||||
promptDelete: function() {
|
||||
this.transitionToRoute('host.delete', this.get('model'));
|
||||
},
|
||||
},
|
||||
|
||||
availableActions: function() {
|
||||
var a = this.get('actions');
|
||||
|
||||
return [
|
||||
{ tooltip: 'View in API', icon: 'fa-external-link', action: 'goToApi', enabled: true, detail: true },
|
||||
{ tooltip: 'Activate', icon: 'fa-arrow-up', action: 'activate', enabled: !!a.activate },
|
||||
{ tooltip: 'Deactivate', icon: 'fa-arrow-down', action: 'deactivate', enabled: !!a.deactivate },
|
||||
{ tooltip: 'Delete', icon: 'fa-trash-o', action: 'promptDelete', enabled: !!a.remove, altAction: 'delete' },
|
||||
{ tooltip: 'Purge', icon: 'fa-fire', action: 'purge', enabled: !!a.purge },
|
||||
];
|
||||
}.property('actions.{activate,deactivate,remove,purge}'),
|
||||
|
||||
displayIp: function() {
|
||||
var obj = (this.get('ipAddresses')||[]).get('firstObject');
|
||||
if ( obj )
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
<div {{bind-attr class=":instance-name stateColor"}}>
|
||||
<i {{bind-attr class=":fa stateIcon" tooltip=displayState}}></i>
|
||||
{{#link-to "container" this.id}}{{displayName}}{{/link-to}}
|
||||
</div>
|
||||
<div class="instance-actions">
|
||||
{{partial "container/actions"}}
|
||||
</div>
|
||||
|
||||
<div {{bind-attr class="isOn::text-muted"}}>{{displayIp}}</div>
|
||||
|
||||
<div {{bind-attr class=":force-wrap isError:text-danger:text-muted showTransitioningMessage::hide"}}>
|
||||
{{transitioningMessage}}
|
||||
</div>
|
||||
|
||||
<div {{bind-attr class="isTransitioning::hide :progress :progress-striped :active"}}>
|
||||
<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>
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
export default Ember.View.extend({
|
||||
classNames: ['instance'],
|
||||
tagName: 'DIV',
|
||||
templateName: 'host/instance',
|
||||
});
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
{{transitioningMessage}}
|
||||
</div>
|
||||
<div class="host-actions">
|
||||
{{partial "host/actions"}}
|
||||
{{resource-actions model=this}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -44,7 +44,9 @@
|
|||
<label>Containers</label>
|
||||
{{#each col in view.columns}}
|
||||
<div class="instance-column">
|
||||
{{each col itemViewClass="host/instance" itemController="container"}}
|
||||
{{#each item in col itemController="container"}}
|
||||
{{container-widget model=item}}
|
||||
{{/each}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div style="padding: 20px; text-align: center;" class="text-muted">
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@
|
|||
{{each host.instances itemViewClass="instanceDot" itemController="container"}}
|
||||
{{/each}}
|
||||
{{else}}
|
||||
{{each col itemViewClass="hosts/item" itemController="host"}}
|
||||
{{#each host in col itemController="host"}}
|
||||
{{host-widget model=host}}
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/each}}
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
<div class="host-header">
|
||||
<div {{bind-attr class=":host-name stateColor"}}>
|
||||
<i {{bind-attr class=":fa stateIcon" tooltip="displayState"}}></i>
|
||||
{{#link-to "host.index" this.id}}
|
||||
{{displayName}}
|
||||
{{/link-to}}
|
||||
<div class="host-ip">{{displayIp}}</div>
|
||||
</div>
|
||||
|
||||
<div class="host-actions">
|
||||
{{partial "host/actions"}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#each instances itemController="container"}}
|
||||
{{view "host/instance"}}
|
||||
{{else}}
|
||||
<div class="text-center text-muted">No containers yet.</div>
|
||||
{{/each}}
|
||||
|
||||
{{#link-to "hosts.containerNew" (query-params hostId=this.id tab="basic") tagName="div" classNames="add-to-host" tooltip="Create Container"}}
|
||||
<span class="fa-stack fa-lg">
|
||||
<i class="fa fa-circle-thin fa-stack-2x"></i>
|
||||
<i class="fa fa-plus fa-stack-1x"></i>
|
||||
</span>
|
||||
{{/link-to}}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
export default Ember.View.extend({
|
||||
classNames: ['host'],
|
||||
templateName: 'hosts/item',
|
||||
});
|
||||
|
|
@ -22,6 +22,16 @@ var VolumeController = Cattle.TransitioningResourceController.extend({
|
|||
},
|
||||
},
|
||||
|
||||
availableActions: function() {
|
||||
var a = this.get('actions');
|
||||
|
||||
return [
|
||||
{ tooltip: 'Restore', icon: 'fa-ambulance', action: 'restore', enabled: !!a.restore },
|
||||
{ tooltip: 'Delete', icon: 'fa-trash-o', action: 'promptDelete', enabled: this.get('canDelete'), altAction: 'delete' },
|
||||
{ tooltip: 'Purge', icon: 'fa-fire', action: 'purge', enabled: !!a.purge },
|
||||
];
|
||||
}.property('actions.{restore,purge}','canDelete'),
|
||||
|
||||
displayUri: function() {
|
||||
return (this.get('uri')||'').replace(/^file:\/\//,'');
|
||||
}.property('uri'),
|
||||
|
|
|
|||
|
|
@ -1,48 +1,50 @@
|
|||
<section>
|
||||
<table class="table fixed" style="margin-bottom: 0">
|
||||
<tr>
|
||||
<th width="120">State</th>
|
||||
<th>Name</th>
|
||||
<th>Containers</th>
|
||||
<th>Created</th>
|
||||
<th width="140"> </th>
|
||||
</tr>
|
||||
<tr class="no-lines">
|
||||
<th colspan="5" class="text-muted">Host Path
|
||||
</tr>
|
||||
{{#each volume in nonRootVolumes itemController="volume"}}
|
||||
<tbody>
|
||||
<tr>
|
||||
<td {{bind-attr class="volume.stateColor"}}>
|
||||
<i {{bind-attr class=":fa volume.stateIcon"}}></i> {{volume.displayState}}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{volume.displayName}}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{#if volume.activeMounts.length}}
|
||||
{{volume.activeMounts.length}}
|
||||
{{else}}
|
||||
<span class="text-muted">None</span>
|
||||
{{/if}}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<div class="text-muted">{{date-calendar volume.created}}</div>
|
||||
</td>
|
||||
|
||||
<td align="right">
|
||||
<button type="button" {{bind-attr class=":btn :btn-sm :btn-info volume.canDelete::hide"}} {{action "promptDelete"}} tooltip="Delete"><i class="fa fa-trash-o"></i></button>
|
||||
<button type="button" {{bind-attr class=":btn :btn-sm :btn-info volume.actions.restore::hide"}} {{action "restore"}} tooltip="Restore"><i class="fa fa-ambulance"></i></button>
|
||||
<button type="button" {{bind-attr class=":btn :btn-sm :btn-info volume.actions.purge::hide"}} {{action "purge"}} tooltip="Purge"><i class="fa fa-fire"></i></button>
|
||||
</td>
|
||||
<th width="120">State</th>
|
||||
<th>Name</th>
|
||||
<th>Containers</th>
|
||||
<th>Created</th>
|
||||
<th width="140"> </th>
|
||||
</tr>
|
||||
<tr class="no-lines">
|
||||
<td colspan="5" class="text-muted clip">
|
||||
{{volume.displayUri}}
|
||||
</td>
|
||||
<th colspan="5" class="text-muted">Host Path
|
||||
</tr>
|
||||
</tbody>
|
||||
{{#each volume in nonRootVolumes itemController="volume"}}
|
||||
<tbody class="resource-action-hover">
|
||||
<tr>
|
||||
<td {{bind-attr class="volume.stateColor"}}>
|
||||
<i {{bind-attr class=":fa volume.stateIcon"}}></i> {{volume.displayState}}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{volume.displayName}}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{#if volume.activeMounts.length}}
|
||||
{{volume.activeMounts.length}}
|
||||
{{else}}
|
||||
<span class="text-muted">None</span>
|
||||
{{/if}}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<div class="text-muted">{{date-calendar volume.created}}</div>
|
||||
</td>
|
||||
|
||||
<td align="right" rowspan="2">
|
||||
{{resource-actions model=volume}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="no-lines">
|
||||
<td colspan="4" class="text-muted clip">
|
||||
{{volume.displayUri}}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
{{/each}}
|
||||
</table>
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
@import "app/styles/growl";
|
||||
|
||||
@import "app/styles/resource-actions";
|
||||
@import "app/styles/layout";
|
||||
@import "app/styles/overlay";
|
||||
@import "app/styles/progress-bar";
|
||||
|
|
|
|||
|
|
@ -72,7 +72,8 @@ H1, H2, H3, H4, H5, H6 {
|
|||
.table.no-lines > TBODY > TR > TH,
|
||||
.table.no-lines > TBODY > TR > TD,
|
||||
.table.no-lines > TFOOT > TR > TH,
|
||||
.table.no-lines > TFOOT > TR > TD {
|
||||
.table.no-lines > TFOOT > TR > TD,
|
||||
.table > TBODY + TBODY {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -99,33 +99,6 @@ $instance-column-width: $host-column-width - 20px;
|
|||
color: black;
|
||||
}
|
||||
|
||||
.host .host-actions,
|
||||
.instance .instance-actions {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.host-actions,
|
||||
.instance-actions {
|
||||
BUTTON {
|
||||
color: #444;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
BUTTON:hover {
|
||||
color: #1d6fa5;
|
||||
}
|
||||
}
|
||||
|
||||
.instance-actions {
|
||||
padding: 5px 10px 5px 0;
|
||||
}
|
||||
|
||||
.instance-detail .instance-actions {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.instance {
|
||||
position: relative;
|
||||
border: 1px solid #e7eaee;
|
||||
|
|
@ -179,22 +152,6 @@ $instance-column-width: $host-column-width - 20px;
|
|||
}
|
||||
}
|
||||
|
||||
/* Hover actions on devices with mice, always shown on devices with touch */
|
||||
.no-touch {
|
||||
.host-actions,
|
||||
.instance-actions {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.host:hover .host-actions,
|
||||
.instance:hover .instance-actions,
|
||||
.host-detail .host-actions,
|
||||
.instance-detail .instance-actions {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
.dot {
|
||||
float: left;
|
||||
margin: 2px;
|
||||
|
|
@ -218,3 +175,14 @@ $instance-column-width: $host-column-width - 20px;
|
|||
position: absolute;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.host .resource-actions,
|
||||
.instance .resource-actions {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.instance .resource-actions {
|
||||
padding: 5px 10px 5px 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
.resource-actions {
|
||||
BUTTON {
|
||||
color: #444;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
BUTTON:hover {
|
||||
color: #1d6fa5;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Hover actions on devices with mice, always shown on devices with touch.
|
||||
|
||||
Put .resource-action-hover on a parent node that you want to trigger display of the actions on.
|
||||
|
||||
If there are nested nodes with actions, put .no-resource-action-hover on a node that wraps the inner nodes
|
||||
to prevent hover on the parent from triggering hover on the children.
|
||||
*/
|
||||
.no-touch {
|
||||
.resource-action-hover {
|
||||
.resource-actions {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.resource-actions {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.no-resource-action-hover {
|
||||
.resource-actions {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.no-resource-action-hover {
|
||||
.resource-action-hover:hover {
|
||||
.resource-actions {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
{{action-button enabled=actions.update tooltip="Edit" icon="fa-edit" action="edit"}}
|
||||
{{action-button enabled=view.isDetail tooltip="View in API" icon="fa-external-link" action="goToApi"}}
|
||||
{{action-button enabled=actions.execute tooltip="Execute Shell" icon="fa-terminal" action="shell"}}
|
||||
{{action-button enabled=actions.restart tooltip="Restart" icon="fa-refresh" action="restart"}}
|
||||
{{action-button enabled=actions.start tooltip="Start" icon="fa-arrow-up" action="start"}}
|
||||
{{action-button enabled=actions.stop tooltip="Stop" icon="fa-arrow-down" action="stop"}}
|
||||
{{action-button enabled=actions.restore tooltip="Restore" icon="fa-ambulance" action="restore"}}
|
||||
{{action-button enabled=canDelete tooltip="Delete" icon="fa-trash-o" action="promptDelete" altAction="delete"}}
|
||||
{{action-button enabled=actions.purge tooltip="Purge" icon="fa-fire" action="purge"}}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
{{action-button enabled=view.isDetail tooltip="View in API" icon="fa-external-link" action="goToApi"}}
|
||||
{{action-button enabled=actions.activate tooltip="Activate" icon="fa-arrow-up" action="activate"}}
|
||||
{{action-button enabled=actions.deactivate tooltip="Deactivate" icon="fa-arrow-down" action="deactivate"}}
|
||||
{{action-button enabled=actions.remove tooltip="Delete" icon="fa-trash-o" action="promptDelete" altAction="delete"}}
|
||||
{{action-button enabled=actions.purge tooltip="Purge" icon="fa-fire" action="purge"}}
|
||||
|
|
@ -9,12 +9,12 @@
|
|||
<th width="150">Size</th>
|
||||
<th>Usage</th>
|
||||
</tr>
|
||||
{{#each view.stats.filesystem}}
|
||||
{{#each fs in view.stats.filesystem}}
|
||||
<tr>
|
||||
<td>{{device}}</td>
|
||||
<td>{{size_gb}} GB</td>
|
||||
<td>{{fs.device}}</td>
|
||||
<td>{{fs.size_gb}} GB</td>
|
||||
<td>
|
||||
{{progress-bar value=used_percent textSuffix="% Used"}}
|
||||
{{progress-bar value=fs.used_percent textSuffix="% Used"}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
|
|
|
|||
|
|
@ -200,6 +200,24 @@ var TransitioningResourceController = ResourceController.extend({
|
|||
return model.doAction.apply(model,arguments);
|
||||
},
|
||||
|
||||
availableActions: function() {
|
||||
/*
|
||||
Override me and return [
|
||||
{
|
||||
enabled: true/false, // Whether it's enabled or greyed out
|
||||
detail: true/false, // If true, this action will only be shown on detailed screens
|
||||
tooltip: 'Delete', // Tooltip shown on hover
|
||||
icon: 'fa-trash-o', // Icon shown on screen
|
||||
action: 'promptDelete', // Action to call on the controller when clicked
|
||||
altAction: 'delete' // Action to call on the controller when alt+clicked
|
||||
},
|
||||
...
|
||||
]
|
||||
*/
|
||||
|
||||
return [];
|
||||
},
|
||||
|
||||
displayProgress: function() {
|
||||
var progress = this.get('transitioningProgress');
|
||||
if ( isNaN(progress) || !progress )
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"name": "ui",
|
||||
"dependencies": {
|
||||
"handlebars": "~1.3.0",
|
||||
"ember": "1.9.1",
|
||||
"handlebars": "2.0.0",
|
||||
"jquery": "^1.11.1",
|
||||
"ember": "1.8.1",
|
||||
"ember-data": "1.0.0-beta.12",
|
||||
"ember-resolver": "~0.1.10",
|
||||
"loader.js": "stefanpenner/loader.js#1.0.1",
|
||||
|
|
|
|||
|
|
@ -18,18 +18,17 @@
|
|||
"author": "Rancher Labs",
|
||||
"license": "Apache 2",
|
||||
"devDependencies": {
|
||||
"ember-api-store": "^1.0.6",
|
||||
|
||||
"body-parser": "^1.2.0",
|
||||
"broccoli-asset-rev": "^1.0.0",
|
||||
"broccoli-ember-hbs-template-compiler": "1.6.2",
|
||||
"broccoli-sass": "^0.3.3",
|
||||
"connect-restreamer": "^1.0.1",
|
||||
"ember-cli": "^0.1.4",
|
||||
"ember-api-store": "^1.0.6",
|
||||
"ember-cli": "^0.1.5",
|
||||
"ember-cli-content-security-policy": "0.3.0",
|
||||
"ember-cli-dependency-checker": "0.0.6",
|
||||
"ember-cli-dependency-checker": "0.0.7",
|
||||
"ember-cli-esnext": "0.1.1",
|
||||
"ember-cli-font-awesome": "0.0.4",
|
||||
"ember-cli-htmlbars": "^0.6.0",
|
||||
"ember-cli-inject-live-reload": "^1.3.0",
|
||||
"ember-cli-inline-content": "^0.3.1",
|
||||
"ember-cli-moment": "0.0.1",
|
||||
|
|
|
|||
|
|
@ -4,16 +4,16 @@ import Router from '../../router';
|
|||
import config from '../../config/environment';
|
||||
|
||||
export default function startApp(attrs) {
|
||||
var App;
|
||||
var application;
|
||||
|
||||
var attributes = Ember.merge({}, config.APP);
|
||||
attributes = Ember.merge(attributes, attrs); // use defaults, but you can override;
|
||||
|
||||
Ember.run(function() {
|
||||
App = Application.create(attributes);
|
||||
App.setupForTesting();
|
||||
App.injectTestHelpers();
|
||||
application = Application.create(attributes);
|
||||
application.setupForTesting();
|
||||
application.injectTestHelpers();
|
||||
});
|
||||
|
||||
return App;
|
||||
return application;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
import {
|
||||
moduleForComponent,
|
||||
test
|
||||
} from 'ember-qunit';
|
||||
|
||||
moduleForComponent('resource-actions', 'ResourceActionsComponent', {
|
||||
// specify the other units that are required for this test
|
||||
// needs: ['component:foo', 'helper:bar']
|
||||
});
|
||||
|
||||
test('it renders', function() {
|
||||
expect(2);
|
||||
|
||||
// creates the component instance
|
||||
var component = this.subject();
|
||||
equal(component._state, 'preRender');
|
||||
|
||||
// appends the component to the page
|
||||
this.append();
|
||||
equal(component._state, 'inDOM');
|
||||
});
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
import {
|
||||
moduleFor,
|
||||
test
|
||||
} from 'ember-qunit';
|
||||
|
||||
moduleFor('view:host/instance', 'HostInstanceView');
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function() {
|
||||
var view = this.subject();
|
||||
ok(view);
|
||||
});
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
import {
|
||||
moduleFor,
|
||||
test
|
||||
} from 'ember-qunit';
|
||||
|
||||
moduleFor('view:hosts/item', 'HostsItemView');
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function() {
|
||||
var view = this.subject();
|
||||
ok(view);
|
||||
});
|
||||
Loading…
Reference in New Issue