Commit d2a4d6c2 authored by Ammar Alakkad's avatar Ammar Alakkad Committed by Miguel Rincon

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

parent 263a9980
......@@ -53,6 +53,7 @@ export default {
variables() {
return {
fullPath: this.namespacePath,
searchTerm: this.searchTerm,
withExcessStorageData: this.isAdditionalStorageFlagEnabled,
};
},
......@@ -62,6 +63,7 @@ export default {
data() {
return {
namespace: {},
searchTerm: '',
};
},
computed: {
......@@ -94,6 +96,14 @@ export default {
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',
};
......@@ -172,6 +182,7 @@ export default {
<projects-table
:projects="namespaceProjects"
:additional-purchased-storage-size="namespace.additionalPurchasedStorageSize || 0"
@search="handleSearch"
/>
<temporary-storage-increase-modal
v-if="isStorageIncreaseModalVisible"
......
......@@ -116,7 +116,7 @@ export default {
data-testid="projectTableRow"
>
<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"
>
<div class="table-mobile-header gl-font-weight-bold" role="rowheader">
......@@ -146,7 +146,7 @@ export default {
</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"
>
<div class="table-mobile-header gl-font-weight-bold" role="rowheader">
......@@ -155,7 +155,7 @@ export default {
<div class="table-mobile-content gl-text-gray-900">{{ storageSize }}</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"
>
<div class="table-mobile-header gl-font-weight-bold" role="rowheader">
......
<script>
import { GlSearchBoxByType } from '@gitlab/ui';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import Project from './project.vue';
import ProjectWithExcessStorage from './project_with_excess_storage.vue';
import { SEARCH_DEBOUNCE_MS } from '~/ref/constants';
export default {
components: {
Project,
ProjectWithExcessStorage,
GlSearchBoxByType,
},
mixins: [glFeatureFlagsMixin()],
props: {
......@@ -30,25 +33,33 @@ export default {
return Project;
},
},
searchDebounceValue: SEARCH_DEBOUNCE_MS,
};
</script>
<template>
<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"
>
<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') }}
</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') }}
</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') }}
</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 v-else>
<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) {
id
name
......@@ -19,7 +23,7 @@ query getStorageCounter($fullPath: ID!, $withExcessStorageData: Boolean = false)
wikiSize
snippetsSize
}
projects(includeSubgroups: true, sort: STORAGE) {
projects(includeSubgroups: true, sort: STORAGE, search: $searchTerm) {
edges {
node {
id
......
import { mount } from '@vue/test-utils';
import StorageApp from 'ee/storage_counter/components/app.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 TemporaryStorageIncreaseModal from 'ee/storage_counter/components/temporary_storage_increase_modal.vue';
import UsageGraph from 'ee/storage_counter/components/usage_graph.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 { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { namespaceData, withRootStorageStatistics } from '../mock_data';
......@@ -21,6 +22,7 @@ describe('Storage counter app', () => {
const findUsageGraph = () => wrapper.find(UsageGraph);
const findUsageStatistics = () => wrapper.find(UsageStatistics);
const findStorageInlineAlert = () => wrapper.find(StorageInlineAlert);
const findProjectsTable = () => wrapper.find(ProjectsTable);
const createComponent = ({
props = {},
......@@ -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