Bugs, cleanup unused

This commit is contained in:
Vincent Fiduccia 2017-08-12 21:56:49 -07:00
parent 2ea81bf3dd
commit 4107eb629e
No known key found for this signature in database
GPG Key ID: 2B29AD6BB2BB2582
57 changed files with 462 additions and 797 deletions

View File

@ -12,12 +12,10 @@ module.exports = {
"jQuery": true,
"$": true,
"moment": true,
"c3": true,
"d3": true,
"Terminal": true,
"Prism": true,
"Ui": true,
"dagreD3": true,
"async": true,
"AWS": true,
"Identicon": true,

View File

@ -19,7 +19,14 @@ export default Ember.Route.extend({
return Ember.RSVP.hash(dependencies).then((hash) => {
let service;
hash.mode = 'service';
if ( hash.existingService ) {
if ( hash.existingService.get('isGlobalScale') ) {
hash.mode = 'global';
}
if ( params.upgrade+'' === 'true' ) {
service = hash.existingService.clone();

View File

@ -1,4 +1,5 @@
{{new-edit-balancer
mode=model.mode
service=model.service
existing=model.existing
editing=upgrade

View File

@ -1,5 +1,5 @@
<div class="accordion-header" {{action expand this}}>
<div class="expand"><i role="button" class="icon icon-play eased text-small btn bg-transparent p-10 {{if expanded 'icon-rotate-90'}}"><span class="visually-hidden">Open accordion</span></i></div>
<div class="expand"><i role="button" class="icon icon-play eased text-small btn bg-transparent {{if expanded 'icon-rotate-90'}}"><span class="visually-hidden">Open accordion</span></i></div>
<div class="title">
<span class="m-0">{{title}}</span>
<p class="help-block">{{detail}}</p>

View File

@ -2,7 +2,20 @@ import Ember from 'ember';
import ContainerChoices from 'ui/mixins/container-choices';
import { STATUS, STATUS_INTL_KEY, classForStatus } from 'ui/components/accordion-list-item/component';
const headers = [
{
name: 'name',
translationKey: 'formContainerLinks.name.label',
},
{
name: 'alias',
translationKey: 'formContainerLinks.alias.label',
},
];
export default Ember.Component.extend(ContainerChoices, {
growl: Ember.inject.service(),
// Inputs
editing: null,
instance: null,
@ -12,6 +25,8 @@ export default Ember.Component.extend(ContainerChoices, {
tagName: '',
errors: null,
headers,
actions: {
addLink: function() {
let links = this.get('linksArray');
@ -30,6 +45,28 @@ export default Ember.Component.extend(ContainerChoices, {
removeLink: function(obj) {
this.get('linksArray').removeObject(obj);
},
followLink: function(str) {
let stack, stackName, containerName;
if ( str.includes('/')) {
[stackName, containerName] = name.split('/');
let stacks = this.get('store').all('stack');
stack = stacks.findBy('name', stackName);
} else {
stack = this.get('stack');
containerName = str;
}
if ( stack ) {
let container = stack.get('instances').findBy('name', containerName);
if ( container ) {
this.get('router').transitionTo('container', container.get('id'));
return;
}
}
this.get('growl').fromError('Unable to find container for "'+name+'"');
},
},
statusClass: null,

View File

@ -6,13 +6,12 @@
expandAll=expandAll
expand=(action expandFn)
}}
{{#if editing}}
<button class="btn bg-link icon-btn" {{action "addLink"}}>
<span class="darken"><i class="icon icon-plus text-small"/></span>
<span>{{t 'formContainerLinks.addActionLabel'}}</span>
</button>
<button class="btn bg-link icon-btn" {{action "addLink"}}>
<span class="darken"><i class="icon icon-plus text-small"/></span>
<span>{{t 'formContainerLinks.addActionLabel'}}</span>
</button>
{{#if linksArray.length}}
<table class="table fixed no-lines no-top-padding mt-10">
<tr class="acc-label">
<th>{{t 'formContainerLinks.name.label'}}</th>
@ -23,21 +22,17 @@
{{#each linksArray as |link|}}
<tr>
<td>
{{schema/input-container
value=link.name
exclude=launchConfig.id
stack=stack
}}
{{schema/input-container
value=link.name
exclude=launchConfig.id
stack=stack
}}
</td>
<td class="text-center">
<p><i class="icon icon-chevron-right"></i></p>
</td>
<td>
{{#if editing}}
<p class="input-sm text-muted">{{link.alias}}</p>
{{else}}
{{input class="form-control input-sm" type="text" value=link.alias placeholder=(t 'formContainerLinks.alias.placeholder')}}
{{/if}}
{{input class="form-control input-sm" type="text" value=link.alias placeholder=(t 'formContainerLinks.alias.placeholder')}}
</td>
<td class="text-right">
{{#unless link.existing}}
@ -47,6 +42,25 @@
</tr>
{{/each}}
</table>
{{else}}
{{#sortable-table
classNames="grid sortable-table"
body=linksArray
bulkActions=false
fullRows=true
pagingLabel="pagination.link"
headers=headers as |sortable kind row dt|}}
{{#if (eq kind "row")}}
<tr>
<td><a {{action "followLink" row.name}}>{{row.name}}</a></td>
<td>{{row.alias}}</td>
</tr>
{{else if (eq kind "nomatch")}}
<tr><td colspan="{{sortable.fullColspan}}" class="text-center text-muted lacsso pt-20 pb-20">{{t 'formContainerLinks.noMatch'}}</td></tr>
{{else if (eq kind "norows")}}
<tr><td colspan="{{sortable.fullColspan}}" class="text-center text-muted lacsso pt-20 pb-20">{{t 'formContainerLinks.noData'}}</td></tr>
{{/if}}
{{/sortable-table}}
{{/if}}
{{/accordion-list-item}}

View File

@ -39,7 +39,7 @@ export default Ember.Component.extend({
volumeChoices: function() {
let store = this.get('store');
let allVolumes = store.all('volume');
let stackId = this.get('stackId');
let stackId = this.get('stack.id');
let out = allVolumes.slice();
if ( this.get('isService') ) {
@ -51,7 +51,7 @@ export default Ember.Component.extend({
}
return out.sortBy('displayNameScope','id');
}.property('allVolumes.[]','allVolumeTemplates.[]','isService'),
}.property('allVolumes.[]','allVolumeTemplates.[]','isService','stack.id'),
containerChoices: function() {
var list = [];

View File

@ -1,12 +1,11 @@
import Ember from 'ember';
import NewOrEdit from 'ui/mixins/new-or-edit';
import SelectTab from 'ui/mixins/select-tab';
import { debouncedObserver } from 'ui/utils/debounce';
import C from 'ui/utils/constants';
import { flattenLabelArrays } from 'ui/mixins/manage-labels';
import Util from 'ui/utils/util';
export default Ember.Component.extend(NewOrEdit, SelectTab, {
export default Ember.Component.extend(NewOrEdit, {
intl: Ember.inject.service(),
prefs: Ember.inject.service(),
settings: Ember.inject.service(),

View File

@ -156,6 +156,7 @@
{{/unless}}
{{else}}
{{container/form-container-links
editing=true
instance=launchConfig
stack=stack
expandAll=al.expandAll

View File

@ -28,8 +28,8 @@
{{entry.service.displayName}}
{{~/link-to~}}
{{/each}}
{{else if model.selectorContainer}}
<span>{{model.selectorContainer}}</span>
{{else if model.selector}}
<span>{{model.selector}}</span>
{{else}}
{{model.displayTargets}}
{{/if}}

View File

@ -1,14 +1,20 @@
<td data-title="{{dt.instanceName}}" class="clip">
<a href="{{href-to 'container' model.instanceId}}">{{model.instanceName}}</a>
</td>
<td data-title="{{dt.path}}" class="clip">
{{#copy-inline clipboardText=model.path}}
{{model.path}}
{{/copy-inline}}
</td>
<td data-title="{{dt.displayPermission}}" class="clip">
{{model.displayPermission}}
</td>
<td data-title="{{dt.volumeName}}" class="clip">
<a href="{{href-to 'volume' model.volumeId}}">{{model.displayVolumeName}}</a>
</td>
<tr>
<td data-title="{{dt.serviceName}}" class="clip">
{{#if model.instance.service}}
<a href="{{href-to 'service' model.instance.service.id}}">{{model.instance.service.displayName}}</a>
{{else}}
<span class="text-muted">{{t 'generic.na'}}</span>
{{/if}}
</td>
<td data-title="{{dt.instanceName}}" class="clip">
<a href="{{href-to 'container' model.instanceId}}">{{model.instanceName}}</a>
</td>
<td data-title="{{dt.path}}" class="clip">
{{#copy-inline clipboardText=model.path}}
{{model.path}}
{{/copy-inline}}
</td>
<td data-title="{{dt.displayPermission}}" class="clip">
{{model.displayPermission}}
</td>
</tr>

View File

@ -13,6 +13,7 @@
<div class="col span-11-of-23 mt-0 mb-0 offset-1-of-23">
{{container/form-scale
mode=mode
initialLabels=launchConfig.labels
initialScale=service.scale
editing=editing

View File

@ -4,7 +4,7 @@ import NewOrEdit from 'ui/mixins/new-or-edit';
const HOSTNAME = 'externalhostname';
const IP = 'externalip';
const ALIAS = 'dnsservice';
const SELECTOR = 'service';
const SELECTOR = 'selectorservice';
function modeToType(mode) {
if ( mode === HOSTNAME || mode === IP ) {
@ -26,7 +26,7 @@ export default Ember.Component.extend(NewOrEdit, {
targetServicesAsMaps: null,
targetIpArray: null,
stack: null,
stackErrors: null,
stackErrors: null,
actions: {
done() {
@ -120,7 +120,7 @@ export default Ember.Component.extend(NewOrEdit, {
}
break;
case SELECTOR:
if ( !this.get('record.selectorContainer.length') ) {
if ( !this.get('record.selector.length') ) {
errors.pushObject(this.get('intl').t('editDns.errors.selectorRequired'));
}
break;

View File

@ -90,9 +90,9 @@
{{/if}}
{{else}}
<div class="mb-20">
<label>{{t 'editDns.selectorContainer.label'}}{{field-required}}</label>
<label>{{t 'editDns.selector.label'}}{{field-required}}</label>
</div>
{{input value=record.selectorContainer placeholder=(t 'editDns.selectorContainer.placeholder')}}
{{input value=record.selector placeholder=(t 'editDns.selector.placeholder')}}
{{/if}}
</div>
</div>

View File

@ -1,13 +0,0 @@
import Ember from 'ember';
import SelectTab from 'ui/mixins/select-tab';
export default Ember.Component.extend(SelectTab, {
tagName : 'section',
initialTab : '',
init: function() {
this._super(...arguments);
Ember.run.scheduleOnce('afterRender', () => {
this.send('selectTab', this.get('initialTab'));
});
}
});

View File

@ -1 +0,0 @@
{{yield this}}

View File

@ -3,14 +3,7 @@ import Ember from 'ember';
export default Ember.Component.extend({
prefs: Ember.inject.service(),
stickyHeader: true,
showHost: true,
showStats: false,
showInstanceState: true,
pagingLabel: 'pagination.entry',
sortBy: 'name',
model: null,
headers: [
{

View File

@ -1,8 +1,6 @@
{{#sortable-table
classNames="grid sortable-table"
body=logs
searchText=searchText
sortBy=sortBy
body=model
bulkActions=false
search=true
fullRows=true

View File

@ -1,33 +0,0 @@
import Ember from 'ember';
export default Ember.Component.extend({
model: null,
single: false,
classNames: ['stack-section','storage', 'clear-section'],
sortBy: 'name',
headers: [
{
name: 'state',
sort: ['state','displayName','id'],
translationKey: 'generic.state',
width: 115,
},
{
name: 'name',
sort: ['displayName','id'],
translationKey: 'storagePoolSection.models.table.header.volumeName',
width: 350,
},
{
name: 'mounts',
translationKey: 'storagePoolSection.models.table.header.mounts',
sort: ['mounts.length:desc', 'displayName','id'],
},
],
hostsByName: function() {
return (this.get('model.hosts')||[]).sortBy('displayName');
}.property('model.hosts.@each.displayName'),
});

View File

@ -1,94 +0,0 @@
<div class="banner bg-info {{if single model.stateBackground}} {{if single 'single'}}">
<div class="collapser"></div>
<div class="pull-left">
{{#unless single}}
<div class="banner-message">
<p>{{badge-state model=model}}</p>
</div>
{{/unless}}
<div class="banner-message">
<p class="divider clip">{{model.name}}</p>
{{!-- when storage pools details ready --}}
{{!-- {{#if single}} --}}
{{!-- <span class="divider clip">{{model.name}}</span> --}}
{{!-- {{else}} --}}
{{!-- <span class="divider clip">{{#link-to "storagepools.detail" model.id}} {{model.name}}{{/link-to}}</span> --}}
{{!-- {{/if}} --}}
</div>
</div>
<div class="stack-actions pull-right mt-10 mr-10">
{{#unless single}}
{{#link-to "storagepools.new-volume" (query-params driverName=model.driverName) classNames="btn bg-primary btn-sm"}}{{t 'storagePoolSection.volumes.add'}}{{/link-to}}
{{/unless}}
</div>
</div>
<div class="stack-body row">
<div class="box col span-3">
<h2>{{t 'storagePoolSection.hosts.header'}}</h2>
<div class="clearfix hosts">
{{#each hostsByName as |host|}}
<div class="mb-10"><i class="badge-state icon {{host.stateIcon}} {{host.stateBackground}}"></i> {{#link-to "host" host.id}}{{host.displayName}}{{/link-to}}</div>
{{else}}
<div class="text-center text-muted">{{t 'storagePoolSection.hosts.none'}}</div>
{{/each}}
</div>
</div>
{{#if model.volumes.length}}
<div class="col span-9 col-full-height">
<h2>{{t 'storagePoolSection.volumes.header'}}</h2>
{{#sortable-table
classNames="grid mb-0 sortable-table"
bulkActions=false
paging=false
search=false
sortBy=sortBy
descending=descending
headers=headers
body=model.volumes
as |sortable kind vol|
}}
{{#if (eq kind "row")}}
<td class="state">
{{badge-state model=vol}}
</td>
<td class="force-wrap">
{{#tooltip-element type="tooltip-basic" model=vol tooltipTemplate="tooltip-storage" tooltipFor="storagePoolSection"}}
<p class="hand force-wrap clip m-0">{{vol.displayName}}</p> <i classs="icon icon-info"></i>
{{/tooltip-element}}
</td>
<td class="force-wrap">
{{#if vol.mounts.length}}
{{#each vol.mounts as |mount|}}
<div>
{{~#if mount.instance.isVm~}}
{{#link-to "virtualmachine" mount.instanceId}}{{mount.instance.displayName}}{{/link-to}}
{{~else~}}
{{#link-to "container" mount.instanceId}}{{mount.instance.displayName}}{{/link-to}}
{{~/if~}}
: {{mount.path}}
{{#if (eq mount.permissions "ro")}}
<span class="text-muted">{{t 'storagePoolSection.readOnly'}}</span>
{{/if}}
</div>
{{/each}}
{{else}}
<span class="text-muted">{{t 'generic.none'}}</span>
{{/if}}
</td>
<td class="actions wide">
{{action-menu model=vol}}
</td>
{{else if (eq kind "norows")}}
<tr>
<td colspan="{{sortable.fullColspan}}" class="text-center text-muted">{{t 'storagePoolSection.volumes.none'}}</td>
</tr>
{{/if}}
{{/sortable-table}}
</div>
{{else}}
<div class="text-muted text-center pl-10">{{t 'storagePoolSection.volumes.none'}}</div>
{{/if}}
</div>

View File

@ -1,4 +1,5 @@
import Ember from 'ember';
import {headers} from 'ui/volume/controller';
export default Ember.Component.extend({
projects: Ember.inject.service(),
@ -9,6 +10,10 @@ export default Ember.Component.extend({
subMatches: null,
expanded: null,
bulkActions: true,
showActions: true,
headers: headers,
canExpand: function() {
return this.get('model.type').toLowerCase() === 'volumetemplate';
}.property('model.type'),

View File

@ -1,7 +1,9 @@
<tr class="main-row">
<td valign="middle" class="row-check" style="padding-top: 2px;">
{{check-box nodeId=model.id}}
</td>
{{#if bulkActions}}
<td valign="middle" class="row-check" style="padding-top: 2px;">
{{check-box nodeId=model.id}}
</td>
{{/if}}
<td>
{{#if canExpand}}<i role="button" {{action "toggle"}} class="icon icon-play eased text-small text-muted {{if expanded 'icon-rotate-90'}}"><span class="visually-hidden">Open accordion</span></i>{{/if}}
@ -31,9 +33,11 @@
{{model.driver}}
</td>
<td data-title="{{dt.actions}}" class="actions">
{{action-menu model=model}}
</td>
{{#if showActions}}
<td data-title="{{dt.actions}}" class="actions">
{{action-menu model=model}}
</td>
{{/if}}
</tr>
{{#if canExpand}}
@ -41,15 +45,25 @@
<td>{{! checkbox and expand}}</td>
<td colspan="{{sub fullColspan 2}}">
{{#if expanded}}
{{container-table
body=model.instances
stickyHeader=false
bulkActions=false
search=false
searchText=searchText
subRow=true
showHost=true
{{#sortable-table
classNames="grid fixed mb-0 sortable-table"
bulkActions=false
pagingLabel="pagination.volumes"
fullRows=true
rowActions=false
search=false
stickyHeader=false
headers=headers
body=model.volumes
as |sortable kind subVol dt|
}}
{{volume-row
model=subVol
bulkActions=false
fullColspan=sortable.fullColspan
dt=dt
}}
{{/sortable-table}}
{{/if}}
</td>
<td>{{! actions}}</td>

View File

@ -65,148 +65,138 @@
</div>
</section>
<!--error-->
{{#if model.container.showTransitioningMessage}}
<div class="{{model.container.stateColor}}"><p>{{model.container.transitioningMessage}}</p></div>
{{/if}}
<section>
{{#accordion-list as |al expandFn| }}
{{#accordion-list as |al expandFn|}}
<div>
{{container/form-command
instance=model.container
initialLabels=model.labels
editing=false
expandAll=al.expandAll
expandFn=expandFn
instance=model.container
initialLabels=model.labels
editing=false
expandAll=al.expandAll
expandFn=expandFn
}}
</div>
<div class="mt-20">
{{form-env-var
model=model.container.displayEnvironmentVars
expandAll=al.expandAll
expandFn=expandFn
model=model.container.displayEnvironmentVars
expandAll=al.expandAll
expandFn=expandFn
}}
</div>
<div class="mt-20">
{{form-healthcheck
healthCheck=model.container.healthCheck
editing=false
expandAll=al.expandAll
expandFn=expandFn
healthCheck=model.container.healthCheck
editing=false
expandAll=al.expandAll
expandFn=expandFn
}}
</div>
<div class="mt-20">
{{container/form-scheduling
initialHostId=model.container.requestedHostId
initialLabels=model.container.labels
isGlobal=model.container.isGlobalScale
allHosts=model.hosts
editing=false
expandAll=al.expandAll
expandFn=expandFn
initialHostId=model.container.requestedHostId
initialLabels=model.container.labels
isGlobal=model.container.isGlobalScale
allHosts=model.hosts
editing=false
expandAll=al.expandAll
expandFn=expandFn
}}
</div>
<div class="mt-20">
{{labels-section
model=model.container
expandAll=al.expandAll
expandFn=expandFn
model=model.container
expandAll=al.expandAll
expandFn=expandFn
}}
</div>
<div class="mt-20">
{{#accordion-list-item
title=(t 'containerPage.linksTab.header')
detail=(t 'containerPage.linksTab.detail')
status=(t 'pagination.link' pages=1 count=model.instanceLinks.length)
statusClass=(if model.instanceLinks.length 'bg-success' 'text-muted')
expandAll=al.expandAll
expand=(action expandFn)
{{container/form-container-links
editing=false
instance=model.container
stack=model.container.stack
expandAll=al.expandAll
expandFn=(action expandFn)
}}
<ul class="list-unstyled list-inline with-room">
{{#each model.instanceLinks as |link|}}
<li>
<a href="{{href-to 'container' link.targetInstanceId }}">
{{link.linkedInstanceName}} as {{link.linkName}}
</a>
</li>
{{else}}
<li class="text-muted text-center">{{t 'containerPage.linksTab.noData'}}</li>
{{/each}}
</ul>
{{/accordion-list-item}}
</div>
<div class="mt-20">
{{container/form-networking
editing=false
instance=model.container
initialLabels=model.container.labels
allHosts=model.hosts
expandAll=al.expandAll
expandFn=expandFn
editing=false
instance=model.container
initialLabels=model.container.labels
allHosts=model.hosts
expandAll=al.expandAll
expandFn=expandFn
}}
</div>
<div class="mt-20">
{{#accordion-list-item
title=(t 'containerPage.portsTab.header')
detail=(t 'containerPage.portsTab.detail')
status=(t 'pagination.port' pages=1 count=model.container.publicEndpoints.length)
statusClass=(if model.container.publicEndpoints.length 'bg-success' 'text-muted')
expandAll=al.expandAll
expand=(action expandFn)
as | parent |
title=(t 'containerPage.portsTab.header')
detail=(t 'containerPage.portsTab.detail')
status=(t 'pagination.port' pages=1 count=model.container.publicEndpoints.length)
statusClass=(if model.container.publicEndpoints.length 'bg-success' 'text-muted')
expandAll=al.expandAll
expand=(action expandFn)
componentName='container-table'
as | parent |
}}
{{public-endpoints model=model.container}}
{{compontent parent.intent
model=model.container
}}
{{/accordion-list-item}}
</div>
<div class="mt-20">
{{container/form-security
instance=model.container
editing=false
expandAll=al.expandAll
expandFn=expandFn
instance=model.container
editing=false
expandAll=al.expandAll
expandFn=expandFn
}}
</div>
<div class="mt-20">
{{container/form-secrets
instance=model.container
editing=false
expandAll=al.expandAll
expandFn=expandFn
instance=model.container
editing=false
expandAll=al.expandAll
expandFn=expandFn
}}
</div>
<div class="mt-20">
{{#accordion-list-item
title=(t 'containerPage.volumesTab.header')
detail=(t 'containerPage.volumesTab.detail')
status=(t 'pagination.volume' pages=1 count=(or model.container.mounts.length 0))
statusClass=(if model.container.mounts.length 'bg-success' 'text-muted')
expandAll=al.expandAll
expand=(action expandFn)
componentName='sortable-table'
as | parent |
title=(t 'containerPage.volumesTab.header')
detail=(t 'containerPage.volumesTab.detail')
status=(t 'pagination.volume' pages=1 count=(or model.container.mounts.length 0))
statusClass=(if model.container.mounts.length 'bg-success' 'text-muted')
expandAll=al.expandAll
expand=(action expandFn)
componentName='sortable-table'
as | parent |
}}
{{#component parent.intent
classNames="grid sortable-table"
body=model.container.mounts
searchText=searchText
sortBy=sortBy
bulkActions=false
stickyHeader=false
pagingLabel="pagination.volume"
isVisible=parent.expanded
headers=storageHeaders as |sortable kind mount dt|}}
classNames="grid sortable-table"
body=model.container.mounts
searchText=searchText
sortBy=sortBy
bulkActions=false
stickyHeader=false
pagingLabel="pagination.volume"
isVisible=parent.expanded
headers=storageHeaders as |sortable kind mount dt|
}}
{{#if (eq kind "row")}}
<td data-title="{{dt.name}}">
{{mount.displayVolumeName}}

View File

@ -29,7 +29,7 @@ export const headers = [
},
{
name: 'scale',
sort: ['scale:desc','isGlobalScale:desc'],
sort: ['scale:desc','isGlobalScale:desc','displayName'],
searchField: null,
translationKey: 'stacksPage.table.scale',
classNames: 'text-center',

View File

@ -70,5 +70,4 @@ export default Ember.Mixin.create({
return '';
}
}.property('endpointsByPort.@each.{port,endpoints}', 'intl.locale'),
});

View File

@ -1,67 +0,0 @@
import Ember from 'ember';
export default Ember.Mixin.create({
k8s: Ember.inject.service(),
selectorsAsArray: function() {
var out = [];
var sel = this.get('spec.selector');
if ( typeof sel === 'string' )
{
sel.split(/\s*,\s*/).filter((str) => { return str.length > 0; }).forEach((pair) => {
var idx = pair.indexOf('=');
if ( idx >= 0 )
{
out.push({label: pair.substr(0,idx), value: pair.substr(idx+1) });
}
});
}
else if ( typeof sel === 'object' )
{
if ( sel.matchLabels ) {
Object.keys(sel.matchLabels).forEach((key) => {
out.push({label: key, value: sel.matchLabels[key]});
});
}
else
{
Object.keys(sel).forEach((key) => {
out.push({label: key, value: sel[key]});
});
}
}
return out;
}.property('spec.selector'),
_selected(field,method) {
var selectors = this.get('selectorsAsArray');
if ( selectors.length === 0 )
{
return [];
}
var ns = this.get('k8s.namespace.id');
var matching = this.get(field).slice();
selectors.forEach((sel) => {
matching = matching.filter((r) => {
if ( r.metadata && r.metadata.namespace && r.metadata.namespace !== ns ) {
return false;
}
return r[method](sel.label, sel.value);
});
});
return matching;
},
selectedPods: function() {
return this._selected('k8s.pods','hasLabel');
}.property('selectorsAsArray.@each.{label,value}','k8s.pods.[]','k8s.namespace.id'),
selectedReplicaSets: function() {
return this._selected('k8s.replicasets','hasLabel');
}.property('selectorsAsArray.@each.{label,value}','k8s.replicasets.[]','k8s.namespace.id'),
});

View File

@ -1,15 +0,0 @@
import Ember from 'ember';
export default Ember.Mixin.create({
tab: null,
actions: {
selectTab: function(name) {
this.set('tab', name);
this.$('.tab').removeClass('active');
this.$('.tab[data-section="'+name+'"]').addClass('active');
this.$('.section').addClass('hide');
this.$('.section[data-section="'+name+'"]').removeClass('hide');
}
}
});

View File

@ -25,6 +25,7 @@ export default Resource.extend({
return choices;
}.property('actionLinks.{remove,update}'),
issuedDate: function() {
return new Date(this.get('issuedAt'));
}.property('issuedAt'),

View File

@ -1,21 +1,8 @@
import Service from 'ui/models/service';
import Ember from 'ember';
import C from 'ui/utils/constants';
import Util from 'ui/utils/util';
import { parsePortSpec } from 'ui/utils/parse-port';
const esc = Ember.Handlebars.Utils.escapeExpression;
function portToStr(spec) {
var parts = parsePortSpec(spec,'http');
return parts.host + (parts.protocol === 'http' ? '' : '/' + parts.protocol);
}
function specToPort(spec) {
var parts = parsePortSpec(spec,'http');
return parts.hostPort;
}
var LoadBalancerService = Service.extend({
type: 'loadBalancerService',
@ -52,7 +39,7 @@ var LoadBalancerService = Service.extend({
// Set `ssl` on each endpoint since we know it from balancer listener context
(this.get('publicEndpoints')||[]).forEach((endpoint) => {
endpoint.set('tls', tlsPorts.includes(obj.publicPort));
endpoint.set('tls', tlsPorts.includes(endpoint.publicPort));
});
return this._super(...arguments);

View File

@ -4,7 +4,7 @@ import PolledResource from 'ui/mixins/cattle-polled-resource';
import C from 'ui/utils/constants';
import { parseExternalId } from 'ui/utils/parse-externalid';
const builtInUi = ['amazonec2','azure','digitalocean','exoscale','packet','rackspace','ubiquity','vmwarevsphere','aliyunecs'];
const builtInUi = ['amazonec2','azure','digitalocean','exoscale','packet','rackspace','vmwarevsphere','aliyunecs'];
function displayUrl(url) {
url = url||'';

View File

@ -10,6 +10,14 @@ export default Resource.extend({
instance: denormalizeId('instanceId'),
volume: denormalizeId('volumeId'),
availableActions: function() {
let choices = [
{ label: 'action.viewInApi', icon: 'icon icon-external-link', action: 'goToApi', enabled: true },
];
return choices;
}.property(),
displayVolumeName: Ember.computed('volumeName', function() {
let name = this.get('volumeName');
if ( name.match(/^[0-9a-f]{64}$/) ) {

View File

@ -294,7 +294,6 @@ var Service = Resource.extend(StateCounts, EndpointPorts, {
}.property('isReal','isSelector','lcType'),
isReal: function() {
let type = this.get('lcType');
if ( this.get('isSelector') ) {
return false;
}
@ -305,7 +304,7 @@ var Service = Resource.extend(StateCounts, EndpointPorts, {
'networkdriverservice',
'storagedriverservice',
'loadbalancerservice',
].includes(type);
].includes(this.get('lcType'));
}.property('lcType','isSelector'),
canHaveSidekicks: function() {
@ -314,13 +313,31 @@ var Service = Resource.extend(StateCounts, EndpointPorts, {
hasPorts: Ember.computed.alias('isReal'),
hasImage: Ember.computed.alias('isReal'),
hasLabels: Ember.computed.alias('isReal'),
canUpgrade: Ember.computed.alias('isReal'),
canHaveLabels: Ember.computed.alias('isReal'),
canScale: Ember.computed.alias('isReal'),
realButNotLb: function() {
return this.get('isReal') && !this.get('isBalancer');
}.property('isReal','isBalancer'),
canHaveLinks: Ember.computed.alias('realButNotLb'),
canChangeNetworking: Ember.computed.alias('realButNotLb'),
canChangeSecurity: Ember.computed.alias('realButNotLb'),
canHaveSecrets: Ember.computed.alias('realButNotLb'),
canHaveEnvironment: Ember.computed.alias('realButNotLb'),
canHaveHealthCheck: function() {
return [
'service',
'scalinggroup',
'externalservice',
].includes(this.get('lcType'));
}.property('lcType'),
isSelector: function() {
return !!this.get('selectorContainer');
}.property('selectorContainer'),
return !!this.get('selector');
}.property('selector'),
isBalancer: function() {
return ['loadbalancerservice'].indexOf(this.get('lcType')) >= 0;

View File

@ -7,9 +7,7 @@ var Volume = Resource.extend({
intl: Ember.inject.service(),
mounts: denormalizeIdArray('mountIds'),
stack: denormalizeId('stackId'),
isRoot: Ember.computed.notEmpty('instanceId'),
scope: function() {

View File

@ -14,8 +14,16 @@ var VolumeTemplate = Resource.extend({
this.set('_allVolumes', allVolumes);
}
return allVolumes.filterBy('volumeTempalteId', this.get('id'));
},
return allVolumes.filterBy('volumeTemplateId', this.get('id'));
}.property(),
mounts: function() {
let out = [];
this.get('volumes').forEach((volume) => {
out.pushObjects(volume.get('mounts')||[]);
});
return out;
}.property('volumes.@each.mounts'),
scope: function() {
if ( this.get('perContainer') ) {

View File

@ -105,7 +105,7 @@ Router.map(function() {
this.route('volume', {path: '/volume/:volume_id', resetNamespace: true});
});
this.route('service', {path: '/services/:scaling_group_id', resetNamespace: true});
this.route('service', {path: '/services/:service_id', resetNamespace: true});
this.route('stack', {path: '/stack/:stack_id', resetNamespace: true}, function() {
this.route('index', {path: '/'});

View File

@ -1,14 +1,16 @@
import Ember from 'ember';
export default Ember.Controller.extend({
service: Ember.computed.alias('model.service'),
stack: Ember.computed.alias('model.stack'),
application: Ember.inject.controller(),
service: Ember.computed.alias('model.service'),
rules: Ember.computed.alias('service.lbConfig.portRules'),
sortBy: 'priority',
fixedLaunchConfig: null,
activeLaunchConfig: null,
portSortBy: 'privatePort',
headers: [
{
name: 'priority',
@ -60,6 +62,7 @@ export default Ember.Controller.extend({
translationKey: 'formBalancerRules.backendName.label',
},
],
portHeaders: [
{
name: 'publicIp',

View File

@ -3,41 +3,23 @@ import FilteredSorted from 'ui/utils/filtered-sorted-array-proxy';
export default Ember.Route.extend({
model: function(params) {
var service = this.get('store').getById('service', params.scaling_group_id);
if ( service ) {
return Ember.RSVP.hash({
hosts: this.get('store').findAll('host'),
logs: this.getServiceLogs(service),
}).then((hash) => {
return this.get('store').find('service', params.service_id).then((service) => {
return this.getServiceLogs(service.get('id')).then((logs) => {
return Ember.Object.create({
service: service,
stack: service.get('stack'),
logs: hash.logs,
hosts: hash.hosts
service,
logs,
});
});
} else {
return Ember.RSVP.hash({
service: this.get('store').find('service', params.scaling_group_id),
hosts: this.get('store').findAll('host'),
}).then((hash) => {
return Ember.Object.create({
service: hash.service,
stack: hash.service.get('stack'),
hosts: hash.hosts
});
});
}
});
},
afterModel(model) {
if (model.get('service.initPorts')) {
model.get('service').initPorts();
}
},
getServiceLogs(model) {
let par = model;
let serviceId = par.get('id');
getServiceLogs(serviceId) {
// Find just the recent ones for this service
return this.get('store').find('serviceLog', null,{
filter: {serviceId: serviceId},
@ -45,22 +27,19 @@ export default Ember.Route.extend({
sortOrder: 'desc',
depaginate: false,
limit: 100
}).then(() => {
let all = this.get('store').all('serviceLog');
return Ember.Object.create({
logs: FilteredSorted.create({
sourceContent: all,
sortProperties: ['createdTS:desc'],
dependentKeys: ['sourceContent.@each.serviceId'],
filterFn: function(log) {
return log.get('serviceId') === serviceId;
}
})
});
});
return FilteredSorted.create({
sourceContent: this.get('store').all('serviceLog'),
dependentKeys: ['sourceContent.@each.serviceId'],
filterFn: function(log) {
return log.get('serviceId') === serviceId;
}
});
},
setupController(controller, model) {
this._super(controller, model);
this._super(...arguments);
let lc = model.get('service.launchConfig');
if (lc) {

View File

@ -2,7 +2,7 @@
<h1 class="pull-left">
{{t 'servicePage.header' type=service.displayType name=service.displayName}}
</h1>
{{#if service.canHaveContainers}}
{{#if (and service.canHaveContainers (not service.isSelector))}}
<div class="pull-left mt-5">
{{info-multi-stats model=service largeTargetId="largeStats"}}
</div>
@ -20,10 +20,8 @@
{{banner-message color='bg-secondary mb-0 mt-10' message=model.description}}
{{/if}}
{{!todo copy pasta}}
<section>
<div class="row banner bg-info basics">
{{#if fixedLaunchConfig.memoryReservation}}
<div class="inline-block">
<label class="acc-label p-0">{{t 'containersPage.containerPage.infoMultiStats.memoryReservation.labelText'}}</label>
@ -46,9 +44,9 @@
<hr>
{{/if}}
<div class="inline-block">
<label class="acc-label p-0" style="vertical-align: middle;">{{t 'servicePage.multistat.scale'}}</label>
{{#if service.canScale}}
{{#if service.canScale}}
<div class="inline-block">
<label class="acc-label p-0" style="vertical-align: middle;">{{t 'servicePage.multistat.scale'}}</label>
<span class="pr-5" style="vertical-align: middle;">
{{service.displayScale}}
</span>
@ -56,10 +54,8 @@
<button class="btn btn-xs bg-primary" {{action "scaleDown" target=service}} disabled={{not service.canScaleDown}}><i class="icon icon-minus icon-fw"/></button>
<button style="margin-left:2px;" class="btn btn-xs bg-primary" {{action "scaleUp" target=service}} disabled={{not service.canScaleUp}}><i class="icon icon-plus icon-fw"/></button>
</div>
{{else}}
{{t 'generic.na'}}
{{/if}}
</div>
</div>
{{/if}}
{{#if service.hasImage}}
<div class="inline-block">
@ -67,33 +63,26 @@
{{fixedLaunchConfig.image}} {{copy-to-clipboard clipboardText=fixedLaunchConfig.image size="small"}}
</div>
{{/if}}
{{#if service.externalIpAddresses}}
<div class="inline-block">
<label class="text-muted ml-15">{{t 'servicePage.external.externalIp' count=service.externalIpAddresses.length}}</label>
{{join-array service.externalIpAddresses}}
</div>
{{else if service.hostname}}
<div class="inline-block">
<label class="text-muted">{{t 'servicePage.external.externalHostname'}} </label> {{service.hostname}}
</div>
{{else if service.selector}}
<div class="inline-block">
<label class="text-muted">{{t 'servicePage.selector.label'}} </label> {{service.selector}}
</div>
{{/if}}
</div>
</section>
<section class="">
{{#accordion-list as |al expandFn| }}
{{#if (eq service.kind 'externalService')}}
{{!-- since external services are the only ones that have externalIp/hostname it didnt make sense to give extIps its own route like other services --}}
<hr/>
<section>
<div>
{{#if service.externalIpAddresses}}
<label class="text-muted ml-15">{{t 'servicePage.external.externalIp'}}</label>
<ul class="list-unstyled list-inline with-room">
{{#each service.externalIpAddresses as |ip|}}
<li>
<i class="icon icon-external-link"></i> {{ip}}
</li>
{{/each}}
</ul>
{{else}}
<label class="text-muted">{{t 'servicePage.external.externalHostname'}} </label> {{service.hostname}}
{{/if}}
</div>
</section>
<hr/>
{{/if}}
<section>
{{#accordion-list as |al expandFn|}}
{{#if service.canHaveContainers}}
{{#accordion-list-item
title=(t 'servicePage.containersTab.title')
@ -116,22 +105,50 @@
{{/accordion-list-item}}
{{/if}}
{{container/form-scheduling
initialHostId=activeLaunchConfig.requestedHostId
initialLabels=activeLaunchConfig.labels
isGlobal=model.service.isGlobalScale
allHosts=model.hosts
editing=false
expandAll=al.expandAll
expandFn=expandFn
classNames="accordion"
}}
{{#if service.isReal}}
{{#accordion-list-item
title=(t 'containerPage.portsTab.header')
detail=(t 'containerPage.portsTab.detail')
status=(t 'pagination.port' pages=1 count=model.container.publicEndpoints.length)
statusClass=(if model.container.publicEndpoints.length 'bg-success' 'text-muted')
expandAll=al.expandAll
expand=(action expandFn)
componentName='public-endpoints'
as | parent |
}}
{{component parent.intent
model=model.service
}}
{{/accordion-list-item}}
{{#if (not service.isBalancer)}}
{{#accordion-list-item
title=(t 'servicePage.logTab.title')
detail=(t 'servicePage.logTab.detail')
status=(t 'pagination.event' pages=1 count=(or model.logs.length 0))
statusClass=(if model.logs.arrangedContent.length 'bg-success' 'text-muted')
expandAll=al.expandAll
expand=(action expandFn)
}}
{{service-log logs=model.logs.arrangedContent}}
{{/accordion-list-item}}
{{container/form-scheduling
initialHostId=activeLaunchConfig.requestedHostId
initialLabels=activeLaunchConfig.labels
isGlobal=model.service.isGlobalScale
allHosts=model.hosts
editing=false
expandAll=al.expandAll
expandFn=expandFn
classNames="accordion"
}}
{{/if}}
{{#if model.service.canHaveLinks}}
{{#accordion-list-item
title=(t 'servicePage.linksTab.header')
detail=(t 'servicePage.linksTab.detail')
status=(t 'servicePage.linksTab.status' count=service.consumedServicesWithNames.length)
status=(t 'pagination.links' pages=1 count=service.consumedServicesWithNames.length)
statusClass=(if service.consumedServicesWithNames.length 'bg-success' 'text-muted')
expandAll=al.expandAll
expand=(action expandFn)
@ -146,7 +163,7 @@
{{/accordion-list-item}}
{{/if}}
{{#if model.service.isReal}}
{{#if model.service.canUpgrade}}
{{container/form-upgrade
service=model.service
editing=false
@ -157,17 +174,6 @@
}}
{{/if}}
{{#accordion-list-item
title=(t 'servicePage.logTab.title')
detail=(t 'servicePage.logTab.detail')
status=(t 'servicePage.logTab.status' count=(or model.logs.arrangedContent.length 0))
statusClass=(if model.logs.arrangedContent.length 'bg-success' 'text-muted')
expandAll=al.expandAll
expand=(action expandFn)
}}
{{service-log logs=model.logs.arrangedContent}}
{{/accordion-list-item}}
{{#if service.hasSidekicks}}
<hr/>
<div class="header has-tabs mt-20">
@ -255,7 +261,7 @@
{{/if}}
{{#if (not service.isBalancer)}}
{{#if service.canHaveEnvironment}}
{{form-env-var
model=activeLaunchConfig.displayEnvironmentVars
expandAll=al.expandAll
@ -263,108 +269,55 @@
}}
{{/if}}
{{form-healthcheck
healthCheck=activeLaunchConfig
editing=false
expandAll=al.expandAll
expandFn=expandFn
classNames="accordion"
}}
{{#if (not-eq activeLaunchConfig.type 'secondaryLaunchConfig')}}
{{#if service.canHaveHealthCheck}}
{{form-healthcheck
healthCheck=activeLaunchConfig
editing=false
expandAll=al.expandAll
expandFn=expandFn
classNames="accordion"
}}
{{/if}}
{{labels-section
model=activeLaunchConfig
tagName=''
expandAll=al.expandAll
expandFn=expandFn
}}
{{container/form-networking
editing=false
instance=model.service
initialLabels=activeLaunchConfig.labels
allHosts=model.hosts
expandAll=al.expandAll
expandFn=expandFn
}}
{{#if (not-eq activeLaunchConfig.type 'secondaryLaunchConfig')}}
{{#if (and service.hasPorts (not service.isBalancer))}}
{{#accordion-list-item
title=(t 'servicePage.portsTab.title')
detail=(t 'servicePage.portsTab.detail')
status=(t 'servicePage.portsTab.status' count=service.endpointsByPort.length)
statusClass=(if service.endpointsByPort.length 'bg-success' 'text-muted')
expandAll=al.expandAll
expand=(action expandFn)
componentName='sortable-table'
as | parent |
}}
{{#if service.isActive}}
{{#if service.publicEndpoints}}
{{#component parent.intent
classNames="grid sortable-table"
body=service.publicEndpoints
searchText=searchText
sortBy=portSortBy
bulkActions=false
rowActions=false
stickyHeader=false
pagingLabel="pagination.port"
isVisible=parent.expanded
headers=portHeaders as |sortable kind port dt|
}}
{{#if (eq kind "row")}}
<td data-title="{{dt.ipAddress}}">
{{#if (eq "0.0.0.0" port.ipAddress)}}
<span class="text-muted">{{t 'generic.all'}}</span>
{{else}}
{{port.ipAddress}}
{{/if}}
</td>
<td data-title="{{dt.port}}">
{{#if port.port}}
{{port.port}}
{{else}}
<span class="text-muted">{{t 'generic.none'}}</span>
{{/if}}
</td>
{{else if (eq kind "nomatch")}}
<tr><td colspan="{{sortable.fullColspan}}" class="text-center text-muted pt-20 pb-20">{{t 'containerPage.portsTab.table.noMatch'}}</td></tr>
{{else if (eq kind "norows")}}
<tr><td colspan="{{sortable.fullColspan}}" class="text-center text-muted pt-20 pb-20">{{t 'containerPage.portsTab.table.noData'}}</td></tr>
{{/if}}
{{/component}}
{{/if}}
{{else}}
<div class="text-center text-muted">{{t 'servicePage.portsTab.notActive'}}</div>
{{/if}}
{{/accordion-list-item}}
{{/if}}
{{#if service.canHaveLabels}}
{{labels-section
model=activeLaunchConfig
tagName=''
expandAll=al.expandAll
expandFn=expandFn
}}
{{/if}}
{{container/form-security
instance=activeLaunchConfig
editing=false
expandAll=al.expandAll
expandFn=expandFn
}}
{{#if service.canChangeNetworking}}
{{container/form-networking
editing=false
instance=model.service
initialLabels=activeLaunchConfig.labels
expandAll=al.expandAll
expandFn=expandFn
}}
{{/if}}
{{container/form-secrets
instance=activeLaunchConfig
editing=false
expandAll=al.expandAll
expandFn=expandFn
classNames="accordion"
}}
{{#if service.canChangeSecurity}}
{{container/form-security
instance=activeLaunchConfig
editing=false
expandAll=al.expandAll
expandFn=expandFn
}}
{{/if}}
{{#if service.lbConfig}}
{{#if service.canHaveSecrets}}
{{container/form-secrets
instance=activeLaunchConfig
editing=false
expandAll=al.expandAll
expandFn=expandFn
classNames="accordion"
}}
{{/if}}
{{#if service.isBalancer}}
{{form-stickiness
initialLabels=activeLaunchConfig.labels
service=model.service
@ -372,7 +325,6 @@
expandAll=al.expandAll
expandFn=expandFn
}}
{{/if}}
{{/accordion-list}}

View File

@ -89,12 +89,6 @@ export default Ember.Controller.extend({
searchField: 'displayName',
translationKey: 'generic.name',
},
{
name: 'endpoints',
sort: null,
searchField: 'endpointPorts',
translationKey: 'stacksPage.table.endpoints',
},
{
name: 'image',
sort: ['image','displayName'],
@ -102,13 +96,11 @@ export default Ember.Controller.extend({
translationKey: 'generic.image',
},
{
name: 'instanceState',
sort: ['instanceCountSort:desc','displayName'],
name: 'scale',
sort: ['scale:desc','isGlobalScale:desc','displayName'],
searchField: null,
width: 140,
icon: 'icon icon-lg icon-container',
dtTranslationKey: 'stacksPage.table.instanceState',
translationKey: 'stacksPage.table.instanceStateWithIcon',
width: 100,
translationKey: 'stacksPage.table.scale',
},
],

View File

@ -109,10 +109,6 @@
background-image: url('images/providers/rancherdigitalocean.svg');
}
@mixin ubiquity {
background-image: url('images/providers/ubiquity.svg');
}
@mixin vmwarevsphere {
background-image: url('images/providers/vmwarevsphere.png');
}

View File

@ -18,7 +18,7 @@ $accordion-header-border: darken($bg-default, 5) !default;
@extend .clearfix;
background: $accordion-header;
border: solid $accordion-header-border thin;
padding: 10px;
padding: 5px;
display: table;
vertical-align: middle;
width: 100%;
@ -32,7 +32,17 @@ $accordion-header-border: darken($bg-default, 5) !default;
}
.expand {
width: 40px;
width: 30px;
text-align: center;
I {
margin: 0;
padding: 0;
}
}
.help-block {
margin: 0;
}
.badge-state {

View File

@ -213,7 +213,6 @@ $lines-to-show: 4;
&.packet { @include packet; }
&.rackspace { @include rackspace; }
&.rancherdo { @include rancherdo;}
&.ubiquity { @include ubiquity; }
&.vmwarevsphere { @include vmwarevsphere; }
&.newtemplate { @include newtemplate; }
}

View File

@ -97,10 +97,6 @@
@include rackspace;
}
&.ubiquity {
@include ubiquity;
}
&.vmwarevsphere {
@include vmwarevsphere;
}

View File

@ -45,79 +45,17 @@
}
.machine-driver {
&.amazonec2 {
@include amazonec2;
}
&.azure {
@include azure;
}
&.digitalocean {
@include digitalocean;
}
&.exoscale {
@include exoscale;
}
&.openstack {
@include openstack;
}
&.packet {
@include packet;
}
&.rackspace {
@include rackspace;
}
&.ubiquity {
@include ubiquity;
}
&.vmwarevsphere {
@include vmwarevsphere;
}
&.other {
@include other;
}
&.custom {
@include custom;
}
&.aliyunecs {
@include aliyunecs;
}
}
.c3 svg {
font: 12px "Lato";
}
#memoryGraph,
#cpuGraph,
#networkGraph,
#storageGraph {
.c3-axis .tick {
fill: #9da0ae;
// text-shadow: 1px 1px 0px rgba(255,255,255,.5), -1px 1px 0px rgba(255,255,255,.5), 1px -1px 0px rgba(255,255,255,.5), -1px -1px 0px rgba(255,255,255,.5);
line {
display: none;
}
}
.c3-axis-x {
display: none;
}
.c3-axis .domain {
stroke: $light-grey;
}
&.amazonec2 { @include amazonec2; }
&.azure { @include azure; }
&.digitalocean { @include digitalocean; }
&.exoscale { @include exoscale; }
&.openstack { @include openstack; }
&.packet { @include packet; }
&.rackspace { @include rackspace; }
&.vmwarevsphere { @include vmwarevsphere; }
&.other { @include other; }
&.custom { @include custom; }
&.aliyunecs { @include aliyunecs; }
}
.api-field LABEL {

View File

@ -1 +0,0 @@
<button type="button" class="btn bg-default btn-xs"><i class="icon icon-vertical-ellipsis"></i></button>

View File

@ -1,6 +0,0 @@
<div class="text-center text-muted" style="margin: 20px 0">
{{t 'servicePartial.noContainers.label'}}
{{#if isInactive}}
<a href="#" class="hand" {{action "activate" target=model}}>{{t 'servicePartial.noContainers.inactive.start'}}</a>
{{/if}}
</div>

View File

@ -1,3 +0,0 @@
<div class="tooltip-content-inner">
<div class="force-wrap">{{model.displayName}}</div>
</div>

View File

@ -1 +0,0 @@
{{model.cpuTooltip}}

View File

@ -1,9 +0,0 @@
<div class="tooltip-content-inner tooltip-dot">
{{action-menu model=model showPrimary=false inTooltip=true class="pull-right tooltip-more-actions"}}
<div class="display-name">{{displayName}}</div>
<div class="bottom-row">
<span class="pull-left">{{model.state}}</span>
<span class="pull-right pr-20">{{format-date model.created}}</span>
</div>
</div>

View File

@ -1 +0,0 @@
{{model.displayName}}

View File

@ -189,7 +189,6 @@ var C = {
OPENSTACK: 'openstack',
PACKET: 'packet',
RACKSPACE: 'rackspace',
UBIQUITY: 'ubiquity',
VMWAREVSPHERE: 'vmwarevsphere',
OTHER: 'other',
CUSTOM: 'custom',

View File

@ -1,6 +1,29 @@
import Ember from 'ember';
import Util from 'ui/utils/util';
export const headers = [
{
name: 'serviceName',
sort: ['instance.service.displayName:desc', 'instanceId:desc'],
translationKey: 'volumesPage.mounts.table.instance',
},
{
name: 'instanceName',
sort: ['instanceName:desc', 'instanceId:desc'],
translationKey: 'volumesPage.mounts.table.instance',
},
{
name: 'path',
sort: ['path'],
translationKey: 'volumesPage.mounts.table.path',
},
{
name: 'permission',
sort: ['permission'],
translationKey: 'volumesPage.mounts.table.permission',
},
];
export default Ember.Controller.extend({
queryParams: ['type'],
stack: Ember.computed.alias('model.stack'),
@ -24,37 +47,17 @@ export default Ember.Controller.extend({
}
}),
headers: [
{
name: 'instanceName',
sort: ['instanceName: desc', 'instanceId: desc'],
translationKey: 'volumesPage.mounts.table.instance',
},
{
name: 'path',
sort: ['path'],
translationKey: 'volumesPage.mounts.table.path',
},
{
name: 'permission',
sort: ['permission'],
translationKey: 'volumesPage.mounts.table.permission',
},
{
name: 'volumeName',
translationKey: 'volumesPage.mounts.table.volume',
sort: ['volumeName: desc', 'volumeId: desc'],
},
],
headers,
optsHeaders: [
{
name: 'key',
sort: ['key: desc'],
sort: ['key:desc'],
translationKey: 'volumesPage.driverOptions.labels.key',
},
{
name: 'value',
sort: ['value: desc'],
sort: ['value:desc'],
translationKey: 'volumesPage.driverOptions.labels.value',
},
],

View File

@ -76,8 +76,9 @@
{{#component parent.intent
classNames="grid fixed mb-0 sortable-table"
bulkActions=false
rowActions=false
pagingLabel="pagination.mounts"
fullRows=true
rowActions=false
search=true
sortBy=sortBy
stickyHeader=false
@ -129,4 +130,4 @@
{{/component}}
{{/accordion-list-item}}
{{/accordion-list}}
</section>
</section>

View File

@ -2,9 +2,7 @@
"name": "ui",
"dependencies": {
"async": "2.1.2",
"c3": "~0.4.10",
"commonmark": "~0.22.1",
"dagre": "~0.7.1",
"ember-qunit-notifications": "0.1.0",
"ember-resolver": "~0.1.20",
"identicon.js": "identicon#*",

View File

@ -79,20 +79,16 @@ module.exports = function(defaults) {
app.import('bower_components/jgrowl/jquery.jgrowl.js');
app.import('bower_components/jgrowl/jquery.jgrowl.css');
app.import('bower_components/d3/d3.js');
app.import('bower_components/c3/c3.js');
app.import('bower_components/c3/c3.css');
app.import('bower_components/prism/prism.js');
app.import('bower_components/prism/components/prism-yaml.js');
app.import('bower_components/prism/components/prism-bash.js');
app.import('bower_components/lodash/lodash.js');
app.import('bower_components/graphlib/dist/graphlib.core.js');
app.import('bower_components/dagre/dist/dagre.core.js');
app.import('bower_components/async/dist/async.js');
app.import('bower_components/position-calculator/dist/position-calculator.js');
app.import('vendor/aws-sdk-ec2.js');
app.import('bower_components/identicon.js/pnglib.js');
app.import('bower_components/identicon.js/identicon.js');
app.import('vendor/dagre-d3/dagre-d3.core.js');
app.import('vendor/novnc.js');
app.import('bower_components/commonmark/dist/commonmark.js');
app.import('bower_components/momentjs/moment.js');

View File

@ -24,7 +24,7 @@
"ansi_up": "^1.3.0",
"broccoli-asset-rev": "^2.4.5",
"dotenv": "^4.0.0",
"ember-api-store": "2.2.1",
"ember-api-store": "2.2.2",
"ember-browserify": "^1.0.1",
"ember-cli": "^2.12.1",
"ember-cli-app-version": "^2.0.0",

View File

@ -497,8 +497,8 @@ editDns:
placeholder: e.g. myapp
description:
placeholder: e.g. Current version of MyApp
selectorContainer:
label: Container Selector
selector:
label: Container Label Selector
placeholder: e.g. mylabel=somevalue
mode:
label: "Resolves To"
@ -856,8 +856,14 @@ servicePage:
scale: 'Scale:'
image: 'Image:'
external:
externalIp: External IPs
externalIp: |
{count, plural,
=1 {External IP:}
other {External IPs:}
}
externalHostname: 'External Hostname:'
selector:
label: 'Selector:'
containersTab:
title: 'Containers'
detail: 'The containers running in this service.'
@ -865,12 +871,6 @@ servicePage:
header: Links
detail: 'These properties show the links between containers in this service.'
noData: This Service has no links
status: |
{count, plural,
=0 {No links}
=1 {# link}
other {# links}
}
certsTab:
title: Certificates
detail: 'Certificates used for TLS-termination of requests.'
@ -892,22 +892,10 @@ servicePage:
portsTab:
title: Ports
detail: 'Mappings of container listening ports to host ports on public IP addresses.'
status: |
{count, plural,
=0 {No Ports}
=1 {# port}
other {# ports}
}
notActive: Ports are only available while the service is Active.
logTab:
title: Service Log
detail: 'Recent orchestration events that have occurred for this service'
status: |
{count, plural,
=0 {No logs}
=1 {# log}
other {# logs}
}
type:
service: Service
selectorservice: Selector
@ -1003,16 +991,6 @@ newStack:
on: Automatically start them
off: Leave them stopped
storagePoolsPage:
header: Storage Drivers
index:
noData: No storage drivers
newVolume:
header: Add Volume
form:
driverOptions: Driver Options
addActionLabel: Add Option
userPreferencesPage:
header: Preferences
theme:
@ -1636,10 +1614,12 @@ formContainerLinks:
detail: Define relationships between this and other containers.
addActionLabel: Add Link
name:
label: Destination Container
label: Target Container
alias:
label: As Name
placeholder: e.g. database
noData: There are no container links
noMatch: No links match the current search
formCount:
label: Count
@ -1714,7 +1694,7 @@ formEnvVar:
formHealthCheck:
title: Health Check
detail: Periodically make a request to the container to see if it is responding correctly. An unhealthy container will be excluded from Load Balancers. Services can automatically replace unhealthy containers with a new one.
detail: Periodically make a request to the container to see if it is responding correctly. Unhealthy containers are excluded from Load Balancers and Service Discovery.
detailDns: A health check allows {appName} to know if the external resource is healty or not. An unhealthy target will be exlcluded from Load Balancers.
checkType:
none: None
@ -1755,7 +1735,7 @@ formHealthCheck:
strategy:
label: When Unhealthy
none: Take no action
recreate: Re-create
recreate: Delete container and schedule a replacement
formKeyValue:
addAction: Add Pair
@ -3269,21 +3249,6 @@ stackRow:
label: "Stack: {name}"
standalone: Standalone
storagePoolSection:
readOnly: "(read-only)"
hosts:
header: Hosts
none: No Hosts
volumes:
header: Volumes
add: Add Volume
none: No Volumes
models:
table:
header:
volumeName: 'Volume Name'
mounts: 'Mounts (Container: Path)'
svgServiceContainer:
sidekicks: Sidekicks