Commit 5f225a35 authored by Timothy Noah's avatar Timothy Noah Committed by Dhiraj Bodicherla

Update usage quotas table tooltips

This MR updates the tooltips in usage quotas
table rows. The tooltip will now have more info
about why a project is locked or in warning state
parent 009b3788
......@@ -166,7 +166,10 @@ export default {
/>
</div>
</div>
<projects-table :projects="namespaceProjects" />
<projects-table
:projects="namespaceProjects"
:additional-purchased-storage-size="namespace.additionalPurchasedStorageSize || 0"
/>
<temporary-storage-increase-modal
v-if="isStorageIncreaseModalVisible"
:limit="formattedNamespaceLimit"
......
......@@ -6,13 +6,27 @@
* lifted this component could replace and be used mainstream.
*/
import { GlLink, GlIcon, GlTooltipDirective } from '@gitlab/ui';
import { s__ } from '~/locale';
import { s__, sprintf } from '~/locale';
import ProjectAvatar from '~/vue_shared/components/project_avatar/default.vue';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { formatUsageSize, usageRatioToThresholdLevel } from '../utils';
import { ALERT_THRESHOLD, ERROR_THRESHOLD, WARNING_THRESHOLD } from '../constants';
export default {
i18n: {
warningWithNoPurchasedStorageText: s__(
'UsageQuota|This project is near the free %{actualRepositorySizeLimit} limit and at risk of being locked.',
),
lockedWithNoPurchasedStorageText: s__(
'UsageQuota|This project is locked because it is using %{actualRepositorySizeLimit} of free storage and there is no purchased storage available.',
),
warningWithPurchasedStorageText: s__(
'UsageQuota|This project is at risk of being locked because purchased storage is running low.',
),
lockedWithPurchasedStorageText: s__(
'UsageQuota|This project is locked because it used %{actualRepositorySizeLimit} of free storage and all the purchased storage.',
),
},
components: {
GlIcon,
GlLink,
......@@ -26,6 +40,10 @@ export default {
required: true,
type: Object,
},
additionalPurchasedStorageSize: {
type: Number,
required: true,
},
},
computed: {
projectAvatar() {
......@@ -40,6 +58,9 @@ export default {
name() {
return this.project.nameWithNamespace;
},
hasPurchasedStorage() {
return this.additionalPurchasedStorageSize > 0;
},
storageSize() {
return formatUsageSize(this.project.totalCalculatedUsedStorage);
},
......@@ -53,21 +74,32 @@ export default {
return usageRatioToThresholdLevel(this.excessStorageRatio);
},
status() {
const i18nTextOpts = {
actualRepositorySizeLimit: formatUsageSize(this.project.actualRepositorySizeLimit),
};
if (this.thresholdLevel === ERROR_THRESHOLD) {
const tooltipText = this.hasPurchasedStorage
? this.$options.i18n.lockedWithPurchasedStorageText
: this.$options.i18n.lockedWithNoPurchasedStorageText;
return {
bgColor: { 'gl-bg-red-50': true },
iconClass: { 'gl-text-red-500': true },
linkClass: 'gl-text-red-500!',
tooltipText: s__('UsageQuota|This project is locked.'),
tooltipText: sprintf(tooltipText, i18nTextOpts),
};
} else if (
this.thresholdLevel === WARNING_THRESHOLD ||
this.thresholdLevel === ALERT_THRESHOLD
) {
const tooltipText = this.hasPurchasedStorage
? this.$options.i18n.warningWithPurchasedStorageText
: this.$options.i18n.warningWithNoPurchasedStorageText;
return {
bgColor: { 'gl-bg-orange-50': true },
iconClass: 'gl-text-orange-500',
tooltipText: s__('UsageQuota|This project is at risk of being locked.'),
tooltipText: sprintf(tooltipText, i18nTextOpts),
};
}
......
......@@ -14,6 +14,10 @@ export default {
type: Array,
required: true,
},
additionalPurchasedStorageSize: {
type: Number,
required: true,
},
},
computed: {
isAdditionalStorageFlagEnabled() {
......@@ -61,6 +65,7 @@ export default {
v-for="project in projects"
:key="project.id"
:project="project"
:additional-purchased-storage-size="additionalPurchasedStorageSize"
/>
</div>
</template>
......@@ -12,6 +12,7 @@ const createComponent = (propsData = {}) => {
wrapper = shallowMount(ProjectWithExcessStorage, {
propsData: {
project: projects[0],
additionalPurchasedStorageSize: 0,
...propsData,
},
directives: {
......@@ -34,6 +35,7 @@ describe('Storage Counter project component', () => {
wrapper.destroy();
});
describe('without extra storage purchased', () => {
it('renders project avatar', () => {
expect(wrapper.find(ProjectAvatar).exists()).toBe(true);
});
......@@ -72,7 +74,9 @@ describe('Storage Counter project component', () => {
});
it('with tooltip', () => {
expect(getWarningIconTooltipText().title).toBe('This project is locked.');
expect(getWarningIconTooltipText().title).toBe(
'This project is locked because it is using 97.7KiB of free storage and there is no purchased storage available.',
);
});
});
......@@ -94,7 +98,50 @@ describe('Storage Counter project component', () => {
});
it('with tooltip', () => {
expect(getWarningIconTooltipText().title).toBe('This project is at risk of being locked.');
expect(getWarningIconTooltipText().title).toBe(
'This project is near the free 97.7KiB limit and at risk of being locked.',
);
});
});
});
describe('with extra storage purchased', () => {
describe('if projects is in error state', () => {
beforeEach(() => {
createComponent({
project: projects[2],
additionalPurchasedStorageSize: 100000,
});
});
afterEach(() => {
wrapper.destroy();
});
it('renders purchased storage specific error tooltip ', () => {
expect(getWarningIconTooltipText().title).toBe(
'This project is locked because it used 97.7KiB of free storage and all the purchased storage.',
);
});
});
describe('if projects is in warning state', () => {
beforeEach(() => {
createComponent({
project: projects[1],
additionalPurchasedStorageSize: 100000,
});
});
afterEach(() => {
wrapper.destroy();
});
it('renders purchased storage specific warning tooltip ', () => {
expect(getWarningIconTooltipText().title).toBe(
'This project is at risk of being locked because purchased storage is running low.',
);
});
});
});
});
......@@ -14,6 +14,7 @@ const createComponent = ({ additionalRepoStorageByNamespace = false } = {}) => {
wrapper = shallowMount(ProjectsTable, {
propsData: {
projects,
additionalPurchasedStorageSize: 0,
},
stubs,
provide: {
......
......@@ -28714,10 +28714,16 @@ msgstr ""
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
msgid "UsageQuota|This project is at risk of being locked."
msgid "UsageQuota|This project is at risk of being locked because purchased storage is running low."
msgstr ""
msgid "UsageQuota|This project is locked."
msgid "UsageQuota|This project is locked because it is using %{actualRepositorySizeLimit} of free storage and there is no purchased storage available."
msgstr ""
msgid "UsageQuota|This project is locked because it used %{actualRepositorySizeLimit} of free storage and all the purchased storage."
msgstr ""
msgid "UsageQuota|This project is near the free %{actualRepositorySizeLimit} limit and at risk of being locked."
msgstr ""
msgid "UsageQuota|Total excess storage used"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment