Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-09-30 00:08:26 +00:00
parent 836ddfc35d
commit d210b1bee1
25 changed files with 124 additions and 71 deletions

View File

@ -1,5 +1,5 @@
export default function initLogoAnimation() {
window.addEventListener('beforeunload', () => {
document.querySelector('.tanuki-logo').classList.add('animate');
document.querySelector('.tanuki-logo')?.classList.add('animate');
});
}

View File

@ -1,7 +1,7 @@
<script>
import { GlSafeHtmlDirective as SafeHtml, GlButton, GlModal, GlModalDirective } from '@gitlab/ui';
import { escape } from 'lodash';
import createFlash from '~/flash';
import { createAlert, VARIANT_INFO } from '~/flash';
import axios from '~/lib/utils/axios_utils';
import { __, s__, sprintf } from '~/locale';
@ -85,12 +85,12 @@ Please update your Git repository remotes as soon as possible.`),
return axios
.put(this.actionUrl, putData)
.then((result) => {
createFlash({ message: result.data.message, type: 'notice' });
createAlert({ message: result.data.message, variant: VARIANT_INFO });
this.username = username;
this.isRequestPending = false;
})
.catch((error) => {
createFlash({
createAlert({
message:
error?.response?.data?.message ||
s__('Profiles|An error occurred while updating your username, please try again.'),

View File

@ -1,6 +1,6 @@
<script>
import { GlButton } from '@gitlab/ui';
import createFlash, { FLASH_TYPES } from '~/flash';
import { createAlert, VARIANT_DANGER, VARIANT_INFO } from '~/flash';
import { INTEGRATION_VIEW_CONFIGS, i18n } from '../constants';
import IntegrationView from './integration_view.vue';
@ -94,15 +94,15 @@ export default {
return;
}
updateClasses(this.bodyClasses, this.getSelectedTheme().css_class, this.selectedLayout);
const { message = this.$options.i18n.defaultSuccess, type = FLASH_TYPES.NOTICE } =
const { message = this.$options.i18n.defaultSuccess, variant = VARIANT_INFO } =
customEvent?.detail?.[0] || {};
createFlash({ message, type });
createAlert({ message, variant });
this.isSubmitEnabled = true;
},
handleError(customEvent) {
const { message = this.$options.i18n.defaultError, type = FLASH_TYPES.ALERT } =
const { message = this.$options.i18n.defaultError, variant = VARIANT_DANGER } =
customEvent?.detail?.[0] || {};
createFlash({ message, type });
createAlert({ message, variant });
this.isSubmitEnabled = true;
},
},

View File

@ -1,7 +1,7 @@
/* eslint-disable func-names */
import $ from 'jquery';
import createFlash from '~/flash';
import { createAlert } from '~/flash';
import Api from './api';
import { loadCSSFile } from './lib/utils/css_utils';
import { s__ } from './locale';
@ -67,7 +67,7 @@ const projectSelect = async () => {
},
projectsCallback,
).catch(() => {
createFlash({
createAlert({
message: s__('ProjectSelect|Something went wrong while fetching projects'),
});
});

View File

@ -1,4 +1,4 @@
import createFlash from '~/flash';
import { createAlert } from '~/flash';
import axios from '~/lib/utils/axios_utils';
import { PROJECT_BRANCHES_ERROR } from '../constants';
import * as types from './mutation_types';
@ -26,7 +26,7 @@ export const fetchBranches = ({ commit, dispatch, state }, query) => {
commit(types.RECEIVE_BRANCHES_SUCCESS, data.Branches?.length ? data.Branches : data);
})
.catch(() => {
createFlash({ message: PROJECT_BRANCHES_ERROR });
createAlert({ message: PROJECT_BRANCHES_ERROR });
});
};

View File

@ -1,6 +1,6 @@
<script>
import { GlLoadingIcon } from '@gitlab/ui';
import createFlash from '~/flash';
import { createAlert } from '~/flash';
import { __ } from '~/locale';
import {
getQueryHeaders,
@ -59,7 +59,7 @@ export default {
return project?.pipeline;
},
error() {
createFlash({ message: this.$options.i18n.linkedPipelinesFetchError });
createAlert({ message: this.$options.i18n.linkedPipelinesFetchError });
},
},
pipelineStages: {
@ -78,7 +78,7 @@ export default {
return project?.pipeline?.stages?.nodes || [];
},
error() {
createFlash({ message: this.$options.i18n.stagesFetchError });
createAlert({ message: this.$options.i18n.stagesFetchError });
},
},
},
@ -108,7 +108,7 @@ export default {
try {
this.formattedStages = formatStages(this.pipelineStages, this.stages);
} catch (error) {
createFlash({
createAlert({
message: this.$options.i18n.stageConversionError,
captureError: true,
error,

View File

@ -1,7 +1,7 @@
<script>
import { GlLoadingIcon, GlLink } from '@gitlab/ui';
import CiIcon from '~/vue_shared/components/ci_icon.vue';
import createFlash from '~/flash';
import { createAlert } from '~/flash';
import {
getQueryHeaders,
toggleQueryPollingByVisibility,
@ -44,7 +44,7 @@ export default {
return project?.pipeline?.detailedStatus || {};
},
error() {
createFlash({ message: this.$options.PIPELINE_STATUS_FETCH_ERROR });
createAlert({ message: this.$options.PIPELINE_STATUS_FETCH_ERROR });
},
},
},

View File

@ -1,5 +1,5 @@
import * as Sentry from '@sentry/browser';
import createFlash from '~/flash';
import { createAlert } from '~/flash';
import axios from '~/lib/utils/axios_utils';
import { joinPaths } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
@ -13,7 +13,7 @@ export default {
commit(types.COMMITS_AUTHORS, authors);
},
receiveAuthorsError() {
createFlash({
createAlert({
message: __('An error occurred fetching the project authors.'),
});
},

View File

@ -1,7 +1,7 @@
<script>
import { GlDropdown, GlDropdownItem, GlSearchBoxByType, GlDropdownSectionHeader } from '@gitlab/ui';
import { debounce } from 'lodash';
import createFlash from '~/flash';
import { createAlert } from '~/flash';
import axios from '~/lib/utils/axios_utils';
import { s__ } from '~/locale';
@ -76,7 +76,7 @@ export default {
this.tags = data.Tags || [];
})
.catch(() => {
createFlash({
createAlert({
message: s__(
'CompareRevisions|There was an error while searching the branch/tag list. Please try again.',
),
@ -97,7 +97,7 @@ export default {
this.tags = data.Tags || [];
})
.catch(() => {
createFlash({
createAlert({
message: s__(
'CompareRevisions|There was an error while loading the branch/tag list. Please try again.',
),

View File

@ -1,6 +1,6 @@
<script>
import { GlDropdown, GlDropdownItem, GlSearchBoxByType, GlDropdownSectionHeader } from '@gitlab/ui';
import createFlash from '~/flash';
import { createAlert } from '~/flash';
import axios from '~/lib/utils/axios_utils';
import { s__ } from '~/locale';
@ -74,7 +74,7 @@ export default {
this.tags = data.Tags || [];
})
.catch(() => {
createFlash({
createAlert({
message: `${s__(
'CompareRevisions|There was an error while updating the branch/tag list. Please try again.',
)}`,

View File

@ -2,7 +2,7 @@
import fuzzaldrinPlus from 'fuzzaldrin-plus';
import $ from 'jquery';
import createFlash from '~/flash';
import { createAlert } from '~/flash';
import { sanitize } from '~/lib/dompurify';
import axios from '~/lib/utils/axios_utils';
import { spriteIcon } from '~/lib/utils/common_utils';
@ -89,7 +89,7 @@ export default class ProjectFindFile {
this.element.find('.files-slider tr.tree-item').eq(0).addClass('selected').focus();
})
.catch(() =>
createFlash({
createAlert({
message: __('An error occurred while loading filenames'),
}),
);

View File

@ -1,8 +1,6 @@
# frozen_string_literal: true
class IdeController < ApplicationController
layout 'fullscreen'
include ClientsidePreviewCSP
include StaticObjectExternalStorageCSP
include Gitlab::Utils::StrongMemoize
@ -28,6 +26,8 @@ class IdeController < ApplicationController
Gitlab::Tracking.event(self.class.to_s, 'web_ide_views',
namespace: project&.namespace, user: current_user)
end
render layout: 'fullscreen', locals: { minimal: Feature.enabled?(:vscode_web_ide, current_user) }
end
private

View File

@ -1,11 +1,13 @@
- minimal = local_assigns.fetch(:minimal, false)
!!! 5
%html{ lang: I18n.locale, class: page_class }
= render "layouts/head"
%body{ class: "#{user_application_theme} #{user_tab_width} #{@body_class} fullscreen-layout", data: { page: body_data_page } }
= render 'peek/bar'
= header_message
= render partial: "layouts/header/default", locals: { project: @project, group: @group }
.mobile-overlay
- unless minimal
= render partial: "layouts/header/default", locals: { project: @project, group: @group }
.mobile-overlay
.hide-when-top-nav-responsive-open.gl--flex-full.gl-h-full{ class: nav ? ["layout-page", page_with_sidebar_class, "gl-mt-0!"]: '' }
- if defined?(nav) && nav
= render "layouts/nav/sidebar/#{nav}"
@ -17,5 +19,6 @@
= render "layouts/flash", flash_container_no_margin: true
.content-wrapper{ id: "content-body", class: "d-flex flex-column align-items-stretch" }
= yield
= render "layouts/nav/top_nav_responsive", class: "gl-flex-grow-1 gl-overflow-y-auto"
- unless minimal
= render "layouts/nav/top_nav_responsive", class: "gl-flex-grow-1 gl-overflow-y-auto"
= footer_message

View File

@ -5647,6 +5647,10 @@ Input type: `VulnerabilityExternalIssueLinkDestroyInput`
### `Mutation.vulnerabilityFindingDismiss`
WARNING:
**Deprecated** in 15.5.
Use VulnerabilityDismiss for vulnerabilities or SecurityFindingDismiss for pipeline findings.
Input type: `VulnerabilityFindingDismissInput`
#### Arguments

View File

@ -5,7 +5,7 @@ import { shallowMount } from '@vue/test-utils';
import createMockApollo from 'helpers/mock_apollo_helper';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import createFlash from '~/flash';
import { createAlert } from '~/flash';
import CommitBoxPipelineMiniGraph from '~/projects/commit_box/info/components/commit_box_pipeline_mini_graph.vue';
import PipelineMiniGraph from '~/pipelines/components/pipeline_mini_graph/pipeline_mini_graph.vue';
import { COMMIT_BOX_POLL_INTERVAL } from '~/projects/commit_box/info/constants';
@ -178,12 +178,12 @@ describe('Commit box pipeline mini graph', () => {
});
describe('error state', () => {
it('createFlash should show if there is an error fetching the data', async () => {
it('createAlert should show if there is an error fetching the data', async () => {
createComponent({ handler: failedHandler });
await waitForPromises();
expect(createFlash).toHaveBeenCalledWith({
expect(createAlert).toHaveBeenCalledWith({
message: 'There was a problem fetching linked pipelines.',
});
});

View File

@ -4,7 +4,7 @@ import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import createFlash from '~/flash';
import { createAlert } from '~/flash';
import CiIcon from '~/vue_shared/components/ci_icon.vue';
import CommitBoxPipelineStatus from '~/projects/commit_box/info/components/commit_box_pipeline_status.vue';
import {
@ -78,7 +78,7 @@ describe('Commit box pipeline status', () => {
expect(findStatusIcon().exists()).toBe(true);
expect(findLoadingIcon().exists()).toBe(false);
expect(createFlash).toHaveBeenCalledTimes(0);
expect(createAlert).toHaveBeenCalledTimes(0);
});
it('should link to the latest pipeline', () => {
@ -97,12 +97,12 @@ describe('Commit box pipeline status', () => {
});
describe('error state', () => {
it('createFlash should show if there is an error fetching the pipeline status', async () => {
it('createAlert should show if there is an error fetching the pipeline status', async () => {
createComponent(failedHandler);
await waitForPromises();
expect(createFlash).toHaveBeenCalledWith({
expect(createAlert).toHaveBeenCalledWith({
message: PIPELINE_STATUS_FETCH_ERROR,
});
});

View File

@ -3,7 +3,7 @@ import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import { nextTick } from 'vue';
import { TEST_HOST } from 'helpers/test_constants';
import createFlash from '~/flash';
import { createAlert } from '~/flash';
import axios from '~/lib/utils/axios_utils';
import UpdateUsername from '~/profile/account/components/update_username.vue';
@ -149,7 +149,7 @@ describe('UpdateUsername component', () => {
await expect(wrapper.vm.onConfirm()).rejects.toThrow();
expect(createFlash).toHaveBeenCalledWith({
expect(createAlert).toHaveBeenCalledWith({
message: 'Invalid username',
});
});
@ -161,7 +161,7 @@ describe('UpdateUsername component', () => {
await expect(wrapper.vm.onConfirm()).rejects.toThrow();
expect(createFlash).toHaveBeenCalledWith({
expect(createAlert).toHaveBeenCalledWith({
message: 'An error occurred while updating your username, please try again.',
});
});

View File

@ -3,7 +3,7 @@ import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import createFlash from '~/flash';
import { createAlert, VARIANT_DANGER, VARIANT_INFO } from '~/flash';
import IntegrationView from '~/profile/preferences/components/integration_view.vue';
import ProfilePreferences from '~/profile/preferences/components/profile_preferences.vue';
import { i18n } from '~/profile/preferences/constants';
@ -149,7 +149,10 @@ describe('ProfilePreferences component', () => {
const successEvent = new CustomEvent('ajax:success');
form.dispatchEvent(successEvent);
expect(createFlash).toHaveBeenCalledWith({ message: i18n.defaultSuccess, type: 'notice' });
expect(createAlert).toHaveBeenCalledWith({
message: i18n.defaultSuccess,
variant: VARIANT_INFO,
});
});
it('displays the custom success message', () => {
@ -157,14 +160,17 @@ describe('ProfilePreferences component', () => {
const successEvent = new CustomEvent('ajax:success', { detail: [{ message }] });
form.dispatchEvent(successEvent);
expect(createFlash).toHaveBeenCalledWith({ message, type: 'notice' });
expect(createAlert).toHaveBeenCalledWith({ message, variant: VARIANT_INFO });
});
it('displays the default error message', () => {
const errorEvent = new CustomEvent('ajax:error');
form.dispatchEvent(errorEvent);
expect(createFlash).toHaveBeenCalledWith({ message: i18n.defaultError, type: 'alert' });
expect(createAlert).toHaveBeenCalledWith({
message: i18n.defaultError,
variant: VARIANT_DANGER,
});
});
it('displays the custom error message', () => {
@ -172,7 +178,7 @@ describe('ProfilePreferences component', () => {
const errorEvent = new CustomEvent('ajax:error', { detail: [{ message }] });
form.dispatchEvent(errorEvent);
expect(createFlash).toHaveBeenCalledWith({ message, type: 'alert' });
expect(createAlert).toHaveBeenCalledWith({ message, variant: VARIANT_DANGER });
});
});

View File

@ -1,6 +1,6 @@
import MockAdapter from 'axios-mock-adapter';
import testAction from 'helpers/vuex_action_helper';
import createFlash from '~/flash';
import { createAlert } from '~/flash';
import axios from '~/lib/utils/axios_utils';
import { PROJECT_BRANCHES_ERROR } from '~/projects/commit/constants';
import * as actions from '~/projects/commit/store/actions';
@ -68,7 +68,7 @@ describe('Commit form modal store actions', () => {
await testAction(actions.fetchBranches, {}, state, [], [{ type: 'requestBranches' }]);
expect(createFlash).toHaveBeenCalledWith({ message: PROJECT_BRANCHES_ERROR });
expect(createAlert).toHaveBeenCalledWith({ message: PROJECT_BRANCHES_ERROR });
});
});

View File

@ -1,7 +1,7 @@
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import testAction from 'helpers/vuex_action_helper';
import createFlash from '~/flash';
import { createAlert } from '~/flash';
import actions from '~/projects/commits/store/actions';
import * as types from '~/projects/commits/store/mutation_types';
import createState from '~/projects/commits/store/state';
@ -38,8 +38,8 @@ describe('Project commits actions', () => {
const mockDispatchContext = { dispatch: () => {}, commit: () => {}, state };
actions.receiveAuthorsError(mockDispatchContext);
expect(createFlash).toHaveBeenCalledTimes(1);
expect(createFlash).toHaveBeenCalledWith({
expect(createAlert).toHaveBeenCalledTimes(1);
expect(createAlert).toHaveBeenCalledWith({
message: 'An error occurred fetching the project authors.',
});
});

View File

@ -2,7 +2,7 @@ import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import AxiosMockAdapter from 'axios-mock-adapter';
import { nextTick } from 'vue';
import createFlash from '~/flash';
import { createAlert } from '~/flash';
import axios from '~/lib/utils/axios_utils';
import RevisionDropdown from '~/projects/compare/components/revision_dropdown_legacy.vue';
@ -79,7 +79,7 @@ describe('RevisionDropdown component', () => {
axiosMock.onGet('some/invalid/path').replyOnce(404);
await wrapper.vm.fetchBranchesAndTags();
expect(createFlash).toHaveBeenCalled();
expect(createAlert).toHaveBeenCalled();
});
describe('GlDropdown component', () => {

View File

@ -2,7 +2,7 @@ import { GlDropdown, GlDropdownItem, GlSearchBoxByType } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import AxiosMockAdapter from 'axios-mock-adapter';
import { nextTick } from 'vue';
import createFlash from '~/flash';
import { createAlert } from '~/flash';
import axios from '~/lib/utils/axios_utils';
import RevisionDropdown from '~/projects/compare/components/revision_dropdown.vue';
import { revisionDropdownDefaultProps as defaultProps } from './mock_data';
@ -67,7 +67,7 @@ describe('RevisionDropdown component', () => {
createComponent();
await wrapper.vm.fetchBranchesAndTags();
expect(createFlash).toHaveBeenCalled();
expect(createAlert).toHaveBeenCalled();
});
it('makes a new request when refsProjectPath is changed', async () => {
@ -93,7 +93,7 @@ describe('RevisionDropdown component', () => {
createComponent();
await wrapper.vm.searchBranchesAndTags();
expect(createFlash).toHaveBeenCalled();
expect(createAlert).toHaveBeenCalled();
});
it('makes request with search param', async () => {

View File

@ -14,6 +14,8 @@ RSpec.describe IdeController do
let_it_be(:creator) { project.creator }
let_it_be(:other_user) { create(:user) }
let_it_be(:top_nav_partial) { 'layouts/header/_default' }
let(:user) { creator }
let(:branch) { '' }
@ -233,6 +235,25 @@ RSpec.describe IdeController do
end
end
end
# This indirectly tests that `minimal: true` was passed to the fullscreen layout
it 'does not render top nav' do
subject
expect(response).not_to render_template(top_nav_partial)
end
context 'without vscode_web_ide feature flag' do
before do
stub_feature_flags(vscode_web_ide: false)
end
it 'renders top nav' do
subject
expect(response).to render_template(top_nav_partial)
end
end
end
end
end

View File

@ -79,21 +79,18 @@ module DbCleaner
end
def force_disconnect_all_connections!
all_connection_classes.each do |connection_class|
# We use `connection_pool` to avoid going through
# Load Balancer since it does retry ops
pool = connection_class.connection_pool
cmd = <<~SQL
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE datname = current_database()
AND pid <> pg_backend_pid();
SQL
# Force disconnect https://www.cybertec-postgresql.com/en/terminating-database-connections-in-postgresql/
pool.connection.execute(<<-SQL)
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = #{pool.connection.quote(pool.db_config.database)}
AND pid != pg_backend_pid();
SQL
connection_class.connection_pool.disconnect!
Gitlab::Database::EachDatabase.each_database_connection(include_shared: false) do |connection|
connection.execute(cmd)
end
ActiveRecord::Base.clear_all_connections! # rubocop:disable Database/MultipleDatabases
end
end

View File

@ -3,6 +3,10 @@
require 'spec_helper'
RSpec.describe 'layouts/fullscreen' do
let_it_be(:template) { 'layouts/fullscreen' }
let_it_be(:top_nav_partial) { 'layouts/header/_default' }
let_it_be(:top_nav_responsive_partial) { 'layouts/nav/_top_nav_responsive' }
let_it_be(:user) { create(:user) }
before do
@ -23,6 +27,13 @@ RSpec.describe 'layouts/fullscreen' do
expect(rendered).to have_selector(".flash-container.flash-container-no-margin")
end
it 'renders top nav' do
render
expect(view).to render_template(top_nav_partial)
expect(view).to render_template(top_nav_responsive_partial)
end
it_behaves_like 'a layout which reflects the application theme setting'
describe 'sidebar' do
@ -58,4 +69,15 @@ RSpec.describe 'layouts/fullscreen' do
end
end
end
context 'when minimal is set' do
subject { render(template: template, formats: :html, locals: { minimal: true }) }
it 'does not render top nav' do
subject
expect(view).not_to render_template(top_nav_partial)
expect(view).not_to render_template(top_nav_responsive_partial)
end
end
end