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 { ...@@ -113,6 +113,7 @@ export default {
'sortField', 'sortField',
'recentSearches', 'recentSearches',
'pagination', 'pagination',
'cursor',
]), ]),
paginationRequired() { paginationRequired() {
return !_.isEmpty(this.pagination); return !_.isEmpty(this.pagination);
...@@ -142,6 +143,7 @@ export default { ...@@ -142,6 +143,7 @@ export default {
'clearRecentSearches', 'clearRecentSearches',
'loadRecentSearches', 'loadRecentSearches',
'setIndexPath', 'setIndexPath',
'fetchPaginatedResults',
]), ]),
setSearchText(text) { setSearchText(text) {
this.errorSearchQuery = text; this.errorSearchQuery = text;
...@@ -152,10 +154,10 @@ export default { ...@@ -152,10 +154,10 @@ export default {
}, },
goToNextPage() { goToNextPage() {
this.pageValue = this.$options.NEXT_PAGE; this.pageValue = this.$options.NEXT_PAGE;
this.startPolling(`${this.indexPath}?cursor=${this.pagination.next.cursor}`); this.fetchPaginatedResults(this.pagination.next.cursor);
}, },
goToPrevPage() { goToPrevPage() {
this.startPolling(`${this.indexPath}?cursor=${this.pagination.previous.cursor}`); this.fetchPaginatedResults(this.pagination.previous.cursor);
}, },
goToPage(page) { goToPage(page) {
window.scrollTo(0, 0); window.scrollTo(0, 0);
......
...@@ -17,12 +17,14 @@ export function startPolling({ state, commit, dispatch }) { ...@@ -17,12 +17,14 @@ export function startPolling({ state, commit, dispatch }) {
params: { params: {
search_term: state.searchQuery, search_term: state.searchQuery,
sort: state.sortField, sort: state.sortField,
cursor: state.cursor,
}, },
}, },
successCallback: ({ data }) => { successCallback: ({ data }) => {
if (!data) { if (!data) {
return; return;
} }
commit(types.SET_PAGINATION, data.pagination); commit(types.SET_PAGINATION, data.pagination);
commit(types.SET_ERRORS, data.errors); commit(types.SET_ERRORS, data.errors);
commit(types.SET_LOADING, false); commit(types.SET_LOADING, false);
...@@ -74,6 +76,7 @@ export function clearRecentSearches({ commit }) { ...@@ -74,6 +76,7 @@ export function clearRecentSearches({ commit }) {
export const searchByQuery = ({ commit, dispatch }, query) => { export const searchByQuery = ({ commit, dispatch }, query) => {
const searchQuery = query.trim(); const searchQuery = query.trim();
commit(types.SET_CURSOR, null);
commit(types.SET_SEARCH_QUERY, searchQuery); commit(types.SET_SEARCH_QUERY, searchQuery);
commit(types.ADD_RECENT_SEARCH, searchQuery); commit(types.ADD_RECENT_SEARCH, searchQuery);
dispatch('stopPolling'); dispatch('stopPolling');
...@@ -81,6 +84,7 @@ export const searchByQuery = ({ commit, dispatch }, query) => { ...@@ -81,6 +84,7 @@ export const searchByQuery = ({ commit, dispatch }, query) => {
}; };
export const sortByField = ({ commit, dispatch }, field) => { export const sortByField = ({ commit, dispatch }, field) => {
commit(types.SET_CURSOR, null);
commit(types.SET_SORT_FIELD, field); commit(types.SET_SORT_FIELD, field);
dispatch('stopPolling'); dispatch('stopPolling');
dispatch('startPolling'); dispatch('startPolling');
...@@ -90,4 +94,10 @@ export const setEndpoint = ({ commit }, endpoint) => { ...@@ -90,4 +94,10 @@ export const setEndpoint = ({ commit }, endpoint) => {
commit(types.SET_ENDPOINT, endpoint); commit(types.SET_ENDPOINT, endpoint);
}; };
export const fetchPaginatedResults = ({ commit, dispatch }, cursor) => {
commit(types.SET_CURSOR, cursor);
dispatch('stopPolling');
dispatch('startPolling');
};
export default () => {}; export default () => {};
...@@ -8,3 +8,4 @@ export const SET_PAGINATION = 'SET_PAGINATION'; ...@@ -8,3 +8,4 @@ export const SET_PAGINATION = 'SET_PAGINATION';
export const SET_ENDPOINT = 'SET_ENDPOINT'; export const SET_ENDPOINT = 'SET_ENDPOINT';
export const SET_SORT_FIELD = 'SET_SORT_FIELD'; export const SET_SORT_FIELD = 'SET_SORT_FIELD';
export const SET_SEARCH_QUERY = 'SET_SEARCH_QUERY'; export const SET_SEARCH_QUERY = 'SET_SEARCH_QUERY';
export const SET_CURSOR = 'SET_CURSOR';
...@@ -47,6 +47,9 @@ export default { ...@@ -47,6 +47,9 @@ export default {
[types.SET_PAGINATION](state, pagination) { [types.SET_PAGINATION](state, pagination) {
state.pagination = pagination; state.pagination = pagination;
}, },
[types.SET_CURSOR](state, cursor) {
state.cursor = cursor;
},
[types.SET_SORT_FIELD](state, field) { [types.SET_SORT_FIELD](state, field) {
state.sortField = field; state.sortField = field;
}, },
......
...@@ -7,4 +7,5 @@ export default () => ({ ...@@ -7,4 +7,5 @@ export default () => ({
indexPath: '', indexPath: '',
recentSearches: [], recentSearches: [],
pagination: {}, pagination: {},
cursor: null,
}); });
...@@ -107,8 +107,13 @@ class GfmAutoComplete { ...@@ -107,8 +107,13 @@ class GfmAutoComplete {
if (value.params.length > 0) { if (value.params.length > 0) {
tpl += ' <small class="params"><%- params.join(" ") %></small>'; tpl += ' <small class="params"><%- params.join(" ") %></small>';
} }
if (value.description !== '') { if (value.warning && value.icon && value.icon === 'confidential') {
tpl += '<small class="description"><i><%- description %> <%- warningText %></i></small>'; 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>'; tpl += '</li>';
...@@ -119,7 +124,6 @@ class GfmAutoComplete { ...@@ -119,7 +124,6 @@ class GfmAutoComplete {
return _.template(tpl)({ return _.template(tpl)({
...value, ...value,
className: cssClasses.join(' '), className: cssClasses.join(' '),
warningText: value.warning ? `(${value.warning})` : '',
}); });
}, },
insertTpl(value) { insertTpl(value) {
...@@ -150,6 +154,7 @@ class GfmAutoComplete { ...@@ -150,6 +154,7 @@ class GfmAutoComplete {
params: c.params, params: c.params,
description: c.description, description: c.description,
warning: c.warning, warning: c.warning,
icon: c.icon,
search, search,
}; };
}); });
......
...@@ -23,9 +23,9 @@ ...@@ -23,9 +23,9 @@
} }
.has-warning { .has-warning {
.name,
.description { .description {
color: $orange-700; color: $orange-700;
background-color: $orange-100;
} }
} }
...@@ -59,7 +59,6 @@ ...@@ -59,7 +59,6 @@
&.has-warning { &.has-warning {
color: $orange-700; 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. ...@@ -218,7 +218,9 @@ link in the issue sidebar.
If you have [permissions](../../permissions.md) to close an issue and create an 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` 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). [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: When the quick action is executed:
......
...@@ -74,7 +74,7 @@ Now you can [deploy Maven packages](../maven_repository/index.md#uploading-packa ...@@ -74,7 +74,7 @@ Now you can [deploy Maven packages](../maven_repository/index.md#uploading-packa
#### Conan #### 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, 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) 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 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 ...@@ -4,7 +4,7 @@ module Gitlab
module QuickActions module QuickActions
class CommandDefinition class CommandDefinition
attr_accessor :name, :aliases, :description, :explanation, :execution_message, 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 = {}) def initialize(name, attributes = {})
@name = name @name = name
...@@ -12,6 +12,7 @@ module Gitlab ...@@ -12,6 +12,7 @@ module Gitlab
@aliases = attributes[:aliases] || [] @aliases = attributes[:aliases] || []
@description = attributes[:description] || '' @description = attributes[:description] || ''
@warning = attributes[:warning] || '' @warning = attributes[:warning] || ''
@icon = attributes[:icon] || ''
@explanation = attributes[:explanation] || '' @explanation = attributes[:explanation] || ''
@execution_message = attributes[:execution_message] || '' @execution_message = attributes[:execution_message] || ''
@params = attributes[:params] || [] @params = attributes[:params] || []
...@@ -45,7 +46,13 @@ module Gitlab ...@@ -45,7 +46,13 @@ module Gitlab
explanation explanation
end 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 end
def execute(context, arg) def execute(context, arg)
...@@ -72,6 +79,11 @@ module Gitlab ...@@ -72,6 +79,11 @@ module Gitlab
desc = context.instance_exec(&desc) rescue '' desc = context.instance_exec(&desc) rescue ''
end end
warn = warning
if warn.respond_to?(:call)
warn = context.instance_exec(&warn) rescue ''
end
prms = params prms = params
if prms.respond_to?(:call) if prms.respond_to?(:call)
prms = Array(context.instance_exec(&prms)) rescue params prms = Array(context.instance_exec(&prms)) rescue params
...@@ -81,7 +93,8 @@ module Gitlab ...@@ -81,7 +93,8 @@ module Gitlab
name: name, name: name,
aliases: aliases, aliases: aliases,
description: desc, description: desc,
warning: warning, warning: warn,
icon: icon,
params: prms params: prms
} }
end end
......
...@@ -33,8 +33,12 @@ module Gitlab ...@@ -33,8 +33,12 @@ module Gitlab
@description = block_given? ? block : text @description = block_given? ? block : text
end end
def warning(message = '') def warning(text = '', &block)
@warning = message @warning = block_given? ? block : text
end
def icon(string = '')
@icon = string
end end
# Allows to define params for the next quick action. # Allows to define params for the next quick action.
...@@ -192,6 +196,7 @@ module Gitlab ...@@ -192,6 +196,7 @@ module Gitlab
aliases: aliases, aliases: aliases,
description: @description, description: @description,
warning: @warning, warning: @warning,
icon: @icon,
explanation: @explanation, explanation: @explanation,
execution_message: @execution_message, execution_message: @execution_message,
params: @params, params: @params,
...@@ -213,6 +218,7 @@ module Gitlab ...@@ -213,6 +218,7 @@ module Gitlab
@params = nil @params = nil
@condition_block = nil @condition_block = nil
@warning = nil @warning = nil
@icon = nil
@parse_params_block = nil @parse_params_block = nil
@types = nil @types = nil
end end
......
...@@ -14420,10 +14420,10 @@ msgstr "" ...@@ -14420,10 +14420,10 @@ msgstr ""
msgid "Promote" msgid "Promote"
msgstr "" msgstr ""
msgid "Promote issue to an epic" msgid "Promote confidential issue to a non-confidential epic"
msgstr "" msgstr ""
msgid "Promote issue to an epic." msgid "Promote issue to an epic"
msgstr "" msgstr ""
msgid "Promote these project milestones into a group milestone." msgid "Promote these project milestones into a group milestone."
...@@ -14444,6 +14444,9 @@ msgstr "" ...@@ -14444,6 +14444,9 @@ msgstr ""
msgid "PromoteMilestone|Promotion failed - %{message}" msgid "PromoteMilestone|Promotion failed - %{message}"
msgstr "" 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." msgid "Promoted issue to an epic."
msgstr "" msgstr ""
...@@ -21707,9 +21710,6 @@ msgstr "" ...@@ -21707,9 +21710,6 @@ msgstr ""
msgid "math|There was an error rendering this math block" msgid "math|There was an error rendering this math block"
msgstr "" msgstr ""
msgid "may expose confidential information"
msgstr ""
msgid "merge request" msgid "merge request"
msgid_plural "merge requests" msgid_plural "merge requests"
msgstr[0] "" msgstr[0] ""
......
...@@ -71,6 +71,7 @@ describe('ErrorTrackingList', () => { ...@@ -71,6 +71,7 @@ describe('ErrorTrackingList', () => {
setEndpoint: jest.fn(), setEndpoint: jest.fn(),
searchByQuery: jest.fn(), searchByQuery: jest.fn(),
sortByField: jest.fn(), sortByField: jest.fn(),
fetchPaginatedResults: jest.fn(),
}; };
const state = { const state = {
...@@ -305,10 +306,10 @@ describe('ErrorTrackingList', () => { ...@@ -305,10 +306,10 @@ describe('ErrorTrackingList', () => {
it('fetches the previous page of results', () => { it('fetches the previous page of results', () => {
expect(wrapper.find('.prev-page-item').attributes('aria-disabled')).toBe(undefined); expect(wrapper.find('.prev-page-item').attributes('aria-disabled')).toBe(undefined);
wrapper.vm.goToPrevPage(); wrapper.vm.goToPrevPage();
expect(actions.startPolling).toHaveBeenCalledTimes(2); expect(actions.fetchPaginatedResults).toHaveBeenCalled();
expect(actions.startPolling).toHaveBeenLastCalledWith( expect(actions.fetchPaginatedResults).toHaveBeenLastCalledWith(
expect.anything(), expect.anything(),
'/path?cursor=previousCursor', 'previousCursor',
undefined, undefined,
); );
}); });
...@@ -324,10 +325,10 @@ describe('ErrorTrackingList', () => { ...@@ -324,10 +325,10 @@ describe('ErrorTrackingList', () => {
window.scrollTo = jest.fn(); window.scrollTo = jest.fn();
findPagination().vm.$emit('input', 2); findPagination().vm.$emit('input', 2);
expect(window.scrollTo).toHaveBeenCalledWith(0, 0); expect(window.scrollTo).toHaveBeenCalledWith(0, 0);
expect(actions.startPolling).toHaveBeenCalledTimes(2); expect(actions.fetchPaginatedResults).toHaveBeenCalled();
expect(actions.startPolling).toHaveBeenLastCalledWith( expect(actions.fetchPaginatedResults).toHaveBeenLastCalledWith(
expect.anything(), expect.anything(),
'/path?cursor=nextCursor', 'nextCursor',
undefined, undefined,
); );
}); });
......
...@@ -79,6 +79,7 @@ describe('error tracking actions', () => { ...@@ -79,6 +79,7 @@ describe('error tracking actions', () => {
query, query,
{}, {},
[ [
{ type: types.SET_CURSOR, payload: null },
{ type: types.SET_SEARCH_QUERY, payload: query }, { type: types.SET_SEARCH_QUERY, payload: query },
{ type: types.ADD_RECENT_SEARCH, payload: query }, { type: types.ADD_RECENT_SEARCH, payload: query },
], ],
...@@ -93,15 +94,15 @@ describe('error tracking actions', () => { ...@@ -93,15 +94,15 @@ describe('error tracking actions', () => {
testAction( testAction(
actions.sortByField, 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' }], [{ type: 'stopPolling' }, { type: 'startPolling' }],
); );
}); });
}); });
describe('setEnpoint', () => { describe('setEndpoint', () => {
it('should set search endpoint', () => { it('should set search endpoint', () => {
const endpoint = 'https://sentry.io'; const endpoint = 'https://sentry.io';
...@@ -114,4 +115,17 @@ describe('error tracking actions', () => { ...@@ -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