Commit cba9e42d authored by Sheldon Led's avatar Sheldon Led Committed by Natalia Tepluhina

Fetch project capacity and usage items for all types of storage

parent 01cae961
<script>
import { GlAlert } from '@gitlab/ui';
import { s__ } from '~/locale';
import getProjectStorageCount from '../queries/project_storage.query.graphql';
import { parseGetProjectStorageResults } from '../utils';
export default {
name: 'StorageCounterApp',
components: {
GlAlert,
},
inject: ['projectPath'],
apollo: {
project: {
query: getProjectStorageCount,
variables() {
return {
fullPath: this.projectPath,
};
},
update: parseGetProjectStorageResults,
error() {
this.error = s__(
'UsageQuota|Something went wrong while fetching project storage statistics',
);
},
},
},
data() {
return {
project: {},
error: '',
};
},
methods: {
clearError() {
this.error = '';
},
},
i18n: {
placeholder: s__('UsageQuota|Usage'),
},
};
</script>
<template>
<div>{{ $options.i18n.placeholder }}</div>
<gl-alert v-if="error" variant="danger" @dismiss="clearError">
{{ error }}
</gl-alert>
<div v-else>{{ $options.i18n.placeholder }}</div>
</template>
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
import StorageCounterApp from './components/app.vue';
Vue.use(VueApollo);
export default (containerId = 'js-project-storage-count-app') => {
const el = document.getElementById(containerId);
......@@ -8,8 +12,18 @@ export default (containerId = 'js-project-storage-count-app') => {
return false;
}
const { projectPath } = el.dataset;
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
});
return new Vue({
el,
apolloProvider,
provide: {
projectPath,
},
render(createElement) {
return createElement(StorageCounterApp);
},
......
query getProjectStorageCount($fullPath: ID!) {
project(fullPath: $fullPath) {
id
statistics {
buildArtifactsSize
lfsObjectsSize
packagesSize
repositorySize
snippetsSize
storageSize
uploadsSize
wikiSize
}
}
}
import { numberToHumanSize } from '~/lib/utils/number_utils';
import { s__ } from '~/locale';
const projectStorageTypes = [
{
id: 'buildArtifactsSize',
name: s__('UsageQuota|Artifacts'),
},
{
id: 'lfsObjectsSize',
name: s__('UsageQuota|LFS Storage'),
},
{
id: 'packagesSize',
name: s__('UsageQuota|Packages'),
},
{
id: 'repositorySize',
name: s__('UsageQuota|Repository'),
},
{
id: 'snippetsSize',
name: s__('UsageQuota|Snippets'),
},
{
id: 'uploadsSize',
name: s__('UsageQuota|Uploads'),
},
{
id: 'wikiSize',
name: s__('UsageQuota|Wiki'),
},
];
/**
* This method parses the results from `getProjectStorageCount` call.
*
* @param {Object} data graphql result
* @returns {Object}
*/
export const parseGetProjectStorageResults = (data) => {
const projectStatistics = data?.project?.statistics;
if (!projectStatistics) {
return {};
}
const { storageSize, ...storageStatistics } = projectStatistics;
const storageTypes = projectStorageTypes.reduce((types, currentType) => {
if (!storageStatistics[currentType.id]) {
return types;
}
return types.concat({
...currentType,
value: numberToHumanSize(storageStatistics[currentType.id]),
});
}, []);
return {
storage: {
totalUsage: numberToHumanSize(storageSize),
storageTypes,
},
};
};
......@@ -14,4 +14,4 @@
= s_('UsageQuota|Storage')
.tab-content
.tab-pane#storage-quota-tab
#js-project-storage-count-app
#js-project-storage-count-app{ data: { project_path: @project.full_path } }
......@@ -36085,6 +36085,9 @@ msgstr ""
msgid "UsageQuota|Snippets"
msgstr ""
msgid "UsageQuota|Something went wrong while fetching project storage statistics"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
......
import { shallowMount } from '@vue/test-utils';
import { GlAlert } from '@gitlab/ui';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import StorageCounterApp from '~/projects/storage_counter/components/app.vue';
import getProjectStorageCount from '~/projects/storage_counter/queries/project_storage.query.graphql';
const localVue = createLocalVue();
describe('Storage counter app', () => {
let wrapper;
const createComponent = (propsData = {}) => {
wrapper = shallowMount(StorageCounterApp, { propsData });
const createMockApolloProvider = () => {
localVue.use(VueApollo);
const requestHandlers = [
[getProjectStorageCount, jest.fn().mockRejectedValue(new Error('GraphQL error'))],
];
return createMockApollo(requestHandlers);
};
const createComponent = ({ provide = {}, mockApollo } = {}) => {
const defaultProvideValues = {
projectPath: 'test-project',
};
wrapper = shallowMount(StorageCounterApp, {
localVue,
apolloProvider: mockApollo,
provide: {
...defaultProvideValues,
...provide,
},
});
};
const findAlert = () => wrapper.findComponent(GlAlert);
beforeEach(() => {
createComponent();
});
......@@ -19,4 +48,17 @@ describe('Storage counter app', () => {
it('renders app successfully', () => {
expect(wrapper.text()).toBe('Usage');
});
describe('handling apollo fetching error', () => {
let mockApollo;
beforeEach(() => {
mockApollo = createMockApolloProvider();
createComponent({ mockApollo });
});
it('renders gl-alert if there is an error', () => {
expect(findAlert().exists()).toBe(true);
});
});
});
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