Commit d611e6d1 authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch '35288-update-metrics-dashboard-dropdowns' into 'master'

Added search box to dashboards dropdown

See merge request gitlab-org/gitlab!23906
parents 23318c9a 79614a08
......@@ -402,7 +402,9 @@ export default {
:text="currentEnvironmentName"
>
<div class="d-flex flex-column overflow-hidden">
<gl-dropdown-header class="text-center">{{ __('Environment') }}</gl-dropdown-header>
<gl-dropdown-header class="monitor-environment-dropdown-header text-center">{{
__('Environment')
}}</gl-dropdown-header>
<gl-dropdown-divider />
<gl-search-box-by-type
v-if="shouldRenderSearchableEnvironmentsDropdown"
......
......@@ -4,11 +4,14 @@ import {
GlAlert,
GlDropdown,
GlDropdownItem,
GlDropdownHeader,
GlDropdownDivider,
GlSearchBoxByType,
GlModal,
GlLoadingIcon,
GlModalDirective,
} from '@gitlab/ui';
import { s__ } from '~/locale';
import DuplicateDashboardForm from './duplicate_dashboard_form.vue';
const events = {
......@@ -20,7 +23,9 @@ export default {
GlAlert,
GlDropdown,
GlDropdownItem,
GlDropdownHeader,
GlDropdownDivider,
GlSearchBoxByType,
GlModal,
GlLoadingIcon,
DuplicateDashboardForm,
......@@ -44,6 +49,7 @@ export default {
alert: null,
loading: false,
form: {},
searchTerm: '',
};
},
computed: {
......@@ -54,6 +60,17 @@ export default {
selectedDashboardText() {
return this.selectedDashboard.display_name;
},
filteredDashboards() {
return this.allDashboards.filter(({ display_name }) =>
display_name.toLowerCase().includes(this.searchTerm.toLowerCase()),
);
},
shouldShowNoMsgContainer() {
return this.filteredDashboards.length === 0;
},
okButtonText() {
return this.loading ? s__('Metrics|Duplicating...') : s__('Metrics|Duplicate');
},
},
methods: {
...mapActions('monitoringDashboard', ['duplicateSystemDashboard']),
......@@ -95,45 +112,70 @@ export default {
};
</script>
<template>
<gl-dropdown toggle-class="dropdown-menu-toggle" :text="selectedDashboardText">
<gl-dropdown-item
v-for="dashboard in allDashboards"
:key="dashboard.path"
:active="dashboard.path === selectedDashboard.path"
active-class="is-active"
@click="selectDashboard(dashboard)"
>
{{ dashboard.display_name || dashboard.path }}
</gl-dropdown-item>
<template v-if="isSystemDashboard">
<gl-dropdown
toggle-class="dropdown-menu-toggle"
menu-class="monitor-dashboard-dropdown-menu"
:text="selectedDashboardText"
>
<div class="d-flex flex-column overflow-hidden">
<gl-dropdown-header class="monitor-dashboard-dropdown-header text-center">{{
__('Dashboard')
}}</gl-dropdown-header>
<gl-dropdown-divider />
<gl-search-box-by-type
ref="monitorDashboardsDropdownSearch"
v-model="searchTerm"
class="m-2"
/>
<div class="flex-fill overflow-auto">
<gl-dropdown-item
v-for="dashboard in filteredDashboards"
:key="dashboard.path"
:active="dashboard.path === selectedDashboard.path"
active-class="is-active"
@click="selectDashboard(dashboard)"
>
{{ dashboard.display_name || dashboard.path }}
</gl-dropdown-item>
</div>
<gl-modal
ref="duplicateDashboardModal"
modal-id="duplicateDashboardModal"
:title="s__('Metrics|Duplicate dashboard')"
ok-variant="success"
@ok="ok"
@hide="hide"
<div
v-show="shouldShowNoMsgContainer"
ref="monitorDashboardsDropdownMsg"
class="text-secondary no-matches-message"
>
<gl-alert v-if="alert" class="mb-3" variant="danger" @dismiss="alert = null">
{{ alert }}
</gl-alert>
<duplicate-dashboard-form
:dashboard="selectedDashboard"
:default-branch="defaultBranch"
@change="formChange"
/>
<template #modal-ok>
<gl-loading-icon v-if="loading" inline color="light" />
{{ loading ? s__('Metrics|Duplicating...') : s__('Metrics|Duplicate') }}
</template>
</gl-modal>
{{ __('No matching results') }}
</div>
<template v-if="isSystemDashboard">
<gl-dropdown-divider />
<gl-modal
ref="duplicateDashboardModal"
modal-id="duplicateDashboardModal"
:title="s__('Metrics|Duplicate dashboard')"
ok-variant="success"
@ok="ok"
@hide="hide"
>
<gl-alert v-if="alert" class="mb-3" variant="danger" @dismiss="alert = null">
{{ alert }}
</gl-alert>
<duplicate-dashboard-form
:dashboard="selectedDashboard"
:default-branch="defaultBranch"
@change="formChange"
/>
<template #modal-ok>
<gl-loading-icon v-if="loading" inline color="light" />
{{ okButtonText }}
</template>
</gl-modal>
<gl-dropdown-item ref="duplicateDashboardItem" v-gl-modal="'duplicateDashboardModal'">
{{ s__('Metrics|Duplicate dashboard') }}
</gl-dropdown-item>
</template>
<gl-dropdown-item ref="duplicateDashboardItem" v-gl-modal="'duplicateDashboardModal'">
{{ s__('Metrics|Duplicate dashboard') }}
</gl-dropdown-item>
</template>
</div>
</gl-dropdown>
</template>
......@@ -47,7 +47,12 @@
}
.prometheus-graphs-header {
.monitor-environment-dropdown-menu {
.monitor-dashboard-dropdown-header header {
font-size: $gl-font-size;
}
.monitor-environment-dropdown-menu,
.monitor-dashboard-dropdown-menu {
&.show {
display: flex;
flex-direction: column;
......
---
title: Added search box to dashboards dropdown in monitoring dashboard
merge_request: 23906
author:
type: added
......@@ -44,7 +44,7 @@ exports[`Dashboard template matches the default snapshot 1`] = `
class="d-flex flex-column overflow-hidden"
>
<gl-dropdown-header-stub
class="text-center"
class="monitor-environment-dropdown-header text-center"
>
Environment
</gl-dropdown-header-stub>
......
......@@ -35,13 +35,17 @@ describe('DashboardsDropdown', () => {
const findItems = () => wrapper.findAll(GlDropdownItem);
const findItemAt = i => wrapper.findAll(GlDropdownItem).at(i);
const findSearchInput = () => wrapper.find({ ref: 'monitorDashboardsDropdownSearch' });
const findNoItemsMsg = () => wrapper.find({ ref: 'monitorDashboardsDropdownMsg' });
const setSearchTerm = searchTerm => wrapper.setData({ searchTerm });
describe('when it receives dashboards data', () => {
beforeEach(() => {
wrapper = createComponent();
});
it('displays an item for each dashboard', () => {
expect(wrapper.findAll(GlDropdownItem).length).toEqual(dashboardGitResponse.length);
expect(findItems().length).toEqual(dashboardGitResponse.length);
});
it('displays items with the dashboard display name', () => {
......@@ -49,6 +53,32 @@ describe('DashboardsDropdown', () => {
expect(findItemAt(1).text()).toBe(dashboardGitResponse[1].display_name);
expect(findItemAt(2).text()).toBe(dashboardGitResponse[2].display_name);
});
it('displays a search input', () => {
expect(findSearchInput().isVisible()).toBe(true);
});
it('hides no message text by default', () => {
expect(findNoItemsMsg().isVisible()).toBe(false);
});
it('filters dropdown items when searched for item exists in the list', () => {
const searchTerm = 'Default';
setSearchTerm(searchTerm);
return wrapper.vm.$nextTick(() => {
expect(findItems()).toHaveLength(1);
});
});
it('shows no items found message when searched for item does not exists in the list', () => {
const searchTerm = 'does-not-exist';
setSearchTerm(searchTerm);
return wrapper.vm.$nextTick(() => {
expect(findNoItemsMsg().isVisible()).toBe(true);
});
});
});
describe('when a system dashboard is selected', () => {
......@@ -224,7 +254,7 @@ describe('DashboardsDropdown', () => {
it('displays an item for each dashboard', () => {
const item = wrapper.findAll({ ref: 'duplicateDashboardItem' });
expect(findItems().length).toEqual(dashboardGitResponse.length);
expect(findItems()).toHaveLength(dashboardGitResponse.length);
expect(item.length).toBe(0);
});
......
......@@ -518,6 +518,15 @@ export const metricsDashboardPayload = {
],
};
const customDashboardsData = new Array(30).fill(null).map((_, idx) => ({
default: false,
display_name: `Custom Dashboard ${idx}`,
can_edit: true,
system_dashboard: false,
project_blob_path: `${mockProjectDir}/blob/master/dashboards/.gitlab/dashboards/dashboard_${idx}.yml`,
path: `.gitlab/dashboards/dashboard_${idx}.yml`,
}));
export const dashboardGitResponse = [
{
default: true,
......@@ -527,22 +536,7 @@ export const dashboardGitResponse = [
project_blob_path: null,
path: 'config/prometheus/common_metrics.yml',
},
{
default: false,
display_name: 'Custom Dashboard 1',
can_edit: true,
system_dashboard: false,
project_blob_path: `${mockProjectDir}/blob/master/dashboards/.gitlab/dashboards/dashboard_1.yml`,
path: '.gitlab/dashboards/dashboard_1.yml',
},
{
default: false,
display_name: 'Custom Dashboard 2',
can_edit: true,
system_dashboard: false,
project_blob_path: `${mockProjectDir}/blob/master/dashboards/.gitlab/dashboards/dashboard_2.yml`,
path: '.gitlab/dashboards/dashboard_2.yml',
},
...customDashboardsData,
];
export const graphDataPrometheusQuery = {
......
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