diff --git a/app/authenticated/cluster/projects/new-ns/template.hbs b/app/authenticated/cluster/projects/new-ns/template.hbs index 47a92caf5..518384ae2 100644 --- a/app/authenticated/cluster/projects/new-ns/template.hbs +++ b/app/authenticated/cluster/projects/new-ns/template.hbs @@ -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") }} diff --git a/app/components/namespace-quota-row/template.hbs b/app/components/namespace-quota-row/template.hbs index b24728267..41232b6a2 100644 --- a/app/components/namespace-quota-row/template.hbs +++ b/app/components/namespace-quota-row/template.hbs @@ -1,6 +1,13 @@ {{resource-quota-select editing=false quota=quota}} + + {{progress-bar-multi + values=quota.currentProjectUse + tooltipValues=quota.totalLimits + max=quota.max + }} + {{input-resource-quota editing=editing quota=quota key='value'}} \ No newline at end of file diff --git a/app/components/namespace-resource-quota/component.js b/app/components/namespace-resource-quota/component.js index 01c8ecafd..64d55ad37 100644 --- a/app/components/namespace-resource-quota/component.js +++ b/app/components/namespace-resource-quota/component.js @@ -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, }); } diff --git a/app/components/namespace-resource-quota/template.hbs b/app/components/namespace-resource-quota/template.hbs index 76b1b65c1..bb324ae2a 100644 --- a/app/components/namespace-resource-quota/template.hbs +++ b/app/components/namespace-resource-quota/template.hbs @@ -3,12 +3,13 @@ {{t 'formResourceQuota.table.type.label'}} + {{t 'formResourceQuota.table.resources.label'}} {{t 'formResourceQuota.table.value.label'}} {{#each quotaArray as |quota|}} - {{namespace-quota-row + {{namespace-quota-row quota=quota editing=editing }} diff --git a/app/components/namespace-table/template.hbs b/app/components/namespace-table/template.hbs index 230606a6d..8b05127bc 100644 --- a/app/components/namespace-table/template.hbs +++ b/app/components/namespace-table/template.hbs @@ -15,14 +15,13 @@ }} {{#if (eq kind "row")}} - - {{#if projectsWithoutNamespace.length}} + + {{#if (and projectsWithoutNamespace.length (not model.length))}}   {{else}} {{check-box nodeId=ns.id}} {{/if}} - - + {{badge-state model=ns}} diff --git a/app/components/pod-row/template.hbs b/app/components/pod-row/template.hbs index 03b4c52e1..e1fe98cf2 100644 --- a/app/components/pod-row/template.hbs +++ b/app/components/pod-row/template.hbs @@ -32,7 +32,6 @@ {{#copy-inline clipboardText=model.displayIp}}{{format-ip model.displayIp}}{{/copy-inline}} / {{/if}} {{#if (and showNode model.node)}} - {{log model.node}} {{model.node.displayName}} / {{/if}} {{t 'generic.createdDate' date=(date-from-now model.created) htmlSafe=true}} diff --git a/app/components/progress-bar-multi/component.js b/app/components/progress-bar-multi/component.js index 07fe577db..7de6edf03 100644 --- a/app/components/progress-bar-multi/component.js +++ b/app/components/progress-bar-multi/component.js @@ -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'); + }), }); diff --git a/app/components/progress-bar-multi/template.hbs b/app/components/progress-bar-multi/template.hbs index 7897cd7bb..535e94c40 100644 --- a/app/components/progress-bar-multi/template.hbs +++ b/app/components/progress-bar-multi/template.hbs @@ -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" +}}
{{~#each pieces as |obj|~}}
diff --git a/app/components/workload-row/template.hbs b/app/components/workload-row/template.hbs index 969fbbeb3..945e94f17 100644 --- a/app/components/workload-row/template.hbs +++ b/app/components/workload-row/template.hbs @@ -40,11 +40,11 @@ {{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 }} {{model.displayScale}} diff --git a/translations/en-us.yaml b/translations/en-us.yaml index 8f261a763..5cff2d211 100644 --- a/translations/en-us.yaml +++ b/translations/en-us.yaml @@ -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