Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-01-31 21:09:10 +00:00
parent 23332570c9
commit 71c16c702a
17 changed files with 140 additions and 111 deletions

View File

@ -50,6 +50,7 @@ export default {
subscription_event: this.form.find('input[name="update[subscription_event]"]').val(), subscription_event: this.form.find('input[name="update[subscription_event]"]').val(),
health_status: this.form.find('input[name="update[health_status]"]').val(), health_status: this.form.find('input[name="update[health_status]"]').val(),
epic_id: this.form.find('input[name="update[epic_id]"]').val(), epic_id: this.form.find('input[name="update[epic_id]"]').val(),
sprint_id: this.form.find('input[name="update[iteration_id]"]').val(),
add_label_ids: [], add_label_ids: [],
remove_label_ids: [], remove_label_ids: [],
}, },

View File

@ -79,6 +79,16 @@ export default class IssuableBulkUpdateSidebar {
}) })
.catch(() => {}); .catch(() => {});
} }
if (IS_EE) {
import('ee/vue_shared/components/sidebar/iterations_dropdown_bundle')
.then(({ default: iterationsDropdown }) => {
iterationsDropdown();
})
.catch((e) => {
throw e;
});
}
} }
setupBulkUpdateActions() { setupBulkUpdateActions() {

View File

@ -10,7 +10,7 @@ import initProjectPermissionsSettings from '../shared/permissions';
import initProjectDeleteButton from '~/projects/project_delete_button'; import initProjectDeleteButton from '~/projects/project_delete_button';
import UserCallout from '~/user_callout'; import UserCallout from '~/user_callout';
import initServiceDesk from '~/projects/settings_service_desk'; import initServiceDesk from '~/projects/settings_service_desk';
import mountSearchSettings from './mount_search_settings'; import initSearchSettings from '~/search_settings';
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
initFilePickers(); initFilePickers();
@ -32,5 +32,5 @@ document.addEventListener('DOMContentLoaded', () => {
), ),
); );
mountSearchSettings(); initSearchSettings();
}); });

View File

@ -1,12 +0,0 @@
const mountSearchSettings = async () => {
const el = document.querySelector('.js-search-settings-app');
if (el) {
const { default: initSearch } = await import(
/* webpackChunkName: 'search_settings' */ '~/search_settings'
);
initSearch({ el });
}
};
export default mountSearchSettings;

View File

@ -1,23 +1,10 @@
import Vue from 'vue'; const initSearch = async () => {
import $ from 'jquery'; const el = document.querySelector('.js-search-settings-app');
import { expandSection, closeSection } from '~/settings_panels';
import SearchSettings from '~/search_settings/components/search_settings.vue';
const initSearch = ({ el }) => if (el) {
new Vue({ const { default: mount } = await import(/* webpackChunkName: 'search_settings' */ './mount');
el, mount({ el });
render: (h) => }
h(SearchSettings, { };
ref: 'searchSettings',
props: {
searchRoot: document.querySelector('#content-body'),
sectionSelector: 'section.settings',
},
on: {
collapse: (section) => closeSection($(section)),
expand: (section) => expandSection($(section)),
},
}),
});
export default initSearch; export default initSearch;

View File

@ -0,0 +1,23 @@
import Vue from 'vue';
import $ from 'jquery';
import { expandSection, closeSection } from '~/settings_panels';
import SearchSettings from '~/search_settings/components/search_settings.vue';
const mountSearch = ({ el }) =>
new Vue({
el,
render: (h) =>
h(SearchSettings, {
ref: 'searchSettings',
props: {
searchRoot: document.querySelector('#content-body'),
sectionSelector: 'section.settings',
},
on: {
collapse: (section) => closeSection($(section)),
expand: (section) => expandSection($(section)),
},
}),
});
export default mountSearch;

View File

@ -1,15 +1,14 @@
- is_project_overview = local_assigns.fetch(:is_project_overview, false) - is_project_overview = local_assigns.fetch(:is_project_overview, false)
%div{ class: container_class } .nav-block.d-none.d-sm-flex.activities.gl-static
.nav-block.d-none.d-sm-flex.activities.gl-static = render 'shared/event_filter'
= render 'shared/event_filter' .controls.gl-display-flex
.controls.gl-display-flex = link_to project_path(@project, rss_url_options), title: s_("ProjectActivityRSS|Subscribe"), class: 'btn gl-button btn-default btn-icon d-none d-sm-inline-flex has-tooltip' do
= link_to project_path(@project, rss_url_options), title: s_("ProjectActivityRSS|Subscribe"), class: 'btn gl-button btn-default btn-icon d-none d-sm-inline-flex has-tooltip' do = sprite_icon('rss', css_class: 'qa-rss-icon gl-icon')
= sprite_icon('rss', css_class: 'qa-rss-icon gl-icon') - if is_project_overview && can?(current_user, :download_code, @project)
- if is_project_overview && can?(current_user, :download_code, @project) .project-clone-holder.d-none.d-md-inline-flex.gl-ml-2
.project-clone-holder.d-none.d-md-inline-flex.gl-ml-2 = render "projects/buttons/clone", dropdown_class: 'dropdown-menu-right'
= render "projects/buttons/clone", dropdown_class: 'dropdown-menu-right'
.content_list.project-activity{ :"data-href" => activity_project_path(@project) } .content_list.project-activity{ :"data-href" => activity_project_path(@project) }
.loading .loading
.spinner.spinner-md .spinner.spinner-md

View File

@ -5,7 +5,7 @@
%span.ref-name= protected_branch.name %span.ref-name= protected_branch.name
- if @project.root_ref?(protected_branch.name) - if @project.root_ref?(protected_branch.name)
%span.badge.badge-info.d-inline default %span.badge.gl-badge.badge-pill.badge-info.d-inline default
%div %div
- if protected_branch.wildcard? - if protected_branch.wildcard?
@ -20,4 +20,4 @@
- if can_admin_project - if can_admin_project
%td %td
= link_to 'Unprotect', [@project, protected_branch, { update_section: 'js-protected-branches-settings' }], disabled: local_assigns[:disabled], data: { confirm: 'Branch will be writable for developers. Are you sure?' }, method: :delete, class: "btn btn-warning" = link_to 'Unprotect', [@project, protected_branch, { update_section: 'js-protected-branches-settings' }], disabled: local_assigns[:disabled], data: { confirm: 'Branch will be writable for developers. Are you sure?' }, method: :delete, class: "btn gl-button btn-warning"

View File

@ -1,6 +1,7 @@
- type = local_assigns.fetch(:type) - type = local_assigns.fetch(:type)
- bulk_issue_health_status_flag = type == :issues && @project&.group&.feature_available?(:issuable_health_status) - bulk_issue_health_status_flag = type == :issues && @project&.group&.feature_available?(:issuable_health_status)
- epic_bulk_edit_flag = @project&.group&.feature_available?(:epics) && type == :issues - epic_bulk_edit_flag = @project&.group&.feature_available?(:epics) && type == :issues
- bulk_iterations_flag = @project.feature_available?(:iterations) && @project&.group.present? && type == :issues
%aside.issues-bulk-update.js-right-sidebar.right-sidebar{ "aria-live" => "polite", data: { 'signed-in': current_user.present? } } %aside.issues-bulk-update.js-right-sidebar.right-sidebar{ "aria-live" => "polite", data: { 'signed-in': current_user.present? } }
.issuable-sidebar.hidden .issuable-sidebar.hidden
@ -41,6 +42,8 @@
= _('Milestone') = _('Milestone')
.filter-item .filter-item
= dropdown_tag(_("Select milestone"), options: { title: _("Assign milestone"), toggle_class: "js-milestone-select js-extra-options js-filter-submit js-filter-bulk-update", filter: true, dropdown_class: "dropdown-menu-selectable dropdown-menu-milestone", placeholder: _("Search milestones"), data: { show_no: true, field_name: "update[milestone_id]", project_id: @project.id, use_id: true, default_label: _("Milestone") } }) = dropdown_tag(_("Select milestone"), options: { title: _("Assign milestone"), toggle_class: "js-milestone-select js-extra-options js-filter-submit js-filter-bulk-update", filter: true, dropdown_class: "dropdown-menu-selectable dropdown-menu-milestone", placeholder: _("Search milestones"), data: { show_no: true, field_name: "update[milestone_id]", project_id: @project.id, use_id: true, default_label: _("Milestone") } })
- if bulk_iterations_flag
= render_if_exists 'shared/iterations_dropdown', path: @project.group.full_path
.block .block
.title .title
= _('Labels') = _('Labels')

View File

@ -0,0 +1,5 @@
---
title: Apply new GitLab UI for badge and button in project's protected branch settings
merge_request: 52207
author: Yogi (@yo)
type: other

View File

@ -0,0 +1,5 @@
---
title: Remove container_class in project activity which removes extra padding
merge_request: 51878
author: Yogi (@yo)
type: fixed

View File

@ -20,19 +20,21 @@ Only the items visible on the current page are selected for bulk editing (up to
## Bulk edit issues at the group level ## Bulk edit issues at the group level
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7249) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.1. > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7249) in GitLab 12.1.
> - Assigning epic ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/210470) in GitLab 13.2.
> - Editing health status [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/218395) in GitLab 13.2.
> - Editing iteration [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196806) in GitLab 13.9.
NOTE: NOTE:
You need a permission level of [Reporter or higher](../../permissions.md) to manage issues. You need a permission level of [Reporter or higher](../../permissions.md) to manage issues.
When bulk editing issues in a group, you can edit the following attributes: When bulk editing issues in a group, you can edit the following attributes:
- Epic ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/210470) in - [Epic](../epics/index.md)
[GitLab Premium](https://about.gitlab.com/pricing/) 13.2.) **(PREMIUM)** - [Milestone](../../project/milestones/index.md)
- Milestone - [Labels](../../project/labels.md)
- Labels - [Health status](../../project/issues/index.md#health-status)
- Health status ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/218395) in - [Iteration](../iterations/index.md)
[GitLab Ultimate](https://about.gitlab.com/pricing/) 13.2.) **(ULTIMATE)**
To update multiple project issues at the same time: To update multiple project issues at the same time:

View File

@ -21,6 +21,10 @@ Only the items visible on the current page are selected for bulk editing (up to
## Bulk edit issues at the project level ## Bulk edit issues at the project level
> - Assigning epic ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/210470) in GitLab 13.2.
> - Editing health status [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/218395) in GitLab 13.2.
> - Editing iteration [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196806) in GitLab 13.9.
NOTE: NOTE:
You need a permission level of [Reporter or higher](../permissions.md) to manage issues. You need a permission level of [Reporter or higher](../permissions.md) to manage issues.
@ -28,13 +32,12 @@ When bulk editing issues in a project, you can edit the following attributes:
- Status (open/closed) - Status (open/closed)
- Assignee - Assignee
- Epic ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/210470) in - [Epic](../group/epics/index.md)
[GitLab Premium](https://about.gitlab.com/pricing/) 13.2.) **(PREMIUM)** - [Milestone](milestones/index.md)
- Milestone - [Labels](labels.md)
- Labels - [Health status](issues/index.md#health-status)
- Health status ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/218395) in - Notification subscription
[GitLab Ultimate](https://about.gitlab.com/pricing/) 13.2.) **(ULTIMATE)** - [Iteration](../group/iterations/index.md)
- Subscriptions
To update multiple project issues at the same time: To update multiple project issues at the same time:

View File

@ -25996,6 +25996,9 @@ msgstr ""
msgid "Select health status" msgid "Select health status"
msgstr "" msgstr ""
msgid "Select iteration"
msgstr ""
msgid "Select label" msgid "Select label"
msgstr "" msgstr ""

View File

@ -1,25 +0,0 @@
import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
import initSearch from '~/search_settings';
import mountSearchSettings from '~/pages/projects/edit/mount_search_settings';
jest.mock('~/search_settings');
describe('pages/projects/edit/mount_search_settings', () => {
afterEach(() => {
resetHTMLFixture();
});
it('initializes search settings when js-search-settings-app is available', async () => {
setHTMLFixture('<div class="js-search-settings-app"></div>');
await mountSearchSettings();
expect(initSearch).toHaveBeenCalled();
});
it('does not initialize search settings when js-search-settings-app is unavailable', async () => {
await mountSearchSettings();
expect(initSearch).not.toHaveBeenCalled();
});
});

View File

@ -1,36 +1,25 @@
import $ from 'jquery'; import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
import { setHTMLFixture } from 'helpers/fixtures';
import initSearch from '~/search_settings'; import initSearch from '~/search_settings';
import { expandSection, closeSection } from '~/settings_panels'; import mount from '~/search_settings/mount';
jest.mock('~/settings_panels'); jest.mock('~/search_settings/mount');
describe('search_settings/index', () => {
let app;
beforeEach(() => {
const el = document.createElement('div');
setHTMLFixture('<div id="content-body"></div>');
app = initSearch({ el });
});
describe('~/search_settings', () => {
afterEach(() => { afterEach(() => {
app.$destroy(); resetHTMLFixture();
}); });
it('calls settings_panel.onExpand when expand event is emitted', () => { it('initializes search settings when js-search-settings-app is available', async () => {
const section = { name: 'section' }; setHTMLFixture('<div class="js-search-settings-app"></div>');
app.$refs.searchSettings.$emit('expand', section);
expect(expandSection).toHaveBeenCalledWith($(section)); await initSearch();
expect(mount).toHaveBeenCalled();
}); });
it('calls settings_panel.closeSection when collapse event is emitted', () => { it('does not initialize search settings when js-search-settings-app is unavailable', async () => {
const section = { name: 'section' }; await initSearch();
app.$refs.searchSettings.$emit('collapse', section);
expect(closeSection).toHaveBeenCalledWith($(section)); expect(mount).not.toHaveBeenCalled();
}); });
}); });

View File

@ -0,0 +1,36 @@
import $ from 'jquery';
import { setHTMLFixture } from 'helpers/fixtures';
import mount from '~/search_settings/mount';
import { expandSection, closeSection } from '~/settings_panels';
jest.mock('~/settings_panels');
describe('search_settings/mount', () => {
let app;
beforeEach(() => {
const el = document.createElement('div');
setHTMLFixture('<div id="content-body"></div>');
app = mount({ el });
});
afterEach(() => {
app.$destroy();
});
it('calls settings_panel.onExpand when expand event is emitted', () => {
const section = { name: 'section' };
app.$refs.searchSettings.$emit('expand', section);
expect(expandSection).toHaveBeenCalledWith($(section));
});
it('calls settings_panel.closeSection when collapse event is emitted', () => {
const section = { name: 'section' };
app.$refs.searchSettings.$emit('collapse', section);
expect(closeSection).toHaveBeenCalledWith($(section));
});
});