Commit 4ac46452 authored by Ragnar-H's avatar Ragnar-H Committed by Dhiraj Bodicherla

Add storage inline alert component

To inform the user of the status
of their additionally purchased
storage consumption.
parent 80ebc966
<script>
import { GlAlert } from '@gitlab/ui';
import { __ } from '~/locale';
import { numberToHumanSize } from '~/lib/utils/number_utils';
import { usageRatioToThresholdLevel } from '../usage_thresholds';
import { ALERT_THRESHOLD, ERROR_THRESHOLD, WARNING_THRESHOLD } from '../constants';
export default {
components: {
GlAlert,
},
props: {
containsLockedProjects: {
type: Boolean,
required: true,
},
repositorySizeExcessProjectCount: {
type: Number,
required: true,
},
totalRepositorySizeExcess: {
type: Number,
required: true,
},
totalRepositorySize: {
type: Number,
required: true,
},
additionalPurchasedStorageSize: {
type: Number,
required: true,
},
repositoryFreeSizeLimit: {
type: Number,
required: true,
},
},
computed: {
shouldShowAlert() {
return this.hasPurchasedStorage() || this.containsLockedProjects;
},
alertText() {
return this.hasPurchasedStorage()
? this.hasPurchasedStorageText()
: this.hasNotPurchasedStorageText();
},
alertTitle() {
if (!this.hasPurchasedStorage() && this.containsLockedProjects) {
return __('This namespace contains locked projects');
}
return `${this.excessStoragePercentageLeft}% of purchased storage is available`;
},
excessStorageRatio() {
return this.totalRepositorySizeExcess / this.additionalPurchasedStorageSize;
},
excessStoragePercentageUsed() {
return (this.excessStorageRatio * 100).toFixed(0);
},
excessStoragePercentageLeft() {
return Math.max(0, 100 - this.excessStoragePercentageUsed);
},
thresholdLevel() {
return usageRatioToThresholdLevel(this.excessStorageRatio);
},
thresholdLevelToAlertVariant() {
if (this.thresholdLevel === ERROR_THRESHOLD || this.thresholdLevel === ALERT_THRESHOLD) {
return 'danger';
} else if (this.thresholdLevel === WARNING_THRESHOLD) {
return 'warning';
}
return 'info';
},
projectsLockedText() {
if (this.repositorySizeExcessProjectCount === 0) {
return '';
} else if (this.repositorySizeExcessProjectCount === 1) {
return __(`${this.repositorySizeExcessProjectCount} project`);
}
return __(`${this.repositorySizeExcessProjectCount} projects`);
},
},
methods: {
hasPurchasedStorage() {
return this.additionalPurchasedStorageSize > 0;
},
formatSize(size) {
return numberToHumanSize(size);
},
hasPurchasedStorageText() {
if (this.thresholdLevel === ERROR_THRESHOLD) {
return __(
`You have consumed all of your additional storage, please purchase more to unlock your projects over the free ${this.formatSize(
this.repositoryFreeSizeLimit,
)} limit`,
);
} else if (
this.thresholdLevel === WARNING_THRESHOLD ||
this.thresholdLevel === ALERT_THRESHOLD
) {
__(
`Your purchased storage is running low. To avoid locked projects, please purchase more storage.`,
);
}
return __(
`When you purchase additional storage, we automatically unlock projects that were locked when you reached the ${this.formatSize(
this.repositoryFreeSizeLimit,
)} limit.`,
);
},
hasNotPurchasedStorageText() {
if (this.thresholdLevel === ERROR_THRESHOLD) {
return __(
`You have reached the free storage limit of ${this.formatSize(
this.repositoryFreeSizeLimit,
)} on ${this.projectsLockedText}. To unlock them, please purchase additional storage.`,
);
}
return '';
},
},
};
</script>
<template>
<gl-alert
v-if="shouldShowAlert"
class="gl-mt-5"
:variant="thresholdLevelToAlertVariant"
:dismissible="false"
:title="alertTitle"
>
{{ alertText }}
</gl-alert>
</template>
import { shallowMount } from '@vue/test-utils';
import StorageInlineAlert from 'ee/storage_counter/components/storage_inline_alert.vue';
import { GlAlert } from '@gitlab/ui';
const THIRTEEN_GB_IN_BYTES = 1.3e10;
const TEN_GB_IN_BYTES = 1e10;
const FIVE_GB_IN_BYTES = 5e9;
const THREE_GB_IN_BYTES = 3e9;
describe('StorageInlineAlert', () => {
let wrapper;
function mountComponent(props) {
wrapper = shallowMount(StorageInlineAlert, {
propsData: props,
});
}
const findAlert = () => wrapper.find(GlAlert);
describe('no excess storage and no purchase', () => {
beforeEach(() => {
mountComponent({
containsLockedProjects: false,
repositorySizeExcessProjectCount: 0,
totalRepositorySizeExcess: 0,
totalRepositorySize: FIVE_GB_IN_BYTES,
additionalPurchasedStorageSize: 0,
repositoryFreeSizeLimit: TEN_GB_IN_BYTES,
});
});
it('does not render an alert', () => {
expect(findAlert().exists()).toBe(false);
});
});
describe('excess storage and no purchase', () => {
beforeEach(() => {
mountComponent({
containsLockedProjects: true,
repositorySizeExcessProjectCount: 1,
totalRepositorySizeExcess: THREE_GB_IN_BYTES,
totalRepositorySize: THIRTEEN_GB_IN_BYTES,
additionalPurchasedStorageSize: 0,
repositoryFreeSizeLimit: TEN_GB_IN_BYTES,
});
});
it('renders danger variant alert', () => {
expect(findAlert().exists()).toBe(true);
expect(findAlert().props('variant')).toBe('danger');
});
it('renders human readable repositoryFreeLimit', () => {
// Note how we get a less good looking 9.31 GiB number
// Will be fixed in https://gitlab.com/gitlab-org/gitlab/-/issues/263284
expect(findAlert().text()).toBe(
'You have reached the free storage limit of 9.31 GiB on 1 project. To unlock them, please purchase additional storage.',
);
});
});
describe('excess storage below purchase limit', () => {
beforeEach(() => {
mountComponent({
containsLockedProjects: false,
repositorySizeExcessProjectCount: 0,
totalRepositorySizeExcess: THREE_GB_IN_BYTES,
totalRepositorySize: THIRTEEN_GB_IN_BYTES,
additionalPurchasedStorageSize: FIVE_GB_IN_BYTES,
repositoryFreeSizeLimit: TEN_GB_IN_BYTES,
});
});
it('renders info variant alert', () => {
expect(findAlert().exists()).toBe(true);
expect(findAlert().props('variant')).toBe('info');
});
it('renders text explaining storage', () => {
expect(findAlert().text()).toBe(
'When you purchase additional storage, we automatically unlock projects that were locked when you reached the 9.31 GiB limit.',
);
});
});
describe('excess storage above purchase limit', () => {
beforeEach(() => {
mountComponent({
containsLockedProjects: true,
repositorySizeExcessProjectCount: 1,
totalRepositorySizeExcess: THREE_GB_IN_BYTES,
totalRepositorySize: THIRTEEN_GB_IN_BYTES,
additionalPurchasedStorageSize: THREE_GB_IN_BYTES,
repositoryFreeSizeLimit: TEN_GB_IN_BYTES,
});
});
it('renders danger alert', () => {
expect(findAlert().exists()).toBe(true);
expect(findAlert().props('variant')).toBe('danger');
});
});
});
......@@ -8,6 +8,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gitlab 1.0.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-10-07 20:01+0000\n"
"PO-Revision-Date: 2020-10-07 20:01+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
......@@ -26628,6 +26630,9 @@ msgstr ""
msgid "This merge request was merged. To apply this suggestion, edit this file directly."
msgstr ""
msgid "This namespace contains locked projects"
msgstr ""
msgid "This namespace has already been taken! Please choose another one."
msgstr ""
......@@ -30163,6 +30168,9 @@ msgstr ""
msgid "Your projects"
msgstr ""
msgid "Your purchased storage is running low. To avoid locked projects, please purchase more storage."
msgstr ""
msgid "Your request for access could not be processed: %{error_meesage}"
msgstr ""
......
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