summaryrefslogtreecommitdiff
path: root/app/assets
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-03-24 18:07:55 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-03-24 18:07:55 +0000
commit603c7d4cac5e28bc1c75e50c23ed2cbe56f1aafc (patch)
tree907f5b8ee1b6f5aad396e95e3327a08400b9e8ea /app/assets
parent120f4aaedc8fe830a3f572491d240d8ee6addefb (diff)
downloadgitlab-ce-603c7d4cac5e28bc1c75e50c23ed2cbe56f1aafc.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets')
-rw-r--r--app/assets/javascripts/api.js9
-rw-r--r--app/assets/javascripts/code_navigation/components/app.vue3
-rw-r--r--app/assets/javascripts/code_navigation/components/popover.vue13
-rw-r--r--app/assets/javascripts/code_navigation/store/actions.js9
-rw-r--r--app/assets/javascripts/code_navigation/store/mutations.js7
-rw-r--r--app/assets/javascripts/ide/components/branches/search_list.vue4
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/actions.vue4
-rw-r--r--app/assets/javascripts/ide/components/jobs/detail.vue4
-rw-r--r--app/assets/javascripts/ide/components/merge_requests/list.vue4
-rw-r--r--app/assets/javascripts/ide/components/panes/collapsible_sidebar.vue3
-rw-r--r--app/assets/javascripts/ide/components/pipelines/list.vue4
-rw-r--r--app/assets/javascripts/ide/components/preview/clientside.vue6
-rw-r--r--app/assets/javascripts/ide/index.js4
-rw-r--r--app/assets/javascripts/ide/lib/diff/controller.js2
-rw-r--r--app/assets/javascripts/ide/lib/editor.js4
-rw-r--r--app/assets/javascripts/ide/stores/actions.js4
-rw-r--r--app/assets/javascripts/ide/stores/actions/project.js6
-rw-r--r--app/assets/javascripts/ide/stores/actions/tree.js4
-rw-r--r--app/assets/javascripts/logs/components/environment_logs.vue205
-rw-r--r--app/assets/javascripts/logs/components/log_advanced_filters.vue128
-rw-r--r--app/assets/javascripts/logs/components/log_simple_filters.vue73
-rw-r--r--app/assets/javascripts/logs/stores/getters.js8
-rw-r--r--app/assets/stylesheets/pages/builds.scss22
-rw-r--r--app/assets/stylesheets/utilities.scss1
24 files changed, 310 insertions, 221 deletions
diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js
index 022d79ecf49..14381f63e4b 100644
--- a/app/assets/javascripts/api.js
+++ b/app/assets/javascripts/api.js
@@ -44,7 +44,6 @@ const Api = {
mergeRequestsPipeline: '/api/:version/projects/:id/merge_requests/:merge_request_iid/pipelines',
adminStatisticsPath: '/api/:version/application/statistics',
pipelineSinglePath: '/api/:version/projects/:id/pipelines/:pipeline_id',
- lsifPath: '/api/:version/projects/:id/commits/:commit_id/lsif/info',
environmentsPath: '/api/:version/projects/:id/environments',
group(groupId, callback) {
@@ -474,14 +473,6 @@ const Api = {
return axios.get(url);
},
- lsifData(projectPath, commitId, paths) {
- const url = Api.buildUrl(this.lsifPath)
- .replace(':id', encodeURIComponent(projectPath))
- .replace(':commit_id', commitId);
-
- return axios.get(url, { params: { paths } });
- },
-
environments(id) {
const url = Api.buildUrl(this.environmentsPath).replace(':id', encodeURIComponent(id));
return axios.get(url);
diff --git a/app/assets/javascripts/code_navigation/components/app.vue b/app/assets/javascripts/code_navigation/components/app.vue
index 0e5f1f0485d..0e0160b9832 100644
--- a/app/assets/javascripts/code_navigation/components/app.vue
+++ b/app/assets/javascripts/code_navigation/components/app.vue
@@ -7,7 +7,7 @@ export default {
Popover,
},
computed: {
- ...mapState(['currentDefinition', 'currentDefinitionPosition']),
+ ...mapState(['currentDefinition', 'currentDefinitionPosition', 'definitionPathPrefix']),
},
mounted() {
this.blobViewer = document.querySelector('.blob-viewer');
@@ -39,5 +39,6 @@ export default {
v-if="currentDefinition"
:position="currentDefinitionPosition"
:data="currentDefinition"
+ :definition-path-prefix="definitionPathPrefix"
/>
</template>
diff --git a/app/assets/javascripts/code_navigation/components/popover.vue b/app/assets/javascripts/code_navigation/components/popover.vue
index d5bbe430fcd..f216a4c6e6f 100644
--- a/app/assets/javascripts/code_navigation/components/popover.vue
+++ b/app/assets/javascripts/code_navigation/components/popover.vue
@@ -14,6 +14,10 @@ export default {
type: Object,
required: true,
},
+ definitionPathPrefix: {
+ type: String,
+ required: true,
+ },
},
data() {
return {
@@ -27,6 +31,11 @@ export default {
top: `${this.position.y + this.position.height}px`,
};
},
+ definitionPath() {
+ return (
+ this.data.definition_path && `${this.definitionPathPrefix}/${this.data.definition_path}`
+ );
+ },
},
watch: {
position: {
@@ -67,8 +76,8 @@ export default {
{{ hover.value }}
</p>
</div>
- <div v-if="data.definition_url" class="popover-body">
- <gl-button :href="data.definition_url" target="_blank" class="w-100" variant="default">
+ <div v-if="definitionPath" class="popover-body">
+ <gl-button :href="definitionPath" target="_blank" class="w-100" variant="default">
{{ __('Go to definition') }}
</gl-button>
</div>
diff --git a/app/assets/javascripts/code_navigation/store/actions.js b/app/assets/javascripts/code_navigation/store/actions.js
index 5220b1215b8..9b607023f39 100644
--- a/app/assets/javascripts/code_navigation/store/actions.js
+++ b/app/assets/javascripts/code_navigation/store/actions.js
@@ -1,4 +1,4 @@
-import api from '~/api';
+import axios from '~/lib/utils/axios_utils';
import * as types from './mutation_types';
import { getCurrentHoverElement, setCurrentHoverElement, addInteractionClass } from '../utils';
@@ -12,11 +12,10 @@ export default {
fetchData({ commit, dispatch, state }) {
commit(types.REQUEST_DATA);
- api
- .lsifData(state.projectPath, state.commitId, [state.blobPath])
+ axios
+ .get(state.codeNavUrl)
.then(({ data }) => {
- const dataForPath = data[state.blobPath];
- const normalizedData = dataForPath.reduce((acc, d) => {
+ const normalizedData = data.reduce((acc, d) => {
if (d.hover) {
acc[`${d.start_line}:${d.start_char}`] = d;
addInteractionClass(d);
diff --git a/app/assets/javascripts/code_navigation/store/mutations.js b/app/assets/javascripts/code_navigation/store/mutations.js
index bb833a5adbc..febb7afe2f8 100644
--- a/app/assets/javascripts/code_navigation/store/mutations.js
+++ b/app/assets/javascripts/code_navigation/store/mutations.js
@@ -1,10 +1,9 @@
import * as types from './mutation_types';
export default {
- [types.SET_INITIAL_DATA](state, { projectPath, commitId, blobPath }) {
- state.projectPath = projectPath;
- state.commitId = commitId;
- state.blobPath = blobPath;
+ [types.SET_INITIAL_DATA](state, { codeNavUrl, definitionPathPrefix }) {
+ state.codeNavUrl = codeNavUrl;
+ state.definitionPathPrefix = definitionPathPrefix;
},
[types.REQUEST_DATA](state) {
state.loading = true;
diff --git a/app/assets/javascripts/ide/components/branches/search_list.vue b/app/assets/javascripts/ide/components/branches/search_list.vue
index 31f1dec43ad..76821bcd986 100644
--- a/app/assets/javascripts/ide/components/branches/search_list.vue
+++ b/app/assets/javascripts/ide/components/branches/search_list.vue
@@ -1,6 +1,6 @@
<script>
import { mapActions, mapState } from 'vuex';
-import _ from 'underscore';
+import { debounce } from 'lodash';
import { GlLoadingIcon } from '@gitlab/ui';
import Icon from '~/vue_shared/components/icon.vue';
import Item from './item.vue';
@@ -39,7 +39,7 @@ export default {
loadBranches() {
this.fetchBranches({ search: this.search });
},
- searchBranches: _.debounce(function debounceSearch() {
+ searchBranches: debounce(function debounceSearch() {
this.loadBranches();
}, 250),
focusSearch() {
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/actions.vue b/app/assets/javascripts/ide/components/commit_sidebar/actions.vue
index 2581c3e9928..beff95eb47b 100644
--- a/app/assets/javascripts/ide/components/commit_sidebar/actions.vue
+++ b/app/assets/javascripts/ide/components/commit_sidebar/actions.vue
@@ -1,5 +1,5 @@
<script>
-import _ from 'underscore';
+import { escape as esc } from 'lodash';
import { mapState, mapGetters, createNamespacedHelpers } from 'vuex';
import { sprintf, s__ } from '~/locale';
import consts from '../../stores/modules/commit/constants';
@@ -22,7 +22,7 @@ export default {
commitToCurrentBranchText() {
return sprintf(
s__('IDE|Commit to %{branchName} branch'),
- { branchName: `<strong class="monospace">${_.escape(this.currentBranchId)}</strong>` },
+ { branchName: `<strong class="monospace">${esc(this.currentBranchId)}</strong>` },
false,
);
},
diff --git a/app/assets/javascripts/ide/components/jobs/detail.vue b/app/assets/javascripts/ide/components/jobs/detail.vue
index 7710bfb49ec..504391ffdc7 100644
--- a/app/assets/javascripts/ide/components/jobs/detail.vue
+++ b/app/assets/javascripts/ide/components/jobs/detail.vue
@@ -1,6 +1,6 @@
<script>
import { mapActions, mapState } from 'vuex';
-import _ from 'underscore';
+import { throttle } from 'lodash';
import { __ } from '../../../locale';
import tooltip from '../../../vue_shared/directives/tooltip';
import Icon from '../../../vue_shared/components/icon.vue';
@@ -53,7 +53,7 @@ export default {
this.$refs.buildTrace.scrollTo(0, 0);
}
},
- scrollBuildLog: _.throttle(function buildLogScrollDebounce() {
+ scrollBuildLog: throttle(function buildLogScrollDebounce() {
const { scrollTop } = this.$refs.buildTrace;
const { offsetHeight, scrollHeight } = this.$refs.buildTrace;
diff --git a/app/assets/javascripts/ide/components/merge_requests/list.vue b/app/assets/javascripts/ide/components/merge_requests/list.vue
index 5a8face062b..15c08988977 100644
--- a/app/assets/javascripts/ide/components/merge_requests/list.vue
+++ b/app/assets/javascripts/ide/components/merge_requests/list.vue
@@ -1,6 +1,6 @@
<script>
import { mapActions, mapState } from 'vuex';
-import _ from 'underscore';
+import { debounce } from 'lodash';
import { GlLoadingIcon } from '@gitlab/ui';
import { __ } from '~/locale';
import Icon from '~/vue_shared/components/icon.vue';
@@ -59,7 +59,7 @@ export default {
loadMergeRequests() {
this.fetchMergeRequests({ type: this.type, search: this.search });
},
- searchMergeRequests: _.debounce(function debounceSearch() {
+ searchMergeRequests: debounce(function debounceSearch() {
this.loadMergeRequests();
}, 250),
onSearchFocus() {
diff --git a/app/assets/javascripts/ide/components/panes/collapsible_sidebar.vue b/app/assets/javascripts/ide/components/panes/collapsible_sidebar.vue
index 7f65d089148..8adf0122fb4 100644
--- a/app/assets/javascripts/ide/components/panes/collapsible_sidebar.vue
+++ b/app/assets/javascripts/ide/components/panes/collapsible_sidebar.vue
@@ -1,6 +1,5 @@
<script>
import { mapActions, mapState } from 'vuex';
-import _ from 'underscore';
import tooltip from '~/vue_shared/directives/tooltip';
import Icon from '~/vue_shared/components/icon.vue';
import ResizablePanel from '../resizable_panel.vue';
@@ -55,7 +54,7 @@ export default {
return this.extensionTabs.filter(tab => tab.show);
},
tabViews() {
- return _.flatten(this.tabs.map(tab => tab.views));
+ return this.tabs.map(tab => tab.views).flat();
},
aliveTabViews() {
return this.tabViews.filter(view => this.isAliveView(view.name));
diff --git a/app/assets/javascripts/ide/components/pipelines/list.vue b/app/assets/javascripts/ide/components/pipelines/list.vue
index 3a63fc32639..343b0b6e90c 100644
--- a/app/assets/javascripts/ide/components/pipelines/list.vue
+++ b/app/assets/javascripts/ide/components/pipelines/list.vue
@@ -1,6 +1,6 @@
<script>
import { mapActions, mapGetters, mapState } from 'vuex';
-import _ from 'underscore';
+import { escape as esc } from 'lodash';
import { GlLoadingIcon } from '@gitlab/ui';
import { sprintf, __ } from '../../../locale';
import Icon from '../../../vue_shared/components/icon.vue';
@@ -35,7 +35,7 @@ export default {
return sprintf(
__('You can test your .gitlab-ci.yml in %{linkStart}CI Lint%{linkEnd}.'),
{
- linkStart: `<a href="${_.escape(this.currentProject.web_url)}/-/ci/lint">`,
+ linkStart: `<a href="${esc(this.currentProject.web_url)}/-/ci/lint">`,
linkEnd: '</a>',
},
false,
diff --git a/app/assets/javascripts/ide/components/preview/clientside.vue b/app/assets/javascripts/ide/components/preview/clientside.vue
index aa8d932da6e..86a773499bc 100644
--- a/app/assets/javascripts/ide/components/preview/clientside.vue
+++ b/app/assets/javascripts/ide/components/preview/clientside.vue
@@ -1,6 +1,6 @@
<script>
import { mapActions, mapGetters, mapState } from 'vuex';
-import _ from 'underscore';
+import { isEmpty } from 'lodash';
import { Manager } from 'smooshpack';
import { listen } from 'codesandbox-api';
import { GlLoadingIcon } from '@gitlab/ui';
@@ -78,7 +78,7 @@ export default {
.then(() => this.initPreview());
},
beforeDestroy() {
- if (!_.isEmpty(this.manager)) {
+ if (!isEmpty(this.manager)) {
this.manager.listener();
}
this.manager = {};
@@ -125,7 +125,7 @@ export default {
clearTimeout(this.timeout);
this.timeout = setTimeout(() => {
- if (_.isEmpty(this.manager)) {
+ if (isEmpty(this.manager)) {
this.initPreview();
return;
diff --git a/app/assets/javascripts/ide/index.js b/app/assets/javascripts/ide/index.js
index 9e9d9df8f82..55a0dd848c8 100644
--- a/app/assets/javascripts/ide/index.js
+++ b/app/assets/javascripts/ide/index.js
@@ -1,7 +1,7 @@
import Vue from 'vue';
import { mapActions } from 'vuex';
-import _ from 'underscore';
import Translate from '~/vue_shared/translate';
+import { identity } from 'lodash';
import ide from './components/ide.vue';
import store from './stores';
import router from './ide_router';
@@ -31,7 +31,7 @@ Vue.use(Translate);
export function initIde(el, options = {}) {
if (!el) return null;
- const { rootComponent = ide, extendStore = _.identity } = options;
+ const { rootComponent = ide, extendStore = identity } = options;
return new Vue({
el,
diff --git a/app/assets/javascripts/ide/lib/diff/controller.js b/app/assets/javascripts/ide/lib/diff/controller.js
index 046e562ba2b..234a7f903a1 100644
--- a/app/assets/javascripts/ide/lib/diff/controller.js
+++ b/app/assets/javascripts/ide/lib/diff/controller.js
@@ -1,5 +1,5 @@
import { Range } from 'monaco-editor';
-import { throttle } from 'underscore';
+import { throttle } from 'lodash';
import DirtyDiffWorker from './diff_worker';
import Disposable from '../common/disposable';
diff --git a/app/assets/javascripts/ide/lib/editor.js b/app/assets/javascripts/ide/lib/editor.js
index 3d729463cb4..3aff4d30d81 100644
--- a/app/assets/javascripts/ide/lib/editor.js
+++ b/app/assets/javascripts/ide/lib/editor.js
@@ -1,4 +1,4 @@
-import _ from 'underscore';
+import { debounce } from 'lodash';
import { editor as monacoEditor, KeyCode, KeyMod } from 'monaco-editor';
import store from '../stores';
import DecorationsController from './decorations/controller';
@@ -38,7 +38,7 @@ export default class Editor {
setupThemes();
- this.debouncedUpdate = _.debounce(() => {
+ this.debouncedUpdate = debounce(() => {
this.updateDimensions();
}, 200);
}
diff --git a/app/assets/javascripts/ide/stores/actions.js b/app/assets/javascripts/ide/stores/actions.js
index ddc0925efb9..04cf0ad53d5 100644
--- a/app/assets/javascripts/ide/stores/actions.js
+++ b/app/assets/javascripts/ide/stores/actions.js
@@ -1,6 +1,6 @@
import $ from 'jquery';
import Vue from 'vue';
-import _ from 'underscore';
+import { escape as esc } from 'lodash';
import { __, sprintf } from '~/locale';
import { visitUrl } from '~/lib/utils/url_utility';
import flash from '~/flash';
@@ -296,7 +296,7 @@ export const getBranchData = ({ commit, state }, { projectId, branchId, force =
sprintf(
__('Branch not loaded - %{branchId}'),
{
- branchId: `<strong>${_.escape(projectId)}/${_.escape(branchId)}</strong>`,
+ branchId: `<strong>${esc(projectId)}/${esc(branchId)}</strong>`,
},
false,
),
diff --git a/app/assets/javascripts/ide/stores/actions/project.js b/app/assets/javascripts/ide/stores/actions/project.js
index 62084892d13..0b168009847 100644
--- a/app/assets/javascripts/ide/stores/actions/project.js
+++ b/app/assets/javascripts/ide/stores/actions/project.js
@@ -1,4 +1,4 @@
-import _ from 'underscore';
+import { escape as esc } from 'lodash';
import flash from '~/flash';
import { __, sprintf } from '~/locale';
import service from '../../services';
@@ -73,7 +73,7 @@ export const showBranchNotFoundError = ({ dispatch }, branchId) => {
text: sprintf(
__("Branch %{branchName} was not found in this project's repository."),
{
- branchName: `<strong>${_.escape(branchId)}</strong>`,
+ branchName: `<strong>${esc(branchId)}</strong>`,
},
false,
),
@@ -154,7 +154,7 @@ export const openBranch = ({ dispatch, state, getters }, { projectId, branchId,
sprintf(
__('An error occurred while getting files for - %{branchId}'),
{
- branchId: `<strong>${_.escape(projectId)}/${_.escape(branchId)}</strong>`,
+ branchId: `<strong>${esc(projectId)}/${esc(branchId)}</strong>`,
},
false,
),
diff --git a/app/assets/javascripts/ide/stores/actions/tree.js b/app/assets/javascripts/ide/stores/actions/tree.js
index 828e4ed5eb9..7d48f0adc4c 100644
--- a/app/assets/javascripts/ide/stores/actions/tree.js
+++ b/app/assets/javascripts/ide/stores/actions/tree.js
@@ -1,4 +1,4 @@
-import _ from 'underscore';
+import { defer } from 'lodash';
import { __ } from '../../../locale';
import service from '../../services';
import * as types from '../mutation_types';
@@ -71,7 +71,7 @@ export const getFiles = ({ state, commit, dispatch }, payload = {}) =>
// Defer setting the directory data because this triggers some intense rendering.
// The entries is all we need to load the file editor.
- _.defer(() => dispatch('setDirectoryData', { projectId, branchId, treeList }));
+ defer(() => dispatch('setDirectoryData', { projectId, branchId, treeList }));
resolve();
})
diff --git a/app/assets/javascripts/logs/components/environment_logs.vue b/app/assets/javascripts/logs/components/environment_logs.vue
index 92d4be81c75..70b3af8dc75 100644
--- a/app/assets/javascripts/logs/components/environment_logs.vue
+++ b/app/assets/javascripts/logs/components/environment_logs.vue
@@ -7,17 +7,15 @@ import {
GlAlert,
GlDropdown,
GlDropdownHeader,
- GlDropdownDivider,
GlDropdownItem,
- GlFormGroup,
- GlSearchBoxByClick,
GlInfiniteScroll,
} from '@gitlab/ui';
-import { s__ } from '~/locale';
-import DateTimePicker from '~/vue_shared/components/date_time_picker/date_time_picker.vue';
+
+import LogSimpleFilters from './log_simple_filters.vue';
+import LogAdvancedFilters from './log_advanced_filters.vue';
import LogControlButtons from './log_control_buttons.vue';
-import { timeRanges, defaultTimeRange } from '~/vue_shared/constants';
+import { defaultTimeRange } from '~/vue_shared/constants';
import { timeRangeFromUrl } from '~/monitoring/utils';
import { formatDate } from '../utils';
@@ -28,12 +26,10 @@ export default {
GlAlert,
GlDropdown,
GlDropdownHeader,
- GlDropdownDivider,
GlDropdownItem,
- GlFormGroup,
- GlSearchBoxByClick,
GlInfiniteScroll,
- DateTimePicker,
+ LogSimpleFilters,
+ LogAdvancedFilters,
LogControlButtons,
},
filters: {
@@ -63,49 +59,22 @@ export default {
traceHeight: 600,
data() {
return {
- searchQuery: '',
- timeRanges,
isElasticStackCalloutDismissed: false,
scrollDownButtonDisabled: true,
};
},
computed: {
...mapState('environmentLogs', ['environments', 'timeRange', 'logs', 'pods']),
- ...mapGetters('environmentLogs', ['trace']),
-
- timeRangeModel: {
- get() {
- return this.timeRange.selected;
- },
- set(val) {
- this.setTimeRange(val);
- },
- },
+ ...mapGetters('environmentLogs', ['trace', 'showAdvancedFilters']),
showLoader() {
return this.logs.isLoading;
},
- advancedFeaturesEnabled() {
- const environment = this.environments.options.find(
- ({ name }) => name === this.environments.current,
- );
- return environment && environment.enable_advanced_logs_querying;
- },
- disableAdvancedControls() {
- return this.environments.isLoading || !this.advancedFeaturesEnabled;
- },
shouldShowElasticStackCallout() {
- return !this.isElasticStackCalloutDismissed && this.disableAdvancedControls;
- },
-
- podDropdownText() {
- if (this.pods.current) {
- return this.pods.current;
- } else if (this.advancedFeaturesEnabled) {
- // "All pods" is a valid option when advanced querying is available
- return s__('Environments|All pods');
- }
- return s__('Environments|No pod selected');
+ return (
+ !this.isElasticStackCalloutDismissed &&
+ (this.environments.isLoading || !this.showAdvancedFilters)
+ );
},
},
mounted() {
@@ -121,7 +90,6 @@ export default {
...mapActions('environmentLogs', [
'setInitData',
'setSearch',
- 'setTimeRange',
'showPodLogs',
'showEnvironment',
'fetchEnvironments',
@@ -131,9 +99,6 @@ export default {
isCurrentEnvironment(envName) {
return envName === this.environments.current;
},
- isCurrentPod(podName) {
- return podName === this.pods.current;
- },
topReached() {
if (!this.logs.isLoading) {
this.fetchMoreLogsPrepend();
@@ -167,123 +132,49 @@ export default {
</strong>
</a>
</gl-alert>
- <div class="top-bar js-top-bar d-flex">
- <div class="row mx-n1">
- <gl-form-group
- id="environments-dropdown-fg"
- label-size="sm"
- label-for="environments-dropdown"
- class="col-3 px-1"
+ <div class="top-bar d-md-flex border bg-secondary-50 pt-2 pr-1 pb-0 pl-2">
+ <div class="flex-grow-0">
+ <gl-dropdown
+ id="environments-dropdown"
+ :text="environments.current"
+ :disabled="environments.isLoading"
+ class="mb-2 gl-h-32 pr-2 d-flex d-md-block js-environments-dropdown"
>
- <gl-dropdown
- id="environments-dropdown"
- :text="environments.current"
- :disabled="environments.isLoading"
- 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)"
>
- <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)"
- >
- <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-size="sm"
- label-for="pods-dropdown"
- class="col-3 px-1"
- >
- <gl-dropdown
- id="pods-dropdown"
- :text="podDropdownText"
- :disabled="environments.isLoading"
- 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)">
- <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)"
- >
- <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-size="sm"
- label-for="time-window-dropdown"
- class="col-3 px-1"
- >
- <date-time-picker
- ref="dateTimePicker"
- v-model="timeRangeModel"
- class="w-100 gl-h-32"
- right
- :disabled="disableAdvancedControls"
- :options="timeRanges"
- />
- </gl-form-group>
+ <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>
</div>
+ <log-advanced-filters
+ v-if="showAdvancedFilters"
+ ref="log-advanced-filters"
+ class="d-md-flex flex-grow-1"
+ :disabled="environments.isLoading"
+ />
+ <log-simple-filters
+ v-else
+ ref="log-simple-filters"
+ class="d-md-flex flex-grow-1"
+ :disabled="environments.isLoading"
+ />
+
<log-control-buttons
ref="scrollButtons"
- class="controllers"
+ class="flex-grow-0 pr-2 mb-2 controllers"
:scroll-down-button-disabled="scrollDownButtonDisabled"
@refresh="showPodLogs(pods.current)"
@scrollDown="scrollDown"
diff --git a/app/assets/javascripts/logs/components/log_advanced_filters.vue b/app/assets/javascripts/logs/components/log_advanced_filters.vue
new file mode 100644
index 00000000000..dfbd858bf18
--- /dev/null
+++ b/app/assets/javascripts/logs/components/log_advanced_filters.vue
@@ -0,0 +1,128 @@
+<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 { timeRanges } from '~/vue_shared/constants';
+
+export default {
+ components: {
+ GlIcon,
+ GlDropdown,
+ GlDropdownHeader,
+ GlDropdownDivider,
+ GlDropdownItem,
+ GlSearchBoxByClick,
+ DateTimePicker,
+ },
+ props: {
+ disabled: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ },
+ data() {
+ return {
+ timeRanges,
+ searchQuery: '',
+ };
+ },
+ computed: {
+ ...mapState('environmentLogs', ['timeRange', 'pods']),
+
+ timeRangeModel: {
+ get() {
+ return this.timeRange.selected;
+ },
+ set(val) {
+ this.setTimeRange(val);
+ },
+ },
+
+ podDropdownText() {
+ return this.pods.current || s__('Environments|All pods');
+ },
+ },
+ methods: {
+ ...mapActions('environmentLogs', ['setSearch', 'showPodLogs', 'setTimeRange']),
+ isCurrentPod(podName) {
+ return podName === this.pods.current;
+ },
+ },
+};
+</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)"
+ />
+
+ <date-time-picker
+ ref="dateTimePicker"
+ v-model="timeRangeModel"
+ :disabled="disabled"
+ :options="timeRanges"
+ class="mb-2 gl-h-32 pr-2 d-block date-time-picker-wrapper"
+ right
+ />
+ </div>
+</template>
diff --git a/app/assets/javascripts/logs/components/log_simple_filters.vue b/app/assets/javascripts/logs/components/log_simple_filters.vue
new file mode 100644
index 00000000000..21fe1695624
--- /dev/null
+++ b/app/assets/javascripts/logs/components/log_simple_filters.vue
@@ -0,0 +1,73 @@
+<script>
+import { s__ } from '~/locale';
+import { mapActions, mapState } from 'vuex';
+import { GlIcon, GlDropdown, GlDropdownHeader, GlDropdownItem } from '@gitlab/ui';
+
+export default {
+ components: {
+ GlIcon,
+ GlDropdown,
+ GlDropdownHeader,
+ GlDropdownItem,
+ },
+ props: {
+ disabled: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ },
+ data() {
+ return {
+ searchQuery: '',
+ };
+ },
+ computed: {
+ ...mapState('environmentLogs', ['pods']),
+
+ podDropdownText() {
+ return this.pods.current || s__('Environments|No pod selected');
+ },
+ },
+ methods: {
+ ...mapActions('environmentLogs', ['showPodLogs']),
+ isCurrentPod(podName) {
+ return podName === this.pods.current;
+ },
+ },
+};
+</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|Select 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>
+ <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>
+ </gl-dropdown>
+ </div>
+</template>
diff --git a/app/assets/javascripts/logs/stores/getters.js b/app/assets/javascripts/logs/stores/getters.js
index 8770306fdd6..d92969c5389 100644
--- a/app/assets/javascripts/logs/stores/getters.js
+++ b/app/assets/javascripts/logs/stores/getters.js
@@ -5,5 +5,9 @@ const mapTrace = ({ timestamp = null, pod = '', message = '' }) =>
export const trace = state => state.logs.lines.map(mapTrace).join('\n');
-// prevent babel-plugin-rewire from generating an invalid default during karma tests
-export default () => {};
+export const showAdvancedFilters = state => {
+ const environment = state.environments.options.find(
+ ({ name }) => name === state.environments.current,
+ );
+ return Boolean(environment?.enable_advanced_logs_querying);
+};
diff --git a/app/assets/stylesheets/pages/builds.scss b/app/assets/stylesheets/pages/builds.scss
index 11687378e20..0ecb38a1ea7 100644
--- a/app/assets/stylesheets/pages/builds.scss
+++ b/app/assets/stylesheets/pages/builds.scss
@@ -379,25 +379,19 @@
}
.top-bar {
- @include build-trace-top-bar($gl-line-height * 3);
- position: relative;
- top: 0;
-
- .dropdown-menu-toggle {
- width: 200px;
+ .date-time-picker-wrapper,
+ .dropdown-toggle {
+ @include media-breakpoint-up(md) {
+ width: 140px;
+ }
- @include media-breakpoint-up(sm) {
- width: 300px;
+ @include media-breakpoint-up(lg) {
+ width: 160px;
}
}
.controllers {
- @include build-controllers(16px, flex-end, true, 2);
- }
-
- .refresh-control {
- @include build-controllers(16px, flex-end, true, 0);
- margin-left: 2px;
+ @include build-controllers(16px, flex-end, false, 2);
}
}
diff --git a/app/assets/stylesheets/utilities.scss b/app/assets/stylesheets/utilities.scss
index 00d738a50be..f161d76c623 100644
--- a/app/assets/stylesheets/utilities.scss
+++ b/app/assets/stylesheets/utilities.scss
@@ -43,6 +43,7 @@
.border-color-blue-300 { border-color: $blue-300; }
.border-color-default { border-color: $border-color; }
.border-bottom-color-default { border-bottom-color: $border-color; }
+.border-radius-default { border-radius: $border-radius-default; }
.box-shadow-default { box-shadow: 0 2px 4px 0 $black-transparent; }
.gl-children-ml-sm-3 > * {