Commit 8a084072 authored by Miguel Rincon's avatar Miguel Rincon

Merge branch '247840-enable-group-filter-in-usage-quota-projects-table' into 'master'

Enable Filter groups by name in the Usage quota groups/projects table

See merge request gitlab-org/gitlab!45878
parents 8e2bcb53 d2a4d6c2
...@@ -53,6 +53,7 @@ export default { ...@@ -53,6 +53,7 @@ export default {
variables() { variables() {
return { return {
fullPath: this.namespacePath, fullPath: this.namespacePath,
searchTerm: this.searchTerm,
withExcessStorageData: this.isAdditionalStorageFlagEnabled, withExcessStorageData: this.isAdditionalStorageFlagEnabled,
}; };
}, },
...@@ -62,6 +63,7 @@ export default { ...@@ -62,6 +63,7 @@ export default {
data() { data() {
return { return {
namespace: {}, namespace: {},
searchTerm: '',
}; };
}, },
computed: { computed: {
...@@ -94,6 +96,14 @@ export default { ...@@ -94,6 +96,14 @@ export default {
return this.isAdditionalStorageFlagEnabled && !this.$apollo.queries.namespace.loading; return this.isAdditionalStorageFlagEnabled && !this.$apollo.queries.namespace.loading;
}, },
}, },
methods: {
handleSearch(input) {
// if length === 0 clear the search, if length > 2 update the search term
if (input.length === 0 || input.length > 2) {
this.searchTerm = input;
}
},
},
modalId: 'temporary-increase-storage-modal', modalId: 'temporary-increase-storage-modal',
}; };
...@@ -172,6 +182,7 @@ export default { ...@@ -172,6 +182,7 @@ export default {
<projects-table <projects-table
:projects="namespaceProjects" :projects="namespaceProjects"
:additional-purchased-storage-size="namespace.additionalPurchasedStorageSize || 0" :additional-purchased-storage-size="namespace.additionalPurchasedStorageSize || 0"
@search="handleSearch"
/> />
<temporary-storage-increase-modal <temporary-storage-increase-modal
v-if="isStorageIncreaseModalVisible" v-if="isStorageIncreaseModalVisible"
......
...@@ -116,7 +116,7 @@ export default { ...@@ -116,7 +116,7 @@ export default {
data-testid="projectTableRow" data-testid="projectTableRow"
> >
<div <div
class="table-section gl-white-space-normal! gl-flex-sm-wrap section-50 gl-text-truncate" class="table-section gl-white-space-normal! gl-flex-sm-wrap section-50 gl-text-truncate gl-pr-5"
role="gridcell" role="gridcell"
> >
<div class="table-mobile-header gl-font-weight-bold" role="rowheader"> <div class="table-mobile-header gl-font-weight-bold" role="rowheader">
...@@ -146,7 +146,7 @@ export default { ...@@ -146,7 +146,7 @@ export default {
</div> </div>
</div> </div>
<div <div
class="table-section gl-white-space-normal! gl-flex-sm-wrap section-25 gl-text-truncate" class="table-section gl-white-space-normal! gl-flex-sm-wrap section-15 gl-text-truncate"
role="gridcell" role="gridcell"
> >
<div class="table-mobile-header gl-font-weight-bold" role="rowheader"> <div class="table-mobile-header gl-font-weight-bold" role="rowheader">
...@@ -155,7 +155,7 @@ export default { ...@@ -155,7 +155,7 @@ export default {
<div class="table-mobile-content gl-text-gray-900">{{ storageSize }}</div> <div class="table-mobile-content gl-text-gray-900">{{ storageSize }}</div>
</div> </div>
<div <div
class="table-section gl-white-space-normal! gl-flex-sm-wrap section-25 gl-text-truncate" class="table-section gl-white-space-normal! gl-flex-sm-wrap section-15 gl-text-truncate"
role="gridcell" role="gridcell"
> >
<div class="table-mobile-header gl-font-weight-bold" role="rowheader"> <div class="table-mobile-header gl-font-weight-bold" role="rowheader">
......
<script> <script>
import { GlSearchBoxByType } from '@gitlab/ui';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import Project from './project.vue'; import Project from './project.vue';
import ProjectWithExcessStorage from './project_with_excess_storage.vue'; import ProjectWithExcessStorage from './project_with_excess_storage.vue';
import { SEARCH_DEBOUNCE_MS } from '~/ref/constants';
export default { export default {
components: { components: {
Project, Project,
ProjectWithExcessStorage, ProjectWithExcessStorage,
GlSearchBoxByType,
}, },
mixins: [glFeatureFlagsMixin()], mixins: [glFeatureFlagsMixin()],
props: { props: {
...@@ -30,25 +33,33 @@ export default { ...@@ -30,25 +33,33 @@ export default {
return Project; return Project;
}, },
}, },
searchDebounceValue: SEARCH_DEBOUNCE_MS,
}; };
</script> </script>
<template> <template>
<div> <div>
<div <div
class="gl-responsive-table-row table-row-header gl-pl-5 gl-border-t-solid gl-border-t-1 gl-border-gray-100 gl-mt-5 gl-line-height-normal gl-text-black-normal gl-font-base" class="gl-responsive-table-row table-row-header gl-border-t-solid gl-border-t-1 gl-border-gray-100 gl-mt-5 gl-line-height-normal gl-text-black-normal gl-font-base"
role="row" role="row"
> >
<template v-if="isAdditionalStorageFlagEnabled"> <template v-if="isAdditionalStorageFlagEnabled">
<div class="table-section section-50 gl-font-weight-bold" role="columnheader"> <div class="table-section section-50 gl-font-weight-bold gl-pl-5" role="columnheader">
{{ __('Project') }} {{ __('Project') }}
</div> </div>
<div class="table-section section-25 gl-font-weight-bold" role="columnheader"> <div class="table-section section-15 gl-font-weight-bold" role="columnheader">
{{ __('Usage') }} {{ __('Usage') }}
</div> </div>
<div class="table-section section-25 gl-font-weight-bold" role="columnheader"> <div class="table-section section-15 gl-font-weight-bold" role="columnheader">
{{ __('Excess storage') }} {{ __('Excess storage') }}
</div> </div>
<div class="table-section section-20 gl-font-weight-bold gl-pl-6" role="columnheader">
<gl-search-box-by-type
:placeholder="__('Search by name')"
:debounce="$options.searchDebounceValue"
@input="input => this.$emit('search', input)"
/>
</div>
</template> </template>
<template v-else> <template v-else>
<div class="table-section section-70 gl-font-weight-bold" role="columnheader"> <div class="table-section section-70 gl-font-weight-bold" role="columnheader">
......
query getStorageCounter($fullPath: ID!, $withExcessStorageData: Boolean = false) { query getStorageCounter(
$fullPath: ID!
$searchTerm: String = ""
$withExcessStorageData: Boolean = false
) {
namespace(fullPath: $fullPath) { namespace(fullPath: $fullPath) {
id id
name name
...@@ -19,7 +23,7 @@ query getStorageCounter($fullPath: ID!, $withExcessStorageData: Boolean = false) ...@@ -19,7 +23,7 @@ query getStorageCounter($fullPath: ID!, $withExcessStorageData: Boolean = false)
wikiSize wikiSize
snippetsSize snippetsSize
} }
projects(includeSubgroups: true, sort: STORAGE) { projects(includeSubgroups: true, sort: STORAGE, search: $searchTerm) {
edges { edges {
node { node {
id id
......
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import StorageApp from 'ee/storage_counter/components/app.vue'; import StorageApp from 'ee/storage_counter/components/app.vue';
import Project from 'ee/storage_counter/components/project.vue'; import Project from 'ee/storage_counter/components/project.vue';
import ProjectsTable from 'ee/storage_counter/components/projects_table.vue';
import StorageInlineAlert from 'ee/storage_counter/components/storage_inline_alert.vue'; import StorageInlineAlert from 'ee/storage_counter/components/storage_inline_alert.vue';
import TemporaryStorageIncreaseModal from 'ee/storage_counter/components/temporary_storage_increase_modal.vue';
import UsageGraph from 'ee/storage_counter/components/usage_graph.vue'; import UsageGraph from 'ee/storage_counter/components/usage_graph.vue';
import UsageStatistics from 'ee/storage_counter/components/usage_statistics.vue'; import UsageStatistics from 'ee/storage_counter/components/usage_statistics.vue';
import TemporaryStorageIncreaseModal from 'ee/storage_counter/components/temporary_storage_increase_modal.vue';
import { formatUsageSize } from 'ee/storage_counter/utils'; import { formatUsageSize } from 'ee/storage_counter/utils';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { namespaceData, withRootStorageStatistics } from '../mock_data'; import { namespaceData, withRootStorageStatistics } from '../mock_data';
...@@ -21,6 +22,7 @@ describe('Storage counter app', () => { ...@@ -21,6 +22,7 @@ describe('Storage counter app', () => {
const findUsageGraph = () => wrapper.find(UsageGraph); const findUsageGraph = () => wrapper.find(UsageGraph);
const findUsageStatistics = () => wrapper.find(UsageStatistics); const findUsageStatistics = () => wrapper.find(UsageStatistics);
const findStorageInlineAlert = () => wrapper.find(StorageInlineAlert); const findStorageInlineAlert = () => wrapper.find(StorageInlineAlert);
const findProjectsTable = () => wrapper.find(ProjectsTable);
const createComponent = ({ const createComponent = ({
props = {}, props = {},
...@@ -213,4 +215,46 @@ describe('Storage counter app', () => { ...@@ -213,4 +215,46 @@ describe('Storage counter app', () => {
}); });
}); });
}); });
describe('filtering projects', () => {
beforeEach(() => {
createComponent({
additionalRepoStorageByNamespace: true,
namespace: withRootStorageStatistics,
});
});
const sampleSearchTerm = 'GitLab';
const sampleShortSearchTerm = '12';
it('triggers search if user enters search input', () => {
expect(wrapper.vm.searchTerm).toBe('');
findProjectsTable().vm.$emit('search', sampleSearchTerm);
expect(wrapper.vm.searchTerm).toBe(sampleSearchTerm);
});
it('triggers search if user clears the entered search input', () => {
const projectsTable = findProjectsTable();
expect(wrapper.vm.searchTerm).toBe('');
projectsTable.vm.$emit('search', sampleSearchTerm);
expect(wrapper.vm.searchTerm).toBe(sampleSearchTerm);
projectsTable.vm.$emit('search', '');
expect(wrapper.vm.searchTerm).toBe('');
});
it('does not trigger search if user enters short search input', () => {
expect(wrapper.vm.searchTerm).toBe('');
findProjectsTable().vm.$emit('search', sampleShortSearchTerm);
expect(wrapper.vm.searchTerm).toBe('');
});
});
}); });
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