Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/logs')
-rw-r--r--app/assets/javascripts/logs/components/environment_logs.vue9
-rw-r--r--app/assets/javascripts/logs/components/log_advanced_filters.vue124
-rw-r--r--app/assets/javascripts/logs/components/tokens/token_with_loading_state.vue30
-rw-r--r--app/assets/javascripts/logs/constants.js3
-rw-r--r--app/assets/javascripts/logs/stores/actions.js30
-rw-r--r--app/assets/javascripts/logs/utils.js3
6 files changed, 112 insertions, 87 deletions
diff --git a/app/assets/javascripts/logs/components/environment_logs.vue b/app/assets/javascripts/logs/components/environment_logs.vue
index 0d84798d690..838652f7210 100644
--- a/app/assets/javascripts/logs/components/environment_logs.vue
+++ b/app/assets/javascripts/logs/components/environment_logs.vue
@@ -89,10 +89,9 @@ export default {
methods: {
...mapActions('environmentLogs', [
'setInitData',
- 'setSearch',
- 'showPodLogs',
'showEnvironment',
'fetchEnvironments',
+ 'fetchLogs',
'fetchMoreLogsPrepend',
'dismissRequestEnvironmentsError',
'dismissInvalidTimeRangeWarning',
@@ -191,13 +190,13 @@ export default {
<log-advanced-filters
v-if="showAdvancedFilters"
ref="log-advanced-filters"
- class="d-md-flex flex-grow-1"
+ class="d-md-flex flex-grow-1 min-width-0"
:disabled="environments.isLoading"
/>
<log-simple-filters
v-else
ref="log-simple-filters"
- class="d-md-flex flex-grow-1"
+ class="d-md-flex flex-grow-1 min-width-0"
:disabled="environments.isLoading"
/>
@@ -205,7 +204,7 @@ export default {
ref="scrollButtons"
class="flex-grow-0 pr-2 mb-2 controllers"
:scroll-down-button-disabled="scrollDownButtonDisabled"
- @refresh="showPodLogs(pods.current)"
+ @refresh="fetchLogs()"
@scrollDown="scrollDown"
/>
</div>
diff --git a/app/assets/javascripts/logs/components/log_advanced_filters.vue b/app/assets/javascripts/logs/components/log_advanced_filters.vue
index dfbd858bf18..49bb80b3bfd 100644
--- a/app/assets/javascripts/logs/components/log_advanced_filters.vue
+++ b/app/assets/javascripts/logs/components/log_advanced_filters.vue
@@ -1,25 +1,15 @@
<script>
-import { s__ } from '~/locale';
-import DateTimePicker from '~/vue_shared/components/date_time_picker/date_time_picker.vue';
import { mapActions, mapState } from 'vuex';
-import {
- GlIcon,
- GlDropdown,
- GlDropdownHeader,
- GlDropdownDivider,
- GlDropdownItem,
- GlSearchBoxByClick,
-} from '@gitlab/ui';
+import { GlFilteredSearch } from '@gitlab/ui';
+import { __, s__ } from '~/locale';
+import DateTimePicker from '~/vue_shared/components/date_time_picker/date_time_picker.vue';
import { timeRanges } from '~/vue_shared/constants';
+import { TOKEN_TYPE_POD_NAME } from '../constants';
+import TokenWithLoadingState from './tokens/token_with_loading_state.vue';
export default {
components: {
- GlIcon,
- GlDropdown,
- GlDropdownHeader,
- GlDropdownDivider,
- GlDropdownItem,
- GlSearchBoxByClick,
+ GlFilteredSearch,
DateTimePicker,
},
props: {
@@ -32,11 +22,10 @@ export default {
data() {
return {
timeRanges,
- searchQuery: '',
};
},
computed: {
- ...mapState('environmentLogs', ['timeRange', 'pods']),
+ ...mapState('environmentLogs', ['timeRange', 'pods', 'logs']),
timeRangeModel: {
get() {
@@ -46,75 +35,56 @@ export default {
this.setTimeRange(val);
},
},
+ /**
+ * Token options.
+ *
+ * Returns null when no pods are present, so suggestions are displayed in the token
+ */
+ podOptions() {
+ if (this.pods.options.length) {
+ return this.pods.options.map(podName => ({ value: podName, title: podName }));
+ }
+ return null;
+ },
- podDropdownText() {
- return this.pods.current || s__('Environments|All pods');
+ tokens() {
+ return [
+ {
+ icon: 'pod',
+ type: TOKEN_TYPE_POD_NAME,
+ title: s__('Environments|Pod name'),
+ token: TokenWithLoadingState,
+ operators: [{ value: '=', description: __('is'), default: 'true' }],
+ unique: true,
+ options: this.podOptions,
+ loading: this.logs.isLoading,
+ noOptionsText: s__('Environments|No pods to display'),
+ },
+ ];
},
},
methods: {
- ...mapActions('environmentLogs', ['setSearch', 'showPodLogs', 'setTimeRange']),
- isCurrentPod(podName) {
- return podName === this.pods.current;
+ ...mapActions('environmentLogs', ['showFilteredLogs', 'setTimeRange']),
+
+ filteredSearchSubmit(filters) {
+ this.showFilteredLogs(filters);
},
},
};
</script>
<template>
<div>
- <gl-dropdown
- ref="podsDropdown"
- :text="podDropdownText"
- :disabled="disabled"
- class="mb-2 gl-h-32 pr-2 d-flex d-md-block flex-grow-0 qa-pods-dropdown"
- >
- <gl-dropdown-header class="text-center">
- {{ s__('Environments|Filter by pod') }}
- </gl-dropdown-header>
-
- <gl-dropdown-item v-if="!pods.options.length" disabled>
- <span ref="noPodsMsg" class="text-muted">
- {{ s__('Environments|No pods to display') }}
- </span>
- </gl-dropdown-item>
-
- <template v-else>
- <gl-dropdown-item ref="allPodsOption" key="all-pods" @click="showPodLogs(null)">
- <div class="d-flex">
- <gl-icon
- :class="{ invisible: pods.current !== null }"
- name="status_success_borderless"
- />
- <div class="flex-grow-1">{{ s__('Environments|All pods') }}</div>
- </div>
- </gl-dropdown-item>
- <gl-dropdown-divider />
- <gl-dropdown-item
- v-for="podName in pods.options"
- :key="podName"
- class="text-nowrap"
- @click="showPodLogs(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>
- </template>
- </gl-dropdown>
-
- <gl-search-box-by-click
- ref="searchBox"
- v-model.trim="searchQuery"
- :disabled="disabled"
- :placeholder="s__('Environments|Search')"
- class="mb-2 pr-2 flex-grow-1"
- type="search"
- autofocus
- @submit="setSearch(searchQuery)"
- />
+ <div class="mb-2 pr-2 flex-grow-1 min-width-0">
+ <gl-filtered-search
+ :placeholder="__('Search')"
+ :clear-button-title="__('Clear')"
+ :close-button-title="__('Close')"
+ class="gl-h-32"
+ :disabled="disabled || logs.isLoading"
+ :available-tokens="tokens"
+ @submit="filteredSearchSubmit"
+ />
+ </div>
<date-time-picker
ref="dateTimePicker"
diff --git a/app/assets/javascripts/logs/components/tokens/token_with_loading_state.vue b/app/assets/javascripts/logs/components/tokens/token_with_loading_state.vue
new file mode 100644
index 00000000000..f8ce704942b
--- /dev/null
+++ b/app/assets/javascripts/logs/components/tokens/token_with_loading_state.vue
@@ -0,0 +1,30 @@
+<script>
+import { GlFilteredSearchToken, GlLoadingIcon } from '@gitlab/ui';
+
+export default {
+ components: {
+ GlFilteredSearchToken,
+ GlLoadingIcon,
+ },
+ inheritAttrs: false,
+ props: {
+ config: {
+ type: Object,
+ required: true,
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-filtered-search-token :config="config" v-bind="{ ...$attrs }" v-on="$listeners">
+ <template #suggestions>
+ <div class="m-1">
+ <gl-loading-icon v-if="config.loading" />
+ <div v-else class="py-1 px-2 text-muted">
+ {{ config.noOptionsText }}
+ </div>
+ </div>
+ </template>
+ </gl-filtered-search-token>
+</template>
diff --git a/app/assets/javascripts/logs/constants.js b/app/assets/javascripts/logs/constants.js
new file mode 100644
index 00000000000..450b83f4827
--- /dev/null
+++ b/app/assets/javascripts/logs/constants.js
@@ -0,0 +1,3 @@
+export const dateFormatMask = 'UTC:mmm dd HH:MM:ss.l"Z"';
+
+export const TOKEN_TYPE_POD_NAME = 'TOKEN_TYPE_POD_NAME';
diff --git a/app/assets/javascripts/logs/stores/actions.js b/app/assets/javascripts/logs/stores/actions.js
index be847108a49..a86d3c775a9 100644
--- a/app/assets/javascripts/logs/stores/actions.js
+++ b/app/assets/javascripts/logs/stores/actions.js
@@ -2,6 +2,7 @@ import { backOff } from '~/lib/utils/common_utils';
import httpStatusCodes from '~/lib/utils/http_status';
import axios from '~/lib/utils/axios_utils';
import { convertToFixedRange } from '~/lib/utils/datetime_range';
+import { TOKEN_TYPE_POD_NAME } from '../constants';
import * as types from './mutation_types';
@@ -49,19 +50,42 @@ const requestLogsUntilData = ({ commit, state }) => {
return requestUntilData(logs_api_path, params);
};
+/**
+ * Converts filters emitted by the component, e.g. a filterered-search
+ * to parameters to be applied to the filters of the store
+ * @param {Array} filters - List of strings or objects to filter by.
+ * @returns {Object} - An object with `search` and `podName` keys.
+ */
+const filtersToParams = (filters = []) => {
+ // Strings become part of the `search`
+ const search = filters
+ .filter(f => typeof f === 'string')
+ .join(' ')
+ .trim();
+
+ // null podName to show all pods
+ const podName = filters.find(f => f?.type === TOKEN_TYPE_POD_NAME)?.value?.data ?? null;
+
+ return { search, podName };
+};
+
export const setInitData = ({ commit }, { timeRange, environmentName, podName }) => {
commit(types.SET_TIME_RANGE, timeRange);
commit(types.SET_PROJECT_ENVIRONMENT, environmentName);
commit(types.SET_CURRENT_POD_NAME, podName);
};
-export const showPodLogs = ({ dispatch, commit }, podName) => {
+export const showFilteredLogs = ({ dispatch, commit }, filters = []) => {
+ const { podName, search } = filtersToParams(filters);
+
commit(types.SET_CURRENT_POD_NAME, podName);
+ commit(types.SET_SEARCH, search);
+
dispatch('fetchLogs');
};
-export const setSearch = ({ dispatch, commit }, searchQuery) => {
- commit(types.SET_SEARCH, searchQuery);
+export const showPodLogs = ({ dispatch, commit }, podName) => {
+ commit(types.SET_CURRENT_POD_NAME, podName);
dispatch('fetchLogs');
};
diff --git a/app/assets/javascripts/logs/utils.js b/app/assets/javascripts/logs/utils.js
index 30213dbc130..8479eeb3b59 100644
--- a/app/assets/javascripts/logs/utils.js
+++ b/app/assets/javascripts/logs/utils.js
@@ -1,7 +1,6 @@
import { secondsToMilliseconds } from '~/lib/utils/datetime_utility';
import dateFormat from 'dateformat';
-
-const dateFormatMask = 'UTC:mmm dd HH:MM:ss.l"Z"';
+import { dateFormatMask } from './constants';
/**
* Returns a time range (`start`, `end`) where `start` is the