Commit f996f939 authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch '207912-implementing-filtered-search-dropdown-improvement' into 'master'

Log filters: Replace "form group header" with "dropdown header"

See merge request gitlab-org/gitlab!26635
parents 99b3ee82 04889cb8
......@@ -3,8 +3,10 @@ import { throttle } from 'lodash';
import { mapActions, mapState, mapGetters } from 'vuex';
import {
GlSprintf,
GlIcon,
GlAlert,
GlDropdown,
GlDropdownHeader,
GlDropdownDivider,
GlDropdownItem,
GlFormGroup,
......@@ -22,8 +24,10 @@ import { formatDate } from '../utils';
export default {
components: {
GlSprintf,
GlIcon,
GlAlert,
GlDropdown,
GlDropdownHeader,
GlDropdownDivider,
GlDropdownItem,
GlFormGroup,
......@@ -124,6 +128,12 @@ export default {
'fetchMoreLogsPrepend',
]),
isCurrentEnvironment(envName) {
return envName === this.environments.current;
},
isCurrentPod(podName) {
return podName === this.pods.current;
},
topReached() {
if (!this.logs.isLoading) {
this.fetchMoreLogsPrepend();
......@@ -161,7 +171,6 @@ export default {
<div class="row mx-n1">
<gl-form-group
id="environments-dropdown-fg"
:label="s__('Environments|Environment')"
label-size="sm"
label-for="environments-dropdown"
class="col-3 px-1"
......@@ -173,18 +182,27 @@ export default {
class="d-flex gl-h-32 js-environments-dropdown"
toggle-class="dropdown-menu-toggle"
>
<gl-dropdown-header class="text-center">
{{ s__('Environments|Select environment') }}
</gl-dropdown-header>
<gl-dropdown-item
v-for="env in environments.options"
:key="env.id"
@click="showEnvironment(env.name)"
>
{{ env.name }}
<div class="d-flex">
<gl-icon
:class="{ invisible: !isCurrentEnvironment(env.name) }"
name="status_success_borderless"
/>
<div class="flex-grow-1">{{ env.name }}</div>
</div>
</gl-dropdown-item>
</gl-dropdown>
</gl-form-group>
<gl-form-group
id="pods-dropdown-fg"
:label="s__('Environments|Logs from')"
label-size="sm"
label-for="pods-dropdown"
class="col-3 px-1"
......@@ -196,24 +214,58 @@ export default {
class="d-flex gl-h-32 js-pods-dropdown"
toggle-class="dropdown-menu-toggle"
>
<gl-dropdown-header class="text-center">
{{ s__('Environments|Filter by pod') }}
</gl-dropdown-header>
<template v-if="advancedFeaturesEnabled">
<gl-dropdown-item key="all-pods" @click="showPodLogs(null)">
{{ s__('Environments|All pods') }}
<div class="d-flex">
<gl-icon
:class="{ invisible: !isCurrentPod(null) }"
name="status_success_borderless"
/>
<div class="flex-grow-1">{{ s__('Environments|All pods') }}</div>
</div>
</gl-dropdown-item>
<gl-dropdown-divider />
</template>
<gl-dropdown-item v-if="!pods.options.length" :disabled="true">
<span class="text-muted">
{{ s__('Environments|No pods to display') }}
</span>
</gl-dropdown-item>
<gl-dropdown-item
v-for="podName in pods.options"
:key="podName"
class="text-nowrap"
@click="showPodLogs(podName)"
>
{{ podName }}
<div class="d-flex">
<gl-icon
:class="{ invisible: !isCurrentPod(podName) }"
name="status_success_borderless"
/>
<div class="flex-grow-1">{{ podName }}</div>
</div>
</gl-dropdown-item>
</gl-dropdown>
</gl-form-group>
<gl-form-group id="search-fg" label-size="sm" label-for="search" class="col-3 px-1">
<gl-search-box-by-click
v-model.trim="searchQuery"
:disabled="disableAdvancedControls"
:placeholder="s__('Environments|Search')"
class="js-logs-search"
type="search"
autofocus
@submit="setSearch(searchQuery)"
/>
</gl-form-group>
<gl-form-group
id="dates-fg"
:label="s__('Environments|Show last')"
label-size="sm"
label-for="time-window-dropdown"
class="col-3 px-1"
......@@ -222,32 +274,16 @@ export default {
ref="dateTimePicker"
v-model="timeRangeModel"
class="w-100 gl-h-32"
right
:disabled="disableAdvancedControls"
:options="timeRanges"
/>
</gl-form-group>
<gl-form-group
id="search-fg"
:label="s__('Environments|Search')"
label-size="sm"
label-for="search"
class="col-3 px-1"
>
<gl-search-box-by-click
v-model.trim="searchQuery"
:disabled="disableAdvancedControls"
:placeholder="s__('Environments|Search')"
class="js-logs-search"
type="search"
autofocus
@submit="setSearch(searchQuery)"
/>
</gl-form-group>
</div>
<log-control-buttons
ref="scrollButtons"
class="controllers align-self-end mb-1"
class="controllers"
:scroll-down-button-disabled="scrollDownButtonDisabled"
@refresh="showPodLogs(pods.current)"
@scrollDown="scrollDown"
......
......@@ -379,7 +379,7 @@
}
.top-bar {
@include build-trace-top-bar($gl-line-height * 5);
@include build-trace-top-bar($gl-line-height * 3);
position: relative;
top: 0;
......
---
title: Improve logs dropdown with more clear labels
merge_request: 26635
author:
type: added
......@@ -50,7 +50,7 @@ describe 'Environment > Pod Logs', :js do
page.within('.js-pods-dropdown') do
find(".dropdown-menu-toggle:not([disabled])").click
dropdown_items = find(".dropdown-menu").all(".dropdown-item")
dropdown_items = find(".dropdown-menu").all(".dropdown-item:not([disabled])")
expect(dropdown_items.size).to eq(1)
dropdown_items.each_with_index do |item, i|
......
......@@ -7723,6 +7723,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
msgid "Environments|Filter by pod"
msgstr ""
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
......@@ -7735,9 +7738,6 @@ msgstr ""
msgid "Environments|Learn more about stopping environments"
msgstr ""
msgid "Environments|Logs from"
msgstr ""
msgid "Environments|Logs from %{start} to %{end}."
msgstr ""
......@@ -7753,6 +7753,9 @@ msgstr ""
msgid "Environments|No pod selected"
msgstr ""
msgid "Environments|No pods to display"
msgstr ""
msgid "Environments|Note that this action will stop the environment, but it will %{emphasisStart}not%{emphasisEnd} have an effect on any existing deployment due to no “stop environment action” being defined in the %{ciConfigLinkStart}.gitlab-ci.yml%{ciConfigLinkEnd} file."
msgstr ""
......@@ -7792,10 +7795,10 @@ msgstr ""
msgid "Environments|Search"
msgstr ""
msgid "Environments|Show all"
msgid "Environments|Select environment"
msgstr ""
msgid "Environments|Show last"
msgid "Environments|Show all"
msgstr ""
msgid "Environments|Stop"
......
import Vue from 'vue';
import { GlSprintf, GlDropdown, GlDropdownItem, GlSearchBoxByClick } from '@gitlab/ui';
import { GlSprintf, GlIcon, GlDropdown, GlDropdownItem, GlSearchBoxByClick } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import DateTimePicker from '~/vue_shared/components/date_time_picker/date_time_picker.vue';
import EnvironmentLogs from '~/logs/components/environment_logs.vue';
......@@ -45,6 +45,10 @@ describe('EnvironmentLogs', () => {
const findEnvironmentsDropdown = () => wrapper.find('.js-environments-dropdown');
const findPodsDropdown = () => wrapper.find('.js-pods-dropdown');
const findPodsDropdownItems = () =>
findPodsDropdown()
.findAll(GlDropdownItem)
.filter(itm => !itm.attributes('disabled'));
const findSearchBar = () => wrapper.find('.js-logs-search');
const findTimeRangePicker = () => wrapper.find({ ref: 'dateTimePicker' });
const findInfoAlert = () => wrapper.find('.js-elasticsearch-alert');
......@@ -179,7 +183,7 @@ describe('EnvironmentLogs', () => {
it('displays a disabled pods dropdown', () => {
expect(findPodsDropdown().attributes('disabled')).toBe('true');
expect(findPodsDropdown().findAll(GlDropdownItem).length).toBe(0);
expect(findPodsDropdownItems()).toHaveLength(0);
});
it('displays a disabled search bar', () => {
......@@ -296,8 +300,22 @@ describe('EnvironmentLogs', () => {
});
});
it('dropdown has one environment selected', () => {
const items = findEnvironmentsDropdown().findAll(GlDropdownItem);
mockEnvironments.forEach((env, i) => {
const item = items.at(i);
if (item.text() !== mockEnvName) {
expect(item.find(GlIcon).classes()).toContain('invisible');
} else {
// selected
expect(item.find(GlIcon).classes()).not.toContain('invisible');
}
});
});
it('populates pods dropdown', () => {
const items = findPodsDropdown().findAll(GlDropdownItem);
const items = findPodsDropdownItems();
expect(findPodsDropdown().props('text')).toBe(mockPodName);
expect(items.length).toBe(mockPods.length + 1);
......@@ -313,6 +331,19 @@ describe('EnvironmentLogs', () => {
expect(getInfiniteScrollAttr('fetched-items')).toBe(mockTrace.length);
});
it('dropdown has one pod selected', () => {
const items = findPodsDropdownItems();
mockPods.forEach((pod, i) => {
const item = items.at(i);
if (item.text() !== mockPodName) {
expect(item.find(GlIcon).classes()).toContain('invisible');
} else {
// selected
expect(item.find(GlIcon).classes()).not.toContain('invisible');
}
});
});
it('populates logs trace', () => {
const trace = findLogTrace();
expect(trace.text().split('\n').length).toBe(mockTrace.length);
......@@ -341,7 +372,7 @@ describe('EnvironmentLogs', () => {
});
it('pod name, trace is refreshed', () => {
const items = findPodsDropdown().findAll(GlDropdownItem);
const items = findPodsDropdownItems();
const index = 2; // any pod
expect(dispatch).not.toHaveBeenCalledWith(`${module}/showPodLogs`, expect.anything());
......
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