Merge pull request #2282 from westlywright/progress-bar

Alert Users of Remaining Project Resource Quotas
This commit is contained in:
Westly Wright 2018-09-17 16:58:28 -07:00 committed by GitHub
commit 59ce6f88a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 134 additions and 38 deletions

View File

@ -39,6 +39,8 @@
editing=(or editing isNew)
expanded=expanded
limit=primaryResource.resourceQuota.limit
projectLimit=primaryResource.project.resourceQuota.limit
usedLimit=primaryResource.project.resourceQuota.usedLimit
nsDefaultQuota=primaryResource.project.namespaceDefaultResourceQuota.limit
changed=(action "updateNsQuota")
}}

View File

@ -1,6 +1,13 @@
<td class="pr-10">
{{resource-quota-select editing=false quota=quota}}
</td>
<td class="pr-10">
{{progress-bar-multi
values=quota.currentProjectUse
tooltipValues=quota.totalLimits
max=quota.max
}}
</td>
<td class="pr-10">
{{input-resource-quota editing=editing quota=quota key='value'}}
</td>

View File

@ -4,11 +4,15 @@ import Component from '@ember/component';
import { convertToMillis } from 'shared/utils/util';
import { parseSi } from 'shared/utils/parse-unit';
import layout from './template';
import { inject as service } from '@ember/service';
export default Component.extend({
layout,
intl: service(),
layout,
limit: null,
usedLimit: null,
projectlimit: null,
projectQuota: null,
nsDefaultQuota: null,
@ -51,21 +55,49 @@ export default Component.extend({
});
this.sendAction('changed', Object.keys(out).length ? out : null);
this.updateLimits();
}),
updateLimits() {
( get(this, 'quotaArray') || [] ).forEach((quota) => {
if ( quota.key ) {
const value = parseInt(get(quota, 'value'), 10) || 0;
const usedValue = get(quota, 'currentProjectUse.firstObject.value');
const newUse = get(quota, 'currentProjectUse.lastObject');
const totalLimits = get(quota, 'totalLimits.firstObject');
const myNewUse = usedValue + value;
const translation = get(this, 'intl').t('formResourceQuota.table.resources.tooltip', {
usedValue,
newUse: myNewUse,
remaining: ( get(quota, 'max') - ( myNewUse ) ),
});
set(newUse, 'value', value);
set(totalLimits, 'value', translation);
}
});
},
initQuotaArray() {
let limit = get(this, 'limit');
const nsDefaultQuota = get(this, 'nsDefaultQuota');
const array = [];
const limit = get(this, 'limit');
const nsDefaultQuota = get(this, 'nsDefaultQuota');
const array = [];
const used = get(this, 'usedLimit');
const currentProjectLimit = get(this, 'projectLimit')
const intl = get(this, 'intl');
Object.keys(nsDefaultQuota).forEach((key) => {
if ( key !== 'type' && typeof nsDefaultQuota[key] === 'string') {
let value;
let value, currentProjectUse, totalLimits;
let usedValue = '';
let max = '';
let newUse = null;
if ( limit && !limit[key] ) {
array.push({
key,
value: '',
value: '',
currentProjectUse: [],
});
return;
@ -73,16 +105,60 @@ export default Component.extend({
value = limit && limit[key] ? limit[key] : nsDefaultQuota[key];
if ( key === 'limitsCpu' || key === 'requestsCpu' ) {
value = convertToMillis(value);
} else if ( key === 'limitsMemory' || key === 'requestsMemory' ) {
value = parseSi(value, 1024) / 1048576;
} else if ( key === 'requestsStorage' ) {
value = parseSi(value) / (1024 ** 3);
switch (key) {
case 'limitsCpu':
case 'requestsCpu':
value = convertToMillis(value);
usedValue = convertToMillis(get(used, key));
max = convertToMillis(get(currentProjectLimit, key));
break;
case 'limitsMemory':
case 'requestsMemory':
value = parseSi(value, 1024) / 1048576;
usedValue = parseSi(get(used, key), 1024) / 1048576;
max = parseSi(get(currentProjectLimit, key), 1024) / 1048576;
break;
case 'requestsStorage':
value = parseSi(value) / (1024 ** 3);
usedValue = parseSi(get(used, key)) / (1024 ** 3);
max = parseSi(get(currentProjectLimit, key)) / (1024 ** 3);
break;
default:
break;
}
newUse = usedValue + value;
currentProjectUse = [
{
// current use
color: 'bg-error',
label: key,
value: usedValue,
},
{
// only need the new value here because progress-multi-bar adds this to the previous
color: 'bg-warning',
label: key,
value,
}
];
totalLimits = [{
label: get(this, 'intl').t(`formResourceQuota.resources.${ key }`),
value: intl.t('formResourceQuota.table.resources.tooltip', {
usedValue,
newUse,
remaining: ( max - newUse ),
})
}];
array.push({
currentProjectUse,
key,
max,
totalLimits,
value,
});
}

View File

@ -3,12 +3,13 @@
<thead>
<tr>
<th>{{t 'formResourceQuota.table.type.label'}}</th>
<th width="200px">{{t 'formResourceQuota.table.resources.label'}}</th>
<th>{{t 'formResourceQuota.table.value.label'}}</th>
</tr>
</thead>
<tbody>
{{#each quotaArray as |quota|}}
{{namespace-quota-row
{{namespace-quota-row
quota=quota
editing=editing
}}

View File

@ -15,14 +15,13 @@
}}
{{#if (eq kind "row")}}
<tr class="main-row">
<td valign="middle" class="row-check" style="padding-top: 2px;">
{{#if projectsWithoutNamespace.length}}
<td valign="middle" class="row-check" style="padding-top: 2px;">
{{#if (and projectsWithoutNamespace.length (not model.length))}}
&nbsp;
{{else}}
{{check-box nodeId=ns.id}}
{{/if}}
</td>
</td>
<td>
{{badge-state model=ns}}
</td>

View File

@ -32,7 +32,6 @@
{{#copy-inline clipboardText=model.displayIp}}{{format-ip model.displayIp}}{{/copy-inline}} /
{{/if}}
{{#if (and showNode model.node)}}
{{log model.node}}
<a href="{{href-to "node" scope.currentCluster.id model.node.id}}">{{model.node.displayName}}</a> /
{{/if}}
{{t 'generic.createdDate' date=(date-from-now model.created) htmlSafe=true}}

View File

@ -1,4 +1,4 @@
import { defineProperty, computed, get } from '@ember/object';
import { defineProperty, computed, get, observer } from '@ember/object';
import Component from '@ember/component';
import layout from './template';
@ -28,19 +28,19 @@ export default Component.extend({
init() {
this._super(...arguments);
let colorKey = this.get('colorKey');
let labelKey = this.get('labelKey');
let valueKey = this.get('valueKey');
let colorKey = get(this, 'colorKey');
let labelKey = get(this, 'labelKey');
let valueKey = get(this, 'valueKey');
let valueDep = `values.@each.{${ colorKey },${ labelKey },${ valueKey }}`;
defineProperty(this, 'pieces', computed('min', 'max', valueDep, () => {
let min = this.get('min');
let max = this.get('max');
let min = get(this, 'min');
let max = get(this, 'max');
var out = [];
(this.get('values') || []).forEach((obj) => {
(get(this, 'values') || []).forEach((obj) => {
out.push({
color: get(obj, colorKey),
label: get(obj, labelKey),
@ -56,7 +56,7 @@ export default Component.extend({
}
let sum = 0;
let minPercent = this.get('minPercent');
let minPercent = get(this, 'minPercent');
out.forEach((obj) => {
let per = Math.max(minPercent, toPercent(obj.value, min, max));
@ -79,12 +79,12 @@ export default Component.extend({
valueDep = `tooltipValues.@each.{${ labelKey },${ valueKey }}`;
defineProperty(this, 'tooltipContent', computed(valueDep, () => {
let labelKey = this.get('labelKey');
let valueKey = this.get('valueKey');
let labelKey = get(this, 'labelKey');
let valueKey = get(this, 'valueKey');
var out = [];
(this.get('tooltipValues') || []).forEach((obj) => {
(get(this, 'tooltipValues') || []).forEach((obj) => {
out.push(`${ get(obj, labelKey) }: ${ get(obj, valueKey) }`);
});
@ -95,8 +95,9 @@ export default Component.extend({
didInsertElement() {
this.zIndexDidChange();
},
zIndexDidChange: function() {
this.$().css('zIndex', this.get('zIndex') || 'inherit');
}.observes('zIndex'),
zIndexDidChange: observer('zIndex', function() {
this.$().css('zIndex', get(this, 'zIndex') || 'inherit');
}),
});

View File

@ -1,4 +1,12 @@
{{#tooltip-element type="tooltip-basic" model=tooltipContent tooltipTemplate='tooltip-static' aria-describedby="tooltip-base" tooltipFor="progress-bar" inlineBlock=false}}
{{#tooltip-element
type="tooltip-basic"
model=tooltipContent
tooltipTemplate='tooltip-static'
aria-describedby="tooltip-base"
tooltipFor="progress-bar"
inlineBlock=true
classNames="full-width"
}}
<div class="progress">
{{~#each pieces as |obj|~}}
<div class="progress-bar {{obj.color}}" style={{obj.css}}></div>

View File

@ -40,11 +40,11 @@
<td data-title="{{dt.scale}}" class="text-center">
{{progress-bar-multi
classNames="mt-5"
labelKey="state"
valueKey="count"
values=model.podStates.byColor
tooltipValues=model.podStates.byName
classNames="mt-5"
labelKey="state"
valueKey="count"
values=model.podStates.byColor
tooltipValues=model.podStates.byName
}}
<small class="text-muted">
{{model.displayScale}}

View File

@ -3379,6 +3379,9 @@ formResourceQuota:
placeholder: e.g. 10
milliCpuPlaceholder: e.g. 500
memoryPlaceholder: e.g. 1Gi
resources:
label: Project Resource Availability
tooltip: "Reserved - { usedValue }, This Namespace - { newUse }, Available - { remaining }"
projectLimit:
label: Project Limit
placeholder: e.g. 50