Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
7f119dc263
commit
9ecca14b2b
|
@ -11,10 +11,12 @@ import { sortBy } from 'lodash';
|
|||
import { mapActions, mapGetters, mapState } from 'vuex';
|
||||
import boardCardInner from 'ee_else_ce/boards/mixins/board_card_inner';
|
||||
import { isScopedLabel } from '~/lib/utils/common_utils';
|
||||
import { updateHistory } from '~/lib/utils/url_utility';
|
||||
import { sprintf, __, n__ } from '~/locale';
|
||||
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue';
|
||||
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
|
||||
import { ListType } from '../constants';
|
||||
import eventHub from '../eventhub';
|
||||
import BoardBlockedIcon from './board_blocked_icon.vue';
|
||||
import IssueDueDate from './issue_due_date.vue';
|
||||
import IssueTimeEstimate from './issue_time_estimate.vue';
|
||||
|
@ -174,10 +176,19 @@ export default {
|
|||
)
|
||||
);
|
||||
},
|
||||
labelTarget(label) {
|
||||
filterByLabel(label) {
|
||||
if (!this.updateFilters) return;
|
||||
|
||||
const filterPath = window.location.search ? `${window.location.search}&` : '?';
|
||||
const value = encodeURIComponent(label.title);
|
||||
return `${filterPath}label_name[]=${value}`;
|
||||
const filter = `label_name[]=${encodeURIComponent(label.title)}`;
|
||||
|
||||
if (!filterPath.includes(filter)) {
|
||||
updateHistory({
|
||||
url: `${filterPath}${filter}`,
|
||||
});
|
||||
this.performSearch();
|
||||
eventHub.$emit('updateTokens');
|
||||
}
|
||||
},
|
||||
showScopedLabel(label) {
|
||||
return this.scopedLabelsAvailable && isScopedLabel(label);
|
||||
|
@ -232,7 +243,7 @@ export default {
|
|||
:description="label.description"
|
||||
size="sm"
|
||||
:scoped="showScopedLabel(label)"
|
||||
:target="labelTarget(label)"
|
||||
@click="filterByLabel(label)"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
import { pickBy, isEmpty, mapValues } from 'lodash';
|
||||
import { mapActions } from 'vuex';
|
||||
import { getIdFromGraphQLId, isGid } from '~/graphql_shared/utils';
|
||||
import { updateHistory, setUrlParams } from '~/lib/utils/url_utility';
|
||||
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
|
||||
import { updateHistory, setUrlParams, queryToObject } from '~/lib/utils/url_utility';
|
||||
import { __ } from '~/locale';
|
||||
import {
|
||||
FILTERED_SEARCH_TERM,
|
||||
|
@ -10,6 +11,7 @@ import {
|
|||
} from '~/vue_shared/components/filtered_search_bar/constants';
|
||||
import FilteredSearch from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
|
||||
import { AssigneeFilterType } from '~/boards/constants';
|
||||
import eventHub from '../eventhub';
|
||||
|
||||
export default {
|
||||
i18n: {
|
||||
|
@ -33,6 +35,7 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
filterParams: this.initialFilterParams,
|
||||
filteredSearchKey: 0,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -306,12 +309,21 @@ export default {
|
|||
},
|
||||
},
|
||||
created() {
|
||||
eventHub.$on('updateTokens', this.updateTokens);
|
||||
if (!isEmpty(this.eeFilters)) {
|
||||
this.filterParams = this.eeFilters;
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
eventHub.$off('updateTokens', this.updateTokens);
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['performSearch']),
|
||||
updateTokens() {
|
||||
const rawFilterParams = queryToObject(window.location.search, { gatherArrays: true });
|
||||
this.filterParams = convertObjectPropsToCamelCase(rawFilterParams, {});
|
||||
this.filteredSearchKey += 1;
|
||||
},
|
||||
handleFilter(filters) {
|
||||
this.filterParams = this.getFilterParams(filters);
|
||||
|
||||
|
@ -399,6 +411,7 @@ export default {
|
|||
|
||||
<template>
|
||||
<filtered-search
|
||||
:key="filteredSearchKey"
|
||||
class="gl-w-full"
|
||||
namespace=""
|
||||
:tokens="tokens"
|
||||
|
|
|
@ -5,12 +5,6 @@ module API
|
|||
module Internal
|
||||
class Kubernetes < ::API::Base
|
||||
feature_category :kubernetes_management
|
||||
urgency :low, [
|
||||
'/api/:version/internal/kubernetes/agent_configuration',
|
||||
'/api/:version/internal/kubernetes/agent_info',
|
||||
'/api/:version/internal/kubernetes/project_info'
|
||||
]
|
||||
|
||||
before do
|
||||
check_feature_enabled
|
||||
authenticate_gitlab_kas_request!
|
||||
|
@ -73,7 +67,7 @@ module API
|
|||
detail 'Retrieves agent info for the given token'
|
||||
end
|
||||
route_setting :authentication, cluster_agent_token_allowed: true
|
||||
get '/agent_info' do
|
||||
get '/agent_info', urgency: :low do
|
||||
project = agent.project
|
||||
|
||||
status 200
|
||||
|
@ -87,7 +81,7 @@ module API
|
|||
end
|
||||
end
|
||||
|
||||
namespace 'kubernetes/agent_configuration' do
|
||||
namespace 'kubernetes/agent_configuration', urgency: :low do
|
||||
desc 'POST agent configuration' do
|
||||
detail 'Store configuration for an agent'
|
||||
end
|
||||
|
|
|
@ -17,7 +17,7 @@ module QA
|
|||
Page::Project::Import::Github.perform do |import_page|
|
||||
import_page.add_personal_access_token(github_personal_access_token)
|
||||
import_page.import!(github_repository_path, group.full_path, name)
|
||||
import_page.wait_for_success(github_repository_path)
|
||||
import_page.wait_for_success(github_repository_path, wait: 240)
|
||||
end
|
||||
|
||||
reload!
|
||||
|
|
|
@ -36,7 +36,7 @@ module QA
|
|||
imported_project.reload! # import the project
|
||||
|
||||
expect { imported_project.project_import_status[:import_status] }.to eventually_eq('finished')
|
||||
.within(max_duration: 90, sleep_interval: 1)
|
||||
.within(max_duration: 240, sleep_interval: 1)
|
||||
|
||||
aggregate_failures do
|
||||
verify_status_data
|
||||
|
|
|
@ -46,7 +46,7 @@ module QA
|
|||
import_page.import!(github_repo, group.full_path, imported_project.name)
|
||||
|
||||
aggregate_failures do
|
||||
expect(import_page).to have_imported_project(github_repo)
|
||||
expect(import_page).to have_imported_project(github_repo, wait: 240)
|
||||
# validate button is present instead of navigating to avoid dealing with multiple tabs
|
||||
# which makes the test more complicated
|
||||
expect(import_page).to have_go_to_project_button(github_repo)
|
||||
|
|
|
@ -2,12 +2,15 @@ import { GlLabel, GlLoadingIcon, GlTooltip } from '@gitlab/ui';
|
|||
import { range } from 'lodash';
|
||||
import Vuex from 'vuex';
|
||||
import { nextTick } from 'vue';
|
||||
import setWindowLocation from 'helpers/set_window_location_helper';
|
||||
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
|
||||
import { mountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import BoardBlockedIcon from '~/boards/components/board_blocked_icon.vue';
|
||||
import BoardCardInner from '~/boards/components/board_card_inner.vue';
|
||||
import { issuableTypes } from '~/boards/constants';
|
||||
import eventHub from '~/boards/eventhub';
|
||||
import defaultStore from '~/boards/stores';
|
||||
import { updateHistory } from '~/lib/utils/url_utility';
|
||||
import { mockLabelList, mockIssue, mockIssueFullPath } from './mock_data';
|
||||
|
||||
jest.mock('~/lib/utils/url_utility');
|
||||
|
@ -34,7 +37,7 @@ describe('Board card component', () => {
|
|||
let list;
|
||||
let store;
|
||||
|
||||
const findBoardBlockedIcon = () => wrapper.find(BoardBlockedIcon);
|
||||
const findBoardBlockedIcon = () => wrapper.findComponent(BoardBlockedIcon);
|
||||
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
|
||||
const findEpicCountablesTotalTooltip = () => wrapper.findComponent(GlTooltip);
|
||||
const findEpicCountables = () => wrapper.findByTestId('epic-countables');
|
||||
|
@ -45,9 +48,14 @@ describe('Board card component', () => {
|
|||
const findEpicProgressTooltip = () => wrapper.findByTestId('epic-progress-tooltip-content');
|
||||
const findHiddenIssueIcon = () => wrapper.findByTestId('hidden-icon');
|
||||
|
||||
const performSearchMock = jest.fn();
|
||||
|
||||
const createStore = ({ isEpicBoard = false, isProjectBoard = false } = {}) => {
|
||||
store = new Vuex.Store({
|
||||
...defaultStore,
|
||||
actions: {
|
||||
performSearch: performSearchMock,
|
||||
},
|
||||
state: {
|
||||
...defaultStore.state,
|
||||
issuableType: issuableTypes.issue,
|
||||
|
@ -70,7 +78,6 @@ describe('Board card component', () => {
|
|||
...props,
|
||||
},
|
||||
stubs: {
|
||||
GlLabel: true,
|
||||
GlLoadingIcon: true,
|
||||
},
|
||||
directives: {
|
||||
|
@ -179,7 +186,7 @@ describe('Board card component', () => {
|
|||
|
||||
describe('confidential issue', () => {
|
||||
beforeEach(() => {
|
||||
wrapper.setProps({
|
||||
createWrapper({
|
||||
item: {
|
||||
...wrapper.props('item'),
|
||||
confidential: true,
|
||||
|
@ -194,7 +201,7 @@ describe('Board card component', () => {
|
|||
|
||||
describe('hidden issue', () => {
|
||||
beforeEach(() => {
|
||||
wrapper.setProps({
|
||||
createWrapper({
|
||||
item: {
|
||||
...wrapper.props('item'),
|
||||
hidden: true,
|
||||
|
@ -219,7 +226,7 @@ describe('Board card component', () => {
|
|||
describe('with assignee', () => {
|
||||
describe('with avatar', () => {
|
||||
beforeEach(() => {
|
||||
wrapper.setProps({
|
||||
createWrapper({
|
||||
item: {
|
||||
...wrapper.props('item'),
|
||||
assignees: [user],
|
||||
|
@ -272,7 +279,7 @@ describe('Board card component', () => {
|
|||
beforeEach(() => {
|
||||
global.gon.default_avatar_url = 'default_avatar';
|
||||
|
||||
wrapper.setProps({
|
||||
createWrapper({
|
||||
item: {
|
||||
...wrapper.props('item'),
|
||||
assignees: [
|
||||
|
@ -301,7 +308,7 @@ describe('Board card component', () => {
|
|||
|
||||
describe('multiple assignees', () => {
|
||||
beforeEach(() => {
|
||||
wrapper.setProps({
|
||||
createWrapper({
|
||||
item: {
|
||||
...wrapper.props('item'),
|
||||
assignees: [
|
||||
|
@ -342,7 +349,7 @@ describe('Board card component', () => {
|
|||
avatarUrl: 'test_image',
|
||||
});
|
||||
|
||||
wrapper.setProps({
|
||||
createWrapper({
|
||||
item: {
|
||||
...wrapper.props('item'),
|
||||
assignees,
|
||||
|
@ -368,7 +375,7 @@ describe('Board card component', () => {
|
|||
avatarUrl: 'test_image',
|
||||
})),
|
||||
];
|
||||
wrapper.setProps({
|
||||
createWrapper({
|
||||
item: {
|
||||
...wrapper.props('item'),
|
||||
assignees,
|
||||
|
@ -384,31 +391,74 @@ describe('Board card component', () => {
|
|||
|
||||
describe('labels', () => {
|
||||
beforeEach(() => {
|
||||
wrapper.setProps({ item: { ...issue, labels: [list.label, label1] } });
|
||||
createWrapper({ item: { ...issue, labels: [list.label, label1] } });
|
||||
});
|
||||
|
||||
it('does not render list label but renders all other labels', () => {
|
||||
expect(wrapper.findAll(GlLabel).length).toBe(1);
|
||||
const label = wrapper.find(GlLabel);
|
||||
expect(wrapper.findAllComponents(GlLabel).length).toBe(1);
|
||||
const label = wrapper.findComponent(GlLabel);
|
||||
expect(label.props('title')).toEqual(label1.title);
|
||||
expect(label.props('description')).toEqual(label1.description);
|
||||
expect(label.props('backgroundColor')).toEqual(label1.color);
|
||||
});
|
||||
|
||||
it('does not render label if label does not have an ID', async () => {
|
||||
wrapper.setProps({ item: { ...issue, labels: [label1, { title: 'closed' }] } });
|
||||
createWrapper({ item: { ...issue, labels: [label1, { title: 'closed' }] } });
|
||||
|
||||
await nextTick();
|
||||
|
||||
expect(wrapper.findAll(GlLabel).length).toBe(1);
|
||||
expect(wrapper.findAllComponents(GlLabel).length).toBe(1);
|
||||
expect(wrapper.text()).not.toContain('closed');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when label params arent set', () => {
|
||||
it('passes the right target to GlLabel', () => {
|
||||
expect(wrapper.findAll(GlLabel).at(0).props('target')).toEqual(
|
||||
'?label_name[]=testing%20123',
|
||||
);
|
||||
describe('filterByLabel method', () => {
|
||||
beforeEach(() => {
|
||||
createWrapper({
|
||||
item: {
|
||||
...issue,
|
||||
labels: [label1],
|
||||
},
|
||||
updateFilters: true,
|
||||
});
|
||||
});
|
||||
|
||||
describe('when selected label is not in the filter', () => {
|
||||
beforeEach(() => {
|
||||
setWindowLocation('?');
|
||||
wrapper.findComponent(GlLabel).vm.$emit('click', label1);
|
||||
});
|
||||
|
||||
it('calls updateHistory', () => {
|
||||
expect(updateHistory).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('dispatches performSearch vuex action', () => {
|
||||
expect(performSearchMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('emits updateTokens event', () => {
|
||||
expect(eventHub.$emit).toHaveBeenCalledTimes(1);
|
||||
expect(eventHub.$emit).toHaveBeenCalledWith('updateTokens');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when selected label is already in the filter', () => {
|
||||
beforeEach(() => {
|
||||
setWindowLocation('?label_name[]=testing%20123');
|
||||
wrapper.findComponent(GlLabel).vm.$emit('click', label1);
|
||||
});
|
||||
|
||||
it('does not call updateHistory', () => {
|
||||
expect(updateHistory).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('does not dispatch performSearch vuex action', () => {
|
||||
expect(performSearchMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('does not emit updateTokens event', () => {
|
||||
expect(eventHub.$emit).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue