Commit 04889cb8 authored by Miguel Rincon's avatar Miguel Rincon

Replace form header with dropdown header in filter

To make better use of space the form group header is removed and
dropdown header is enabled in two log filter dropdowns.

Height of filter box is adjusted to match and "selected" icons are
added.
parent 4aad18a1
......@@ -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|
......
......@@ -7708,6 +7708,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 ""
......@@ -7720,9 +7723,6 @@ msgstr ""
msgid "Environments|Learn more about stopping environments"
msgstr ""
msgid "Environments|Logs from"
msgstr ""
msgid "Environments|Logs from %{start} to %{end}."
msgstr ""
......@@ -7738,6 +7738,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 ""
......@@ -7777,10 +7780,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