diff --git a/app/components/banner-message/component.js b/app/components/banner-message/component.js new file mode 100644 index 000000000..40324c9e7 --- /dev/null +++ b/app/components/banner-message/component.js @@ -0,0 +1,16 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + classNames: ['banner'], + classNameBindings: ['color'], + + showIcon: function() { + let value = this.get('value'); + return value === null || value === undefined; + }.property('value'), + + color: 'bg-default', + icon: 'icon icon-info', + value: null, + message: '', +}); diff --git a/app/components/banner-message/template.hbs b/app/components/banner-message/template.hbs new file mode 100644 index 000000000..ad5f2e3b4 --- /dev/null +++ b/app/components/banner-message/template.hbs @@ -0,0 +1,10 @@ + + diff --git a/app/components/graph-area/component.js b/app/components/graph-area/component.js new file mode 100644 index 000000000..816808454 --- /dev/null +++ b/app/components/graph-area/component.js @@ -0,0 +1,184 @@ +import Ember from 'ember'; +import { + formatPercent, formatMib, formatKbps +} +from 'ui/utils/util'; + +const formatters = { + value: (value) => { + return value; + }, + percent: formatPercent, + mib: formatMib, + kbps: formatKbps +}; + +export default Ember.Component.extend({ + attributeBindings: ['cssSize:style', 'tooltip'], + tagName : 'span', + classNames : ['spark-line'], + + intl : Ember.inject.service(), + data : null, + width : null, + height : 20, + min : 0, + max : null, + interpolation : 'step-after', + formatter : 'value', + prefix : '', + type : null, + + svg : null, + line : null, + dot : null, + x : null, + y : null, + tooltipModel: null, + + hasData: function() { + if (this.get('data.length') > 0 && !this.get('svg')) { + this.create(); + } + }.observes('data.length'), + + cssSize: function() { + return new Ember.String.htmlSafe('width: ' + this.get('width') + 'px; height: ' + this.get('height') + 'px'); + }.property('width', 'height'), + + lastValue: function() { + var data = this.get('data'); + if (data && data.get('length')) { + return data.objectAt(data.get('length') - 1); + } + }.property('data.[]'), + + tooltip: function() { + let prefix = this.get('prefix'); + let prefixI18n = null; + let out = null; + + if (prefix) { + prefixI18n = this.get('intl').findTranslationByKey(prefix); + out = `${this.get('intl').formatMessage(prefixI18n)} ${formatters[this.get('formatter')](this.get('lastValue'))}`; + } else { + out = ` ${formatters[this.get('formatter')](this.get('lastValue'))}`; + } + + Ember.run.next(() => { + if ( this.isDestoyed || this.isDestroying ) { + return; + } + + this.set('tooltipModel', out); + }); + }.property('prefix', 'lastValue', 'formatter'), + + create() { + var svg = d3.select(this.$()[0]) + .append('svg:svg') + .attr('width', '100%') + .attr('height', '100%'); + + var gradient = svg.append('svg:defs') + .append("svg:linearGradient") + .attr('id', `${this.get('type')}-gradient`) + .attr('x1', '0%') + .attr('y1', '0%') + .attr('x2', '100%') + .attr('y2', '100%') + .attr('spreadMethod', 'pad'); + + gradient.append('svg:stop') + .attr('offset', '0%') + .attr('stop-color', this.typePath()) + .attr('stop-opacity', '1'); + + gradient.append('svg:stop') + .attr('offset', '100%') + .attr('stop-color', this.typePath()) + .attr('stop-opacity', '.1'); + + this.set('svg', svg); + this.set('x', d3.scale.linear()); + this.set('y', d3.scale.linear()); + + var line = d3.svg.area() + .x((d, i) => { + return this.get('x')(i); + }) + .y0(this.get('height')) + .y1((d) => { + return this.get('y')(d); + }); + + this.set('line', line); + + this.updateLine(); + + svg.append('path') + .attr('class', `spark-path ${this.get('type')}-path`) + .attr('d', line(this.get('data'))); + + }, + + typePath: function() { + var out; + + switch (this.get('type')) { + case 'cpu': + out = '#2ecc71'; //$green + break; + case 'memory': + out = '#00558b'; //$primary-dark + break; + case 'network': + out = '#d35401'; //mix($warning, $error, 20%)Dark + break; + case 'storage': + out = '#3a6f81'; //$info + break; + default: + break; + } + + return out; + }, + + updateLine: function() { + var line = this.get('line'); + var interp = this.get('interpolation'); + + if (line) { + line.interpolate(interp); + } + + }.observes('interpolation'), + + update: function() { + var svg = this.get('svg'); + var data = (this.get('data') || []).slice(); + var x = this.get('x'); + var y = this.get('y'); + var line = this.get('line'); + var width = this.get('width'); + var height = this.get('height'); + + if (svg && data && x && y && line) { + x.domain([0, data.get('length') - 1]); + x.range([0, width - 1]); + + var min = this.get('min') === null ? d3.min(data) : this.get('min'); + var max = this.get('max') === null ? d3.max(data) : this.get('max'); + y.domain([min, max]); + y.range([height, 0]); + y.rangeRound([height, 0]); + + //console.log('update', data[data.length-2], data[data.length-1], x.domain(), x.range(), y.domain(), y.range()); + svg.selectAll('path') + .data([data]) + .style('fill', `url(${window.location.pathname}#${this.get('type')}-gradient)`) + .attr('d', line); + } + }.observes('data', 'data.[]'), +}); diff --git a/app/k8s-tab/template.hbs b/app/k8s-tab/template.hbs index 222e64abd..f34f3c63e 100644 --- a/app/k8s-tab/template.hbs +++ b/app/k8s-tab/template.hbs @@ -1,83 +1,47 @@ {{waiting-orchestration}}
-

Status

+
+

Status

+
-
-

{{#if etcd}}{{else}}{{/if}}

-

etcd

+
+ {{banner-message icon=(if etcd 'icon-success' 'icon-alert') color=(if etcd 'bg-success' 'bg-warning') message='Etcd'}}
-
-

{{#if kubelet}}{{else}}{{/if}}

-

Kubelet

+
+ {{banner-message icon=(if kubelet 'icon-success' 'icon-alert') color=(if kubelet 'bg-success' 'bg-warning') message='Kubelets'}}
-
-

{{#if controlPlane}}{{else}}{{/if}}

-

Control Plane

+
+ {{banner-message icon=(if controlPlane 'icon-success' 'icon-alert') color=(if controlPlane 'bg-success' 'bg-warning') message='Control Plane'}}
-
-

{{#if systemStacks}}{{else}}{{/if}}

-

System Services

+
+ {{banner-message icon=(if systemStacks 'icon-success' 'icon-alert') color=(if systemStacks 'bg-success' 'bg-warning') message='System Services'}}
-

Resources

-
-
-
-

{{model.workload.deploymentList.listMeta.totalItems}}

-

Deployments

+
+

Resources

+
+
+
+
+ {{banner-message value=model.workload.deploymentList.listMeta.totalItems color='bg-info' message='Deployments'}} + {{banner-message value=model.workload.replicaSetList.listMeta.totalItems color='bg-info' message='Replica Sets'}} + {{banner-message value=model.workload.replicationControllerList.listMeta.totalItems color='bg-info' message='Replication Controllers'}} + {{banner-message value=model.workload.podList.listMeta.totalItems color='bg-info' message='Pods'}}
-
-
-
-

{{model.workload.replicaSetList.listMeta.totalItems}}

-

Replica Sets

-
-
-
-
-

{{model.workload.podList.listMeta.totalItems}}

-

Pods

-
-
-
-
-
-
-

{{model.workload.daemonSetList.listMeta.totalItems}}

-

Daemon Sets

-
-
-
-
-

{{model.workload.replicationControllerList.listMeta.totalItems}}

-

RCs

-
-
-
-
-

{{model.workload.statefulSetList.listMeta.totalItems}}

-

Stateful Sets

-
-
-
-
-

{{model.workload.jobList.listMeta.totalItems}}

-

Job Lists

+ +
+ {{banner-message value=model.workload.daemonSetList.listMeta.totalItems color='bg-info' message='Daemon Sets'}} + {{banner-message value=model.workload.statefulSetList.listMeta.totalItems color='bg-info' message='Stateful Sets'}} + {{banner-message value=model.workload.jobList.listMeta.totalItems color='bg-info' message='Jobs'}}
-
- -
- -
-
- -
+
+ Launch Dashboard + +