diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2019-12-21 03:07:40 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2019-12-21 03:07:40 +0300 |
commit | bb348db4c22bf58ac685fcd66445ac172491b302 (patch) | |
tree | aca3fcf2e361989744ddaee559b51761100472ed | |
parent | be59dd1d43332496def276c8d3e78fc82e94273a (diff) |
Add latest changes from gitlab-org/gitlab@master
16 files changed, 90 insertions, 36 deletions
diff --git a/app/assets/javascripts/error_tracking/components/error_tracking_list.vue b/app/assets/javascripts/error_tracking/components/error_tracking_list.vue index 1042029b6db..aa275d63c3f 100644 --- a/app/assets/javascripts/error_tracking/components/error_tracking_list.vue +++ b/app/assets/javascripts/error_tracking/components/error_tracking_list.vue @@ -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); diff --git a/app/assets/javascripts/error_tracking/store/list/actions.js b/app/assets/javascripts/error_tracking/store/list/actions.js index c9e882c4ed2..d96ac7f524e 100644 --- a/app/assets/javascripts/error_tracking/store/list/actions.js +++ b/app/assets/javascripts/error_tracking/store/list/actions.js @@ -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 () => {}; diff --git a/app/assets/javascripts/error_tracking/store/list/mutation_types.js b/app/assets/javascripts/error_tracking/store/list/mutation_types.js index 301984a1ee0..c3468b7eabd 100644 --- a/app/assets/javascripts/error_tracking/store/list/mutation_types.js +++ b/app/assets/javascripts/error_tracking/store/list/mutation_types.js @@ -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'; diff --git a/app/assets/javascripts/error_tracking/store/list/mutations.js b/app/assets/javascripts/error_tracking/store/list/mutations.js index 5648013bb89..dd5cde0576a 100644 --- a/app/assets/javascripts/error_tracking/store/list/mutations.js +++ b/app/assets/javascripts/error_tracking/store/list/mutations.js @@ -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; }, diff --git a/app/assets/javascripts/error_tracking/store/list/state.js b/app/assets/javascripts/error_tracking/store/list/state.js index 93dc1040fde..225a805e709 100644 --- a/app/assets/javascripts/error_tracking/store/list/state.js +++ b/app/assets/javascripts/error_tracking/store/list/state.js @@ -7,4 +7,5 @@ export default () => ({ indexPath: '', recentSearches: [], pagination: {}, + cursor: null, }); diff --git a/app/assets/javascripts/gfm_auto_complete.js b/app/assets/javascripts/gfm_auto_complete.js index e25c9d90f60..de69daf5c22 100644 --- a/app/assets/javascripts/gfm_auto_complete.js +++ b/app/assets/javascripts/gfm_auto_complete.js @@ -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, }; }); diff --git a/app/assets/stylesheets/vendors/atwho.scss b/app/assets/stylesheets/vendors/atwho.scss index ccf3824ea56..37ef52f9573 100644 --- a/app/assets/stylesheets/vendors/atwho.scss +++ b/app/assets/stylesheets/vendors/atwho.scss @@ -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; } } diff --git a/changelogs/unreleased/9215-promote-issue-to-epic-may-expose-confidential-information-warning-ne.yml b/changelogs/unreleased/9215-promote-issue-to-epic-may-expose-confidential-information-warning-ne.yml new file mode 100644 index 00000000000..08c18aeafa2 --- /dev/null +++ b/changelogs/unreleased/9215-promote-issue-to-epic-may-expose-confidential-information-warning-ne.yml @@ -0,0 +1,5 @@ +--- +title: Improve warning for Promote issue to epic +merge_request: 21158 +author: +type: changed diff --git a/doc/user/group/epics/index.md b/doc/user/group/epics/index.md index 01e277d5559..e6947431fcb 100644 --- a/doc/user/group/epics/index.md +++ b/doc/user/group/epics/index.md @@ -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: diff --git a/doc/user/packages/workflows/project_registry.md b/doc/user/packages/workflows/project_registry.md index 57befc4ecb8..d8c1c7c2861 100644 --- a/doc/user/packages/workflows/project_registry.md +++ b/doc/user/packages/workflows/project_registry.md @@ -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 diff --git a/lib/gitlab/quick_actions/command_definition.rb b/lib/gitlab/quick_actions/command_definition.rb index ebdae139315..b17a0208f95 100644 --- a/lib/gitlab/quick_actions/command_definition.rb +++ b/lib/gitlab/quick_actions/command_definition.rb @@ -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 diff --git a/lib/gitlab/quick_actions/dsl.rb b/lib/gitlab/quick_actions/dsl.rb index 5abbd377642..a2dfcc6de9a 100644 --- a/lib/gitlab/quick_actions/dsl.rb +++ b/lib/gitlab/quick_actions/dsl.rb @@ -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 diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 823c7700e93..a2e1c4eeea6 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -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] "" diff --git a/spec/frontend/error_tracking/components/error_tracking_list_spec.js b/spec/frontend/error_tracking/components/error_tracking_list_spec.js index d0893c0de01..f00ba884a6c 100644 --- a/spec/frontend/error_tracking/components/error_tracking_list_spec.js +++ b/spec/frontend/error_tracking/components/error_tracking_list_spec.js @@ -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, ); }); diff --git a/spec/frontend/error_tracking/store/list/actions_spec.js b/spec/frontend/error_tracking/store/list/actions_spec.js index 7906738f5b0..54fdde88818 100644 --- a/spec/frontend/error_tracking/store/list/actions_spec.js +++ b/spec/frontend/error_tracking/store/list/actions_spec.js @@ -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' }], + ); + }); + }); }); diff --git a/spec/javascripts/monitoring/helpers.js b/spec/javascripts/monitoring/helpers.js deleted file mode 100644 index 672e3b948c4..00000000000 --- a/spec/javascripts/monitoring/helpers.js +++ /dev/null @@ -1,8 +0,0 @@ -// eslint-disable-next-line import/prefer-default-export -export const resetStore = store => { - store.replaceState({ - showEmptyState: true, - emptyState: 'loading', - groups: [], - }); -}; |