Commit bb348db4 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent be59dd1d
......@@ -113,6 +113,7 @@ export default {
'sortField',
'recentSearches',
'pagination',
'cursor',
]),
paginationRequired() {
return !_.isEmpty(this.pagination);
......@@ -142,6 +143,7 @@ export default {
'clearRecentSearches',
'loadRecentSearches',
'setIndexPath',
'fetchPaginatedResults',
]),
setSearchText(text) {
this.errorSearchQuery = text;
......@@ -152,10 +154,10 @@ export default {
},
goToNextPage() {
this.pageValue = this.$options.NEXT_PAGE;
this.startPolling(`${this.indexPath}?cursor=${this.pagination.next.cursor}`);
this.fetchPaginatedResults(this.pagination.next.cursor);
},
goToPrevPage() {
this.startPolling(`${this.indexPath}?cursor=${this.pagination.previous.cursor}`);
this.fetchPaginatedResults(this.pagination.previous.cursor);
},
goToPage(page) {
window.scrollTo(0, 0);
......
......@@ -17,12 +17,14 @@ export function startPolling({ state, commit, dispatch }) {
params: {
search_term: state.searchQuery,
sort: state.sortField,
cursor: state.cursor,
},
},
successCallback: ({ data }) => {
if (!data) {
return;
}
commit(types.SET_PAGINATION, data.pagination);
commit(types.SET_ERRORS, data.errors);
commit(types.SET_LOADING, false);
......@@ -74,6 +76,7 @@ export function clearRecentSearches({ commit }) {
export const searchByQuery = ({ commit, dispatch }, query) => {
const searchQuery = query.trim();
commit(types.SET_CURSOR, null);
commit(types.SET_SEARCH_QUERY, searchQuery);
commit(types.ADD_RECENT_SEARCH, searchQuery);
dispatch('stopPolling');
......@@ -81,6 +84,7 @@ export const searchByQuery = ({ commit, dispatch }, query) => {
};
export const sortByField = ({ commit, dispatch }, field) => {
commit(types.SET_CURSOR, null);
commit(types.SET_SORT_FIELD, field);
dispatch('stopPolling');
dispatch('startPolling');
......@@ -90,4 +94,10 @@ export const setEndpoint = ({ commit }, endpoint) => {
commit(types.SET_ENDPOINT, endpoint);
};
export const fetchPaginatedResults = ({ commit, dispatch }, cursor) => {
commit(types.SET_CURSOR, cursor);
dispatch('stopPolling');
dispatch('startPolling');
};
export default () => {};
......@@ -8,3 +8,4 @@ export const SET_PAGINATION = 'SET_PAGINATION';
export const SET_ENDPOINT = 'SET_ENDPOINT';
export const SET_SORT_FIELD = 'SET_SORT_FIELD';
export const SET_SEARCH_QUERY = 'SET_SEARCH_QUERY';
export const SET_CURSOR = 'SET_CURSOR';
......@@ -47,6 +47,9 @@ export default {
[types.SET_PAGINATION](state, pagination) {
state.pagination = pagination;
},
[types.SET_CURSOR](state, cursor) {
state.cursor = cursor;
},
[types.SET_SORT_FIELD](state, field) {
state.sortField = field;
},
......
......@@ -7,4 +7,5 @@ export default () => ({
indexPath: '',
recentSearches: [],
pagination: {},
cursor: null,
});
......@@ -107,8 +107,13 @@ class GfmAutoComplete {
if (value.params.length > 0) {
tpl += ' <small class="params"><%- params.join(" ") %></small>';
}
if (value.description !== '') {
tpl += '<small class="description"><i><%- description %> <%- warningText %></i></small>';
if (value.warning && value.icon && value.icon === 'confidential') {
tpl +=
'<small class="description"><em><i class="fa fa-eye-slash" aria-hidden="true"/><%- warning %></em></small>';
} else if (value.warning) {
tpl += '<small class="description"><em><%- warning %></em></small>';
} else if (value.description !== '') {
tpl += '<small class="description"><em><%- description %></em></small>';
}
tpl += '</li>';
......@@ -119,7 +124,6 @@ class GfmAutoComplete {
return _.template(tpl)({
...value,
className: cssClasses.join(' '),
warningText: value.warning ? `(${value.warning})` : '',
});
},
insertTpl(value) {
......@@ -150,6 +154,7 @@ class GfmAutoComplete {
params: c.params,
description: c.description,
warning: c.warning,
icon: c.icon,
search,
};
});
......
......@@ -23,9 +23,9 @@
}
.has-warning {
.name,
.description {
color: $orange-700;
background-color: $orange-100;
}
}
......@@ -59,7 +59,6 @@
&.has-warning {
color: $orange-700;
background-color: $orange-100;
}
}
......
---
title: Improve warning for Promote issue to epic
merge_request: 21158
author:
type: changed
......@@ -218,7 +218,9 @@ link in the issue sidebar.
If you have [permissions](../../permissions.md) to close an issue and create an
epic in the parent group, you can promote an issue to an epic with the `/promote`
[quick action](../../project/quick_actions.md#quick-actions-for-issues-merge-requests-and-epics).
Only issues from projects that are in groups can be promoted.
Only issues from projects that are in groups can be promoted. When attempting to promote a confidential
issue, a warning will display. Promoting a confidential issue to an epic will make all information
related to the issue public as epics are public to group members.
When the quick action is executed:
......
......@@ -74,7 +74,7 @@ Now you can [deploy Maven packages](../maven_repository/index.md#uploading-packa
#### Conan
For Conan, first you need to add GitLab as a Conan registry remote. Follow the instructions in the [GitLab Conan Repository docs](../conan_repository/index.md#setting-the-conan-remote-to-the-gitlab-package-registry)
For Conan, first you need to add GitLab as a Conan registry remote. Follow the instructions in the [GitLab Conan Repository docs](../conan_repository/index.md#adding-the-gitlab-package-registry-as-a-conan-remote)
to do so. Then, create your package using the plus-separated (`+`) project path as your Conan user. For example,
if your project is located at `https://gitlab.com/foo/bar/my-proj`, then you can [create your Conan package](../conan_repository/index.md)
using `conan create . foo+bar+my-proj/channel`, where `channel` is your package channel (`stable`, `beta`, etc.). Once your package
......
......@@ -4,7 +4,7 @@ module Gitlab
module QuickActions
class CommandDefinition
attr_accessor :name, :aliases, :description, :explanation, :execution_message,
:params, :condition_block, :parse_params_block, :action_block, :warning, :types
:params, :condition_block, :parse_params_block, :action_block, :warning, :icon, :types
def initialize(name, attributes = {})
@name = name
......@@ -12,6 +12,7 @@ module Gitlab
@aliases = attributes[:aliases] || []
@description = attributes[:description] || ''
@warning = attributes[:warning] || ''
@icon = attributes[:icon] || ''
@explanation = attributes[:explanation] || ''
@execution_message = attributes[:execution_message] || ''
@params = attributes[:params] || []
......@@ -45,7 +46,13 @@ module Gitlab
explanation
end
warning.empty? ? message : "#{message} (#{warning})"
warning_text = if warning.respond_to?(:call)
execute_block(warning, context, arg)
else
warning
end
warning.empty? ? message : "#{message} (#{warning_text})"
end
def execute(context, arg)
......@@ -72,6 +79,11 @@ module Gitlab
desc = context.instance_exec(&desc) rescue ''
end
warn = warning
if warn.respond_to?(:call)
warn = context.instance_exec(&warn) rescue ''
end
prms = params
if prms.respond_to?(:call)
prms = Array(context.instance_exec(&prms)) rescue params
......@@ -81,7 +93,8 @@ module Gitlab
name: name,
aliases: aliases,
description: desc,
warning: warning,
warning: warn,
icon: icon,
params: prms
}
end
......
......@@ -33,8 +33,12 @@ module Gitlab
@description = block_given? ? block : text
end
def warning(message = '')
@warning = message
def warning(text = '', &block)
@warning = block_given? ? block : text
end
def icon(string = '')
@icon = string
end
# Allows to define params for the next quick action.
......@@ -192,6 +196,7 @@ module Gitlab
aliases: aliases,
description: @description,
warning: @warning,
icon: @icon,
explanation: @explanation,
execution_message: @execution_message,
params: @params,
......@@ -213,6 +218,7 @@ module Gitlab
@params = nil
@condition_block = nil
@warning = nil
@icon = nil
@parse_params_block = nil
@types = nil
end
......
......@@ -14420,10 +14420,10 @@ msgstr ""
msgid "Promote"
msgstr ""
msgid "Promote issue to an epic"
msgid "Promote confidential issue to a non-confidential epic"
msgstr ""
msgid "Promote issue to an epic."
msgid "Promote issue to an epic"
msgstr ""
msgid "Promote these project milestones into a group milestone."
......@@ -14444,6 +14444,9 @@ msgstr ""
msgid "PromoteMilestone|Promotion failed - %{message}"
msgstr ""
msgid "Promoted confidential issue to a non-confidential epic. Information in this issue is no longer confidential as epics are public to group members."
msgstr ""
msgid "Promoted issue to an epic."
msgstr ""
......@@ -21707,9 +21710,6 @@ msgstr ""
msgid "math|There was an error rendering this math block"
msgstr ""
msgid "may expose confidential information"
msgstr ""
msgid "merge request"
msgid_plural "merge requests"
msgstr[0] ""
......
......@@ -71,6 +71,7 @@ describe('ErrorTrackingList', () => {
setEndpoint: jest.fn(),
searchByQuery: jest.fn(),
sortByField: jest.fn(),
fetchPaginatedResults: jest.fn(),
};
const state = {
......@@ -305,10 +306,10 @@ describe('ErrorTrackingList', () => {
it('fetches the previous page of results', () => {
expect(wrapper.find('.prev-page-item').attributes('aria-disabled')).toBe(undefined);
wrapper.vm.goToPrevPage();
expect(actions.startPolling).toHaveBeenCalledTimes(2);
expect(actions.startPolling).toHaveBeenLastCalledWith(
expect(actions.fetchPaginatedResults).toHaveBeenCalled();
expect(actions.fetchPaginatedResults).toHaveBeenLastCalledWith(
expect.anything(),
'/path?cursor=previousCursor',
'previousCursor',
undefined,
);
});
......@@ -324,10 +325,10 @@ describe('ErrorTrackingList', () => {
window.scrollTo = jest.fn();
findPagination().vm.$emit('input', 2);
expect(window.scrollTo).toHaveBeenCalledWith(0, 0);
expect(actions.startPolling).toHaveBeenCalledTimes(2);
expect(actions.startPolling).toHaveBeenLastCalledWith(
expect(actions.fetchPaginatedResults).toHaveBeenCalled();
expect(actions.fetchPaginatedResults).toHaveBeenLastCalledWith(
expect.anything(),
'/path?cursor=nextCursor',
'nextCursor',
undefined,
);
});
......
......@@ -79,6 +79,7 @@ describe('error tracking actions', () => {
query,
{},
[
{ type: types.SET_CURSOR, payload: null },
{ type: types.SET_SEARCH_QUERY, payload: query },
{ type: types.ADD_RECENT_SEARCH, payload: query },
],
......@@ -93,15 +94,15 @@ describe('error tracking actions', () => {
testAction(
actions.sortByField,
{ field },
field,
{},
[{ type: types.SET_SORT_FIELD, payload: { field } }],
[{ type: types.SET_CURSOR, payload: null }, { type: types.SET_SORT_FIELD, payload: field }],
[{ type: 'stopPolling' }, { type: 'startPolling' }],
);
});
});
describe('setEnpoint', () => {
describe('setEndpoint', () => {
it('should set search endpoint', () => {
const endpoint = 'https://sentry.io';
......@@ -114,4 +115,17 @@ describe('error tracking actions', () => {
);
});
});
describe('fetchPaginatedResults', () => {
it('should start polling the selected page cursor', () => {
const cursor = '1576637570000:1:1';
testAction(
actions.fetchPaginatedResults,
cursor,
{},
[{ type: types.SET_CURSOR, payload: cursor }],
[{ type: 'stopPolling' }, { type: 'startPolling' }],
);
});
});
});
// eslint-disable-next-line import/prefer-default-export
export const resetStore = store => {
store.replaceState({
showEmptyState: true,
emptyState: 'loading',
groups: [],
});
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment