Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2020-03-23 09:09:42 +00:00
parent 1635eacd2a
commit e4bf776a88
15 changed files with 117 additions and 34 deletions

View File

@ -0,0 +1,15 @@
export default () => {
const highlightLineClass = 'hll';
const contentBody = document.getElementById('content-body');
const searchTerm = contentBody.querySelector('.js-search-input').value.toLowerCase();
const blobs = contentBody.querySelectorAll('.blob-result');
blobs.forEach(blob => {
const lines = blob.querySelectorAll('.line');
lines.forEach(line => {
if (line.textContent.toLowerCase().includes(searchTerm)) {
line.classList.add(highlightLineClass);
}
});
});
};

View File

@ -5,9 +5,11 @@ import Api from '~/api';
import { __ } from '~/locale';
import Project from '~/pages/projects/project';
import refreshCounts from './refresh_counts';
import setHighlightClass from './highlight_blob_search_result';
export default class Search {
constructor() {
setHighlightClass();
const $groupDropdown = $('.js-search-group-dropdown');
const $projectDropdown = $('.js-search-project-dropdown');

View File

@ -9,7 +9,7 @@ class Admin::Serverless::DomainsController < Admin::ApplicationController
end
def create
if PagesDomain.instance_serverless.count > 0
if PagesDomain.instance_serverless.exists?
return redirect_to admin_serverless_domains_path, notice: _('An instance-level serverless domain already exists.')
end
@ -31,7 +31,7 @@ class Admin::Serverless::DomainsController < Admin::ApplicationController
end
def destroy
if domain.serverless_domain_clusters.count > 0
if domain.serverless_domain_clusters.exists?
return redirect_to admin_serverless_domains_path,
status: :conflict,
notice: _('Domain cannot be deleted while associated to one or more clusters.')

View File

@ -13,13 +13,8 @@ module Labels
new_label = clone_label_to_group_label(label)
label_ids_for_merge(new_label).find_in_batches(batch_size: BATCH_SIZE) do |batched_ids|
update_issuables(new_label, batched_ids)
update_resource_label_events(new_label, batched_ids)
update_issue_board_lists(new_label, batched_ids)
update_priorities(new_label, batched_ids)
subscribe_users(new_label, batched_ids)
# Order is important, project labels need to be last
update_project_labels(batched_ids)
update_old_label_relations(new_label, batched_ids)
destroy_project_labels(batched_ids)
end
# We skipped validations during creation. Let's run them now, after deleting conflicting labels
@ -32,6 +27,14 @@ module Labels
private
def update_old_label_relations(new_label, old_label_ids)
update_issuables(new_label, old_label_ids)
update_resource_label_events(new_label, old_label_ids)
update_issue_board_lists(new_label, old_label_ids)
update_priorities(new_label, old_label_ids)
subscribe_users(new_label, old_label_ids)
end
# rubocop: disable CodeReuse/ActiveRecord
def subscribe_users(new_label, label_ids)
# users can be subscribed to multiple labels that will be merged into the group one
@ -86,7 +89,7 @@ module Labels
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def update_project_labels(label_ids)
def destroy_project_labels(label_ids)
Label.where(id: label_ids).destroy_all # rubocop: disable DestroyAll
end
# rubocop: enable CodeReuse/ActiveRecord
@ -105,3 +108,5 @@ module Labels
end
end
end
Labels::PromoteService.prepend_if_ee('EE::Labels::PromoteService')

View File

@ -17,7 +17,7 @@
-# Populated by app/assets/javascripts/dropzone_input.js
%span.uploading-progress 0%
%span.uploading-spinner
= icon('spinner spin', class: 'toolbar-button-icon')
.toolbar-button-icon.spinner.align-text-top
%span.uploading-error-container.hide
%span.uploading-error-icon

View File

@ -0,0 +1,5 @@
---
title: Highlight line which includes search term is code search results
merge_request: 22914
author: Alex Terekhov (terales)
type: added

View File

@ -0,0 +1,5 @@
---
title: Update board scopes when promoting a label
merge_request: 27662
author:
type: fixed

View File

@ -0,0 +1,5 @@
---
title: Migrate .fa-spinner to .spinner for app/views/shared/notes
merge_request: 25028
author: nuwe1
type: other

View File

@ -2548,7 +2548,7 @@ type EpicIssue implements Noteable {
epicIssueId: ID!
"""
Current health status. Available only when feature flag `save_issuable_health_status` is enabled
Current health status. Returns null if `save_issuable_health_status` feature flag is disabled.
"""
healthStatus: HealthStatus
@ -3539,7 +3539,7 @@ type Issue implements Noteable {
epic: Epic
"""
Current health status. Available only when feature flag `save_issuable_health_status` is enabled
Current health status. Returns null if `save_issuable_health_status` feature flag is disabled.
"""
healthStatus: HealthStatus

View File

@ -7397,7 +7397,7 @@
},
{
"name": "healthStatus",
"description": "Current health status. Available only when feature flag `save_issuable_health_status` is enabled",
"description": "Current health status. Returns null if `save_issuable_health_status` feature flag is disabled.",
"args": [
],
@ -10125,7 +10125,7 @@
},
{
"name": "healthStatus",
"description": "Current health status. Available only when feature flag `save_issuable_health_status` is enabled",
"description": "Current health status. Returns null if `save_issuable_health_status` feature flag is disabled.",
"args": [
],

View File

@ -419,7 +419,7 @@ Relationship between an epic and an issue
| `dueDate` | Time | Due date of the issue |
| `epic` | Epic | Epic to which this issue belongs |
| `epicIssueId` | ID! | ID of the epic-issue relation |
| `healthStatus` | HealthStatus | Current health status. Available only when feature flag `save_issuable_health_status` is enabled |
| `healthStatus` | HealthStatus | Current health status. Returns null if `save_issuable_health_status` feature flag is disabled. |
| `id` | ID | Global ID of the epic-issue relation |
| `iid` | ID! | Internal ID of the issue |
| `milestone` | Milestone | Milestone of the issue |
@ -540,7 +540,7 @@ Autogenerated return type of EpicTreeReorder
| `downvotes` | Int! | Number of downvotes the issue has received |
| `dueDate` | Time | Due date of the issue |
| `epic` | Epic | Epic to which this issue belongs |
| `healthStatus` | HealthStatus | Current health status. Available only when feature flag `save_issuable_health_status` is enabled |
| `healthStatus` | HealthStatus | Current health status. Returns null if `save_issuable_health_status` feature flag is disabled. |
| `iid` | ID! | Internal ID of the issue |
| `milestone` | Milestone | Milestone of the issue |
| `reference` | String! | Internal reference of the issue. Returned in shortened format by default |

View File

@ -206,11 +206,11 @@ module API
conflict!('Email has already been taken') if params[:email] &&
User.by_any_email(params[:email].downcase)
.where.not(id: user.id).count > 0
.where.not(id: user.id).exists?
conflict!('Username has already been taken') if params[:username] &&
User.by_username(params[:username])
.where.not(id: user.id).count > 0
.where.not(id: user.id).exists?
user_params = declared_params(include_missing: false)

View File

@ -16,4 +16,19 @@ describe SearchController, '(JavaScript fixtures)', type: :controller do
expect(response).to be_successful
end
context 'search within a project' do
let(:namespace) { create(:namespace, name: 'frontend-fixtures') }
let(:project) { create(:project, :public, :repository, namespace: namespace, path: 'search-project') }
it 'search/blob_search_result.html' do
get :show, params: {
search: 'Send',
project_id: project.id,
scope: :blobs
}
expect(response).to be_successful
end
end
end

View File

@ -0,0 +1,15 @@
import setHighlightClass from '~/pages/search/show/highlight_blob_search_result';
const fixture = 'search/blob_search_result.html';
describe('pages/search/show/highlight_blob_search_result', () => {
preloadFixtures(fixture);
beforeEach(() => loadFixtures(fixture));
it('highlights lines with search term occurrence', () => {
setHighlightClass();
expect(document.querySelectorAll('.blob-result .hll').length).toBe(11);
});
});

View File

@ -1,8 +1,10 @@
import $ from 'jquery';
import Api from '~/api';
import Search from '~/pages/search/show/search';
import setHighlightClass from '~/pages/search/show/highlight_blob_search_result';
jest.mock('~/api');
jest.mock('~/pages/search/show/highlight_blob_search_result');
describe('Search', () => {
const fixturePath = 'search/show.html';
@ -16,27 +18,41 @@ describe('Search', () => {
preloadFixtures(fixturePath);
beforeEach(() => {
loadFixtures(fixturePath);
new Search(); // eslint-disable-line no-new
});
it('requests groups from backend when filtering', () => {
jest.spyOn(Api, 'groups').mockImplementation(term => {
expect(term).toBe(searchTerm);
describe('constructor side effects', () => {
afterEach(() => {
jest.restoreAllMocks();
});
const inputElement = fillDropdownInput('.js-search-group-dropdown');
it('highlights lines with search terms in blob search results', () => {
new Search(); // eslint-disable-line no-new
$(inputElement).trigger('input');
expect(setHighlightClass).toHaveBeenCalled();
});
});
it('requests projects from backend when filtering', () => {
jest.spyOn(Api, 'projects').mockImplementation(term => {
expect(term).toBe(searchTerm);
describe('dropdown behavior', () => {
beforeEach(() => {
loadFixtures(fixturePath);
new Search(); // eslint-disable-line no-new
});
const inputElement = fillDropdownInput('.js-search-project-dropdown');
$(inputElement).trigger('input');
it('requests groups from backend when filtering', () => {
jest.spyOn(Api, 'groups').mockImplementation(term => {
expect(term).toBe(searchTerm);
});
const inputElement = fillDropdownInput('.js-search-group-dropdown');
$(inputElement).trigger('input');
});
it('requests projects from backend when filtering', () => {
jest.spyOn(Api, 'projects').mockImplementation(term => {
expect(term).toBe(searchTerm);
});
const inputElement = fillDropdownInput('.js-search-project-dropdown');
$(inputElement).trigger('input');
});
});
});