mirror of https://github.com/rancher/ui.git
Merge pull request #2282 from westlywright/progress-bar
Alert Users of Remaining Project Resource Quotas
This commit is contained in:
commit
59ce6f88a3
|
|
@ -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")
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -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))}}
|
||||
|
||||
{{else}}
|
||||
{{check-box nodeId=ns.id}}
|
||||
{{/if}}
|
||||
|
||||
</td>
|
||||
</td>
|
||||
<td>
|
||||
{{badge-state model=ns}}
|
||||
</td>
|
||||
|
|
|
|||
|
|
@ -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}}
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
}),
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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}}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue