Commit 678286b8 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '14693-storage-usage' into 'master'

Adds total usage in storage quotas

Closes #14693

See merge request gitlab-org/gitlab-ee!16048
parents 697cb8d3 a3a6a5c0
<script>
import { GlLink } from '@gitlab/ui';
import Project from './project.vue';
import query from '../queries/storage.graphql';
import { numberToHumanSize } from '~/lib/utils/number_utils';
import Icon from '~/vue_shared/components/icon.vue';
export default {
components: {
Project,
GlLink,
Icon,
},
props: {
namespacePath: {
type: String,
required: true,
},
helpPagePath: {
type: String,
required: true,
},
},
apollo: {
namespace: {
......@@ -20,8 +29,18 @@ export default {
fullPath: this.namespacePath,
};
},
/**
* `rootStorageStatistics` will be sent as null until an
* event happens to trigger the storage count.
* For that reason we have to verify if `storageSize` is sent or
* if we should render N/A
*/
update: data => ({
projects: data.namespace.projects.edges.map(({ node }) => node),
totalUsage:
data.namespace.rootStorageStatistics && data.namespace.rootStorageStatistics.storageSize
? numberToHumanSize(data.namespace.rootStorageStatistics.storageSize)
: 'N/A',
}),
},
},
......@@ -33,19 +52,40 @@ export default {
};
</script>
<template>
<div class="ci-table" role="grid">
<div
class="gl-responsive-table-row table-row-header bg-gray-light pl-2 border-top mt-3 lh-100"
role="row"
>
<div class="table-section section-70 font-weight-bold" role="columnheader">
{{ __('Project') }}
</div>
<div class="table-section section-30 font-weight-bold" role="columnheader">
{{ __('Usage') }}
<div>
<div class="pipeline-quota container-fluid">
<div class="row">
<div class="col-sm-6">
<strong>{{ s__('UsageQuota|Usage since') }}</strong>
<div>
<span class="js-total-usage">
{{ namespace.totalUsage }}
<gl-link
:href="helpPagePath"
target="_blank"
:aria-label="__('Usage quotas help link')"
>
<icon name="question" :size="12" />
</gl-link>
</span>
</div>
</div>
</div>
</div>
<div class="ci-table" role="grid">
<div
class="gl-responsive-table-row table-row-header bg-gray-light pl-2 border-top mt-3 lh-100"
role="row"
>
<div class="table-section section-70 font-weight-bold" role="columnheader">
{{ __('Project') }}
</div>
<div class="table-section section-30 font-weight-bold" role="columnheader">
{{ __('Usage') }}
</div>
</div>
<project v-for="project in namespace.projects" :key="project.id" :project="project" />
<project v-for="project in namespace.projects" :key="project.id" :project="project" />
</div>
</div>
</template>
......@@ -7,7 +7,7 @@ Vue.use(VueApollo);
export default () => {
const el = document.getElementById('js-storage-counter-app');
const { namespacePath } = el.dataset;
const { namespacePath, helpPagePath } = el.dataset;
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(),
......@@ -20,6 +20,7 @@ export default () => {
return h(App, {
props: {
namespacePath,
helpPagePath,
},
});
},
......
query getStorageCounter($fullPath: ID!) {
namespace(fullPath: $fullPath) {
id
rootStorageStatistics {
storageSize
}
projects(includeSubgroups: true) {
edges {
node {
......
......@@ -23,5 +23,5 @@
= render "namespaces/pipelines_quota/list",
locals: { namespace: @group, projects: @projects }
.tab-pane#storage-quota-tab
#js-storage-counter-app{ data: { namespace_path: @group.full_path } }
#js-storage-counter-app{ data: { namespace_path: @group.full_path, help_page_path: help_page_path('user/group', anchor: 'storage-usage-quota-starter')} }
---
title: Adds total usage information to the usage quotas page
merge_request:
author:
type: added
import { shallowMount } from '@vue/test-utils';
import StorageApp from 'ee/storage_counter/components/app.vue';
import Project from 'ee/storage_counter/components/project.vue';
import { projects } from '../data';
import { projects, withRootStorageStatistics } from '../data';
describe('Storage counter app', () => {
let wrapper;
......@@ -16,19 +16,47 @@ describe('Storage counter app', () => {
};
wrapper = shallowMount(StorageApp, {
propsData: { namespacePath: 'h5bp' },
propsData: { namespacePath: 'h5bp', helpPagePath: 'help' },
mocks: { $apollo },
sync: true,
});
}
beforeEach(() => {
createComponent();
});
afterEach(() => {
wrapper.destroy();
});
it('renders the 2 projects', () => {
wrapper.setData({
namespace: projects,
});
});
it('renders the 2 projects', () => {
expect(wrapper.findAll(Project).length).toEqual(2);
});
describe('with rootStorageStatistics information', () => {
it('renders total usage', () => {
wrapper.setData({
namespace: withRootStorageStatistics,
});
expect(wrapper.find('.js-total-usage').text()).toContain(
withRootStorageStatistics.totalUsage,
);
});
});
describe('without rootStorageStatistics information', () => {
it('renders N/A', () => {
wrapper.setData({
namespace: projects,
});
expect(wrapper.find('.js-total-usage').text()).toContain('N/A');
});
});
});
// eslint-disable-next-line import/prefer-default-export
export const projects = {
totalUsage: 'N/A',
projects: [
{
id: '24',
......@@ -35,3 +35,7 @@ export const projects = {
},
],
};
export const withRootStorageStatistics = Object.assign({}, projects, {
totalUsage: 3261070,
});
......@@ -16634,6 +16634,9 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
msgid "Usage quotas help link"
msgstr ""
msgid "Usage statistics"
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