Commit ec513224 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch 'led/fe-usage-quotas-refactor-3' into 'master'

Add helpLinks to project storage on namespace usage quotas

See merge request gitlab-org/gitlab!75620
parents f5725b55 60d4e2ac
......@@ -9,14 +9,5 @@ class Projects::UsageQuotasController < Projects::ApplicationController
def index
@hide_search_settings = true
@storage_app_data = {
project_path: @project.full_path,
usage_quotas_help_page_path: help_page_path('user/usage_quotas'),
build_artifacts_help_page_path: help_page_path('ci/pipelines/job_artifacts', anchor: 'when-job-artifacts-are-deleted'),
packages_help_page_path: help_page_path('user/packages/package_registry/index.md', anchor: 'delete-a-package'),
repository_help_page_path: help_page_path('user/project/repository/reducing_the_repo_size_using_git'),
snippets_help_page_path: help_page_path('user/snippets', anchor: 'reduce-snippets-repository-size'),
wiki_help_page_path: help_page_path('administration/wikis/index.md', anchor: 'reduce-wiki-repository-size')
}
end
end
......@@ -16,4 +16,4 @@
= s_('UsageQuota|Storage')
.tab-content
.tab-pane#storage-quota-tab
#js-project-storage-count-app{ data: @storage_app_data }
#js-project-storage-count-app{ data: { project_path: @project.full_path } }
......@@ -14,6 +14,7 @@ export default {
ProjectAvatar,
ProjectStorageDetail,
},
inject: ['helpLinks'],
props: {
project: {
required: true,
......@@ -36,7 +37,7 @@ export default {
return this.isOpen ? 'angle-down' : 'angle-right';
},
projectStorageTypes() {
return getStorageTypesFromProjectStatistics(this.project.statistics);
return getStorageTypesFromProjectStatistics(this.project.statistics, this.helpLinks);
},
},
methods: {
......
......@@ -36,26 +36,7 @@ export default {
GlModalDirective,
},
mixins: [glFeatureFlagsMixin()],
props: {
namespacePath: {
type: String,
required: true,
},
helpPagePath: {
type: String,
required: true,
},
purchaseStorageUrl: {
type: String,
required: false,
default: null,
},
isTemporaryStorageIncreaseVisible: {
type: String,
required: false,
default: 'false',
},
},
inject: ['namespacePath', 'purchaseStorageUrl', 'isTemporaryStorageIncreaseVisible', 'helpLinks'],
apollo: {
namespace: {
query,
......@@ -171,10 +152,7 @@ export default {
:actual-repository-size-limit="namespace.actualRepositorySizeLimit"
/>
<div v-if="isAdditionalStorageFlagEnabled && storageStatistics">
<usage-statistics
:root-storage-statistics="storageStatistics"
:purchase-storage-url="purchaseStorageUrl"
/>
<usage-statistics :root-storage-statistics="storageStatistics" />
</div>
<div v-else class="gl-py-4 gl-px-2 gl-m-0">
<div class="gl-display-flex gl-align-items-center">
......@@ -197,7 +175,7 @@ export default {
</template>
</gl-sprintf>
<gl-link
:href="helpPagePath"
:href="helpLinks.usageQuotas"
target="_blank"
:aria-label="s__('UsageQuota|Usage quotas help link')"
>
......
......@@ -84,7 +84,7 @@ export default {
<p class="gl-m-0 gl-text-gray-400">
{{ $options.TOTAL_USAGE_SUBTITLE }}
<gl-link
:href="helpLinks.usageQuotasHelpPagePath"
:href="helpLinks.usageQuotas"
target="_blank"
:aria-label="helpLinkAriaLabel($options.USAGE_QUOTAS_LABEL)"
data-testid="usage-quotas-help-link"
......
......@@ -12,16 +12,12 @@ export default {
UsageStatisticsCard,
},
mixins: [glFeatureFlagsMixin()],
inject: ['purchaseStorageUrl'],
props: {
rootStorageStatistics: {
required: true,
type: Object,
},
purchaseStorageUrl: {
required: false,
type: String,
default: '',
},
},
computed: {
formattedActualRepoSizeLimit() {
......
import { s__, __ } from '~/locale';
import { helpPagePath } from '~/helpers/help_page_helper';
export const ERROR_MESSAGE = s__(
'UsageQuota|Something went wrong while fetching project storage statistics',
......@@ -77,3 +78,20 @@ export const STORAGE_USAGE_THRESHOLDS = {
};
export const PROJECTS_PER_PAGE = 20;
export const projectHelpLinks = {
usageQuotas: helpPagePath('user/usage_quotas'),
buildArtifacts: helpPagePath('ci/pipelines/job_artifacts', {
anchor: 'when-job-artifacts-are-deleted',
}),
packages: helpPagePath('user/packages/package_registry/index.md', {
anchor: 'delete-a-package',
}),
repository: helpPagePath('user/project/repository/reducing_the_repo_size_using_git'),
snippets: helpPagePath('user/snippets', {
anchor: 'reduce-snippets-repository-size',
}),
wiki: helpPagePath('administration/wikis/index.md', {
anchor: 'reduce-wiki-repository-size',
}),
};
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
import { projectHelpLinks as helpLinks } from './constants';
import NamespaceStorageApp from './components/namespace_storage_app.vue';
Vue.use(VueApollo);
export default () => {
const el = document.getElementById('js-storage-counter-app');
const {
namespacePath,
helpPagePath,
purchaseStorageUrl,
isTemporaryStorageIncreaseVisible,
} = el.dataset;
const { namespacePath, purchaseStorageUrl, isTemporaryStorageIncreaseVisible } = el.dataset;
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(),
......@@ -21,15 +17,14 @@ export default () => {
return new Vue({
el,
apolloProvider,
provide: {
namespacePath,
purchaseStorageUrl,
isTemporaryStorageIncreaseVisible,
helpLinks,
},
render(createElement) {
return createElement(NamespaceStorageApp, {
props: {
namespacePath,
helpPagePath,
purchaseStorageUrl,
isTemporaryStorageIncreaseVisible,
},
});
return createElement(NamespaceStorageApp);
},
});
};
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
import { projectHelpLinks as helpLinks } from './constants';
import ProjectStorageApp from './components/project_storage_app.vue';
Vue.use(VueApollo);
......@@ -12,17 +13,7 @@ export default (containerId = 'js-project-storage-count-app') => {
return false;
}
const {
projectPath,
usageQuotasHelpPagePath,
buildArtifactsHelpPagePath,
lfsObjectsHelpPagePath,
packagesHelpPagePath,
repositoryHelpPagePath,
snippetsHelpPagePath,
uploadsHelpPagePath,
wikiHelpPagePath,
} = el.dataset;
const { projectPath } = el.dataset;
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(),
......@@ -33,16 +24,7 @@ export default (containerId = 'js-project-storage-count-app') => {
apolloProvider,
provide: {
projectPath,
helpLinks: {
usageQuotasHelpPagePath,
buildArtifactsHelpPagePath,
lfsObjectsHelpPagePath,
packagesHelpPagePath,
repositoryHelpPagePath,
snippetsHelpPagePath,
uploadsHelpPagePath,
wikiHelpPagePath,
},
helpLinks,
},
render(createElement) {
return createElement(ProjectStorageApp);
......
......@@ -144,7 +144,7 @@ export const parseGetStorageResults = (data) => {
export const getStorageTypesFromProjectStatistics = (projectStatistics, helpLinks = {}) =>
PROJECT_STORAGE_TYPES.reduce((types, currentType) => {
const helpPathKey = currentType.id.replace(`Size`, `HelpPagePath`);
const helpPathKey = currentType.id.replace(`Size`, ``);
const helpPath = helpLinks[helpPathKey];
return types.concat({
......
......@@ -31,4 +31,4 @@
= 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, help_page_path: help_page_path('user/usage_quotas.md'), purchase_storage_url: url_to_purchase_storage, is_temporary_storage_increase_visible: temporary_storage_increase_visible?(@group).to_s } }
#js-storage-counter-app{ data: { namespace_path: @group.full_path, purchase_storage_url: url_to_purchase_storage, is_temporary_storage_increase_visible: temporary_storage_increase_visible?(@group).to_s } }
......@@ -22,4 +22,4 @@
= render "namespaces/pipelines_quota/list",
locals: { namespace: @namespace, projects: @projects }
.tab-pane#storage-quota-tab
#js-storage-counter-app{ data: { namespace_path: @namespace.full_path, help_page_path: help_page_path('user/usage_quotas.md'), purchase_storage_url: url_to_purchase_storage, is_temporary_storage_increase_visible: temporary_storage_increase_visible?(@namespace).to_s } }
#js-storage-counter-app{ data: { namespace_path: @namespace.full_path, purchase_storage_url: url_to_purchase_storage, is_temporary_storage_increase_visible: temporary_storage_increase_visible?(@namespace).to_s } }
......@@ -3,7 +3,7 @@ import CollapsibleProjectStorageDetail from 'ee/usage_quotas/storage/components/
import ProjectStorageDetail from 'ee/usage_quotas/storage/components/project_storage_detail.vue';
import { numberToHumanSize } from '~/lib/utils/number_utils';
import ProjectAvatar from '~/vue_shared/components/project_avatar.vue';
import { projects } from '../mock_data';
import { projects, projectHelpLinks as helpLinks } from '../mock_data';
let wrapper;
const createComponent = () => {
......@@ -11,6 +11,9 @@ const createComponent = () => {
propsData: {
project: projects[1],
},
provide: {
helpLinks,
},
});
};
......
......@@ -8,7 +8,11 @@ import UsageStatistics from 'ee/usage_quotas/storage/components/usage_statistics
import UsageGraph from 'ee/usage_quotas/storage/components/usage_graph.vue';
import { formatUsageSize } from 'ee/usage_quotas/storage/utils';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { namespaceData, withRootStorageStatistics } from '../mock_data';
import {
namespaceData,
withRootStorageStatistics,
defaultNamespaceProvideValues,
} from '../mock_data';
const TEST_LIMIT = 1000;
......@@ -27,7 +31,7 @@ describe('NamespaceStorageApp', () => {
const findNextButton = () => wrapper.find('[data-testid="nextButton"]');
const createComponent = ({
props = {},
provide = {},
loading = false,
additionalRepoStorageByNamespace = false,
namespace = {},
......@@ -41,7 +45,6 @@ describe('NamespaceStorageApp', () => {
};
wrapper = mount(NamespaceStorageApp, {
propsData: { namespacePath: 'h5bp', helpPagePath: 'help', ...props },
mocks: { $apollo },
directives: {
GlModalDirective: createMockDirective(),
......@@ -50,6 +53,8 @@ describe('NamespaceStorageApp', () => {
glFeatures: {
additionalRepoStorageByNamespace,
},
...defaultNamespaceProvideValues,
...provide,
},
data() {
return {
......@@ -159,7 +164,7 @@ describe('NamespaceStorageApp', () => {
describe('when purchaseStorageUrl is set', () => {
beforeEach(() => {
createComponent({ props: { purchaseStorageUrl: 'customers.gitlab.com' } });
createComponent({ provide: { purchaseStorageUrl: 'customers.gitlab.com' } });
});
it('does render link', () => {
......@@ -173,13 +178,13 @@ describe('NamespaceStorageApp', () => {
describe('temporary storage increase', () => {
describe.each`
props | isVisible
provide | isVisible
${{}} | ${false}
${{ isTemporaryStorageIncreaseVisible: 'false' }} | ${false}
${{ isTemporaryStorageIncreaseVisible: 'true' }} | ${true}
`('with $props', ({ props, isVisible }) => {
`('with $provide', ({ provide, isVisible }) => {
beforeEach(() => {
createComponent({ props });
createComponent({ provide });
});
it(`renders button = ${isVisible}`, () => {
......@@ -189,7 +194,7 @@ describe('NamespaceStorageApp', () => {
describe('when temporary storage increase is visible', () => {
beforeEach(() => {
createComponent({ props: { isTemporaryStorageIncreaseVisible: 'true' } });
createComponent({ provide: { isTemporaryStorageIncreaseVisible: 'true' } });
wrapper.setData({
namespace: {
...namespaceData,
......
......@@ -75,7 +75,7 @@ describe('ProjectStorageApp', () => {
it('renders correct usage quotas help link', () => {
expect(findUsageQuotasHelpLink().attributes('href')).toBe(
defaultProjectProvideValues.helpLinks.usageQuotasHelpPagePath,
defaultProjectProvideValues.helpLinks.usageQuotas,
);
});
});
......
......@@ -39,9 +39,7 @@ describe('ProjectStorageDetail', () => {
expect(wrapper.findByTestId(`${id}-description`).text()).toBe(description);
expect(wrapper.findByTestId(`${id}-icon`).props('name')).toBe(id);
expect(wrapper.findByTestId(`${id}-help-link`).attributes('href')).toBe(
projectHelpLinks[id.replace(`Size`, `HelpPagePath`)]
.replace(`Size`, ``)
.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`),
projectHelpLinks[id.replace(`Size`, ``)],
);
},
);
......
......@@ -7,7 +7,7 @@ import { withRootStorageStatistics } from '../mock_data';
describe('UsageStatistics', () => {
let wrapper;
const createComponent = ({ props = {}, newRouteStoragePurchase = false } = {}) => {
const createComponent = ({ props = {}, provide = {}, newRouteStoragePurchase = false } = {}) => {
wrapper = shallowMount(UsageStatistics, {
propsData: {
rootStorageStatistics: {
......@@ -22,6 +22,7 @@ describe('UsageStatistics', () => {
glFeatures: {
newRouteStoragePurchase,
},
...provide,
},
stubs: {
UsageStatisticsCard,
......@@ -45,7 +46,7 @@ describe('UsageStatistics', () => {
describe('with purchaseStorageUrl passed and newRouteStoragePurchase flag enabled', () => {
beforeEach(() => {
createComponent({
props: {
provide: {
purchaseStorageUrl: 'some-fancy-url',
},
newRouteStoragePurchase: true,
......@@ -63,7 +64,7 @@ describe('UsageStatistics', () => {
describe('with purchaseStorageUrl passed', () => {
beforeEach(() => {
createComponent({
props: {
provide: {
purchaseStorageUrl: 'some-fancy-url',
},
});
......@@ -96,7 +97,7 @@ describe('UsageStatistics', () => {
describe('with no purchaseStorageUrl', () => {
beforeEach(() => {
createComponent({
props: {
provide: {
purchaseStorageUrl: null,
},
});
......
......@@ -138,14 +138,14 @@ export const projectData = {
};
export const projectHelpLinks = {
usageQuotasHelpPagePath: '/usage-quotas',
buildArtifactsHelpPagePath: '/build-artifacts',
lfsObjectsHelpPagePath: '/lsf-objects',
packagesHelpPagePath: '/packages',
repositoryHelpPagePath: '/repository',
snippetsHelpPagePath: '/snippets',
uploadsHelpPagePath: '/uploads',
wikiHelpPagePath: '/wiki',
usageQuotas: '/usage-quotas',
buildArtifacts: '/build-artifacts',
lfsObjects: '/lsf-objects',
packages: '/packages',
repository: '/repository',
snippets: '/snippets',
uploads: '/uploads',
wiki: '/wiki',
};
export const defaultProjectProvideValues = {
......@@ -153,6 +153,13 @@ export const defaultProjectProvideValues = {
helpLinks: projectHelpLinks,
};
export const defaultNamespaceProvideValues = {
namespacePath: 'h5bp',
purchaseStorageUrl: '',
isTemporaryStorageIncreaseVisible: false,
helpLinks: projectHelpLinks,
};
export const namespaceData = {
totalUsage: 'N/A',
limit: 10000000,
......
......@@ -23,20 +23,10 @@ RSpec.describe 'Project Usage Quotas' do
describe 'GET /:namespace/:project/usage_quotas' do
it 'renders usage quotas path' do
mock_storage_app_data = {
project_path: project.full_path,
usage_quotas_help_page_path: help_page_path('user/usage_quotas'),
build_artifacts_help_page_path: help_page_path('ci/pipelines/job_artifacts', anchor: 'when-job-artifacts-are-deleted'),
packages_help_page_path: help_page_path('user/packages/package_registry/index.md', anchor: 'delete-a-package'),
repository_help_page_path: help_page_path('user/project/repository/reducing_the_repo_size_using_git'),
snippets_help_page_path: help_page_path('user/snippets', anchor: 'reduce-snippets-repository-size'),
wiki_help_page_path: help_page_path('administration/wikis/index.md', anchor: 'reduce-wiki-repository-size')
}
get project_usage_quotas_path(project)
expect(response).to have_gitlab_http_status(:ok)
expect(response.body).to include(project_usage_quotas_path(project))
expect(assigns[:storage_app_data]).to eq(mock_storage_app_data)
expect(response.body).to include("Usage of project resources across the <strong>#{project.name}</strong> project")
end
......
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