-
+
{{ __('There are no variables yet.') }}
{{ __('Add variable') }}
{{ valuesButtonText }}
@@ -103,77 +102,31 @@ export default {
directives: {
GlTooltip: GlTooltipDirective,
},
- inject: {
- autocompleteAwardEmojisPath: {
- default: '',
- },
- calendarPath: {
- default: '',
- },
- canBulkUpdate: {
- default: false,
- },
- emptyStateSvgPath: {
- default: '',
- },
- exportCsvPath: {
- default: '',
- },
- fullPath: {
- default: '',
- },
- hasAnyIssues: {
- default: false,
- },
- hasAnyProjects: {
- default: false,
- },
- hasBlockedIssuesFeature: {
- default: false,
- },
- hasIssueWeightsFeature: {
- default: false,
- },
- hasMultipleIssueAssigneesFeature: {
- default: false,
- },
- initialEmail: {
- default: '',
- },
- initialSort: {
- default: '',
- },
- isAnonymousSearchDisabled: {
- default: false,
- },
- isIssueRepositioningDisabled: {
- default: false,
- },
- isProject: {
- default: false,
- },
- isSignedIn: {
- default: false,
- },
- jiraIntegrationPath: {
- default: '',
- },
- newIssuePath: {
- default: '',
- },
- releasesPath: {
- default: '',
- },
- rssPath: {
- default: '',
- },
- showNewIssueLink: {
- default: false,
- },
- signInPath: {
- default: '',
- },
- },
+ inject: [
+ 'autocompleteAwardEmojisPath',
+ 'calendarPath',
+ 'canBulkUpdate',
+ 'emptyStateSvgPath',
+ 'exportCsvPath',
+ 'fullPath',
+ 'hasAnyIssues',
+ 'hasAnyProjects',
+ 'hasBlockedIssuesFeature',
+ 'hasIssueWeightsFeature',
+ 'hasMultipleIssueAssigneesFeature',
+ 'initialEmail',
+ 'initialSort',
+ 'isAnonymousSearchDisabled',
+ 'isIssueRepositioningDisabled',
+ 'isProject',
+ 'isSignedIn',
+ 'jiraIntegrationPath',
+ 'newIssuePath',
+ 'releasesPath',
+ 'rssPath',
+ 'showNewIssueLink',
+ 'signInPath',
+ ],
props: {
eeSearchTokens: {
type: Array,
@@ -349,6 +302,7 @@ export default {
token: MilestoneToken,
fetchMilestones: this.fetchMilestones,
recentSuggestionsStorageKey: `${this.fullPath}-issues-recent-tokens-milestone`,
+ shouldSkipSort: true,
},
{
type: TOKEN_TYPE_LABEL,
@@ -414,7 +368,7 @@ export default {
tokens.sort((a, b) => a.title.localeCompare(b.title));
- return orderBy(tokens, ['title']);
+ return tokens;
},
showPaginationControls() {
return this.issues.length > 0 && (this.pageInfo.hasNextPage || this.pageInfo.hasPreviousPage);
diff --git a/app/assets/javascripts/issues/list/components/new_issue_dropdown.vue b/app/assets/javascripts/issues/list/components/new_issue_dropdown.vue
index 71f84050ba8..666e80dfd4b 100644
--- a/app/assets/javascripts/issues/list/components/new_issue_dropdown.vue
+++ b/app/assets/javascripts/issues/list/components/new_issue_dropdown.vue
@@ -7,10 +7,10 @@ import {
GlSearchBoxByType,
} from '@gitlab/ui';
import createFlash from '~/flash';
-import searchProjectsQuery from '~/issues/list/queries/search_projects.query.graphql';
import { DASH_SCOPE, joinPaths } from '~/lib/utils/url_utility';
import { __, sprintf } from '~/locale';
import { DEBOUNCE_DELAY } from '~/vue_shared/components/filtered_search_bar/constants';
+import searchProjectsQuery from '../queries/search_projects.query.graphql';
export default {
i18n: {
diff --git a/app/assets/javascripts/issues/list/queries/search_milestones.query.graphql b/app/assets/javascripts/issues/list/queries/search_milestones.query.graphql
index e7eb08104a6..ff5dedbdb77 100644
--- a/app/assets/javascripts/issues/list/queries/search_milestones.query.graphql
+++ b/app/assets/javascripts/issues/list/queries/search_milestones.query.graphql
@@ -3,7 +3,12 @@
query searchMilestones($fullPath: ID!, $search: String, $isProject: Boolean = false) {
group(fullPath: $fullPath) @skip(if: $isProject) {
id
- milestones(searchTitle: $search, includeAncestors: true, includeDescendants: true) {
+ milestones(
+ searchTitle: $search
+ includeAncestors: true
+ includeDescendants: true
+ sort: EXPIRED_LAST_DUE_DATE_ASC
+ ) {
nodes {
...Milestone
}
@@ -11,7 +16,7 @@ query searchMilestones($fullPath: ID!, $search: String, $isProject: Boolean = fa
}
project(fullPath: $fullPath) @include(if: $isProject) {
id
- milestones(searchTitle: $search, includeAncestors: true) {
+ milestones(searchTitle: $search, includeAncestors: true, sort: EXPIRED_LAST_DUE_DATE_ASC) {
nodes {
...Milestone
}
diff --git a/app/assets/javascripts/issues/list/utils.js b/app/assets/javascripts/issues/list/utils.js
index 2919bbbfef8..22e904fc3cc 100644
--- a/app/assets/javascripts/issues/list/utils.js
+++ b/app/assets/javascripts/issues/list/utils.js
@@ -1,3 +1,9 @@
+import { isPositiveInteger } from '~/lib/utils/number_utils';
+import { __ } from '~/locale';
+import {
+ FILTERED_SEARCH_TERM,
+ OPERATOR_IS_NOT,
+} from '~/vue_shared/components/filtered_search_bar/constants';
import {
API_PARAM,
BLOCKING_ISSUES_ASC,
@@ -36,13 +42,7 @@ import {
urlSortParams,
WEIGHT_ASC,
WEIGHT_DESC,
-} from '~/issues/list/constants';
-import { isPositiveInteger } from '~/lib/utils/number_utils';
-import { __ } from '~/locale';
-import {
- FILTERED_SEARCH_TERM,
- OPERATOR_IS_NOT,
-} from '~/vue_shared/components/filtered_search_bar/constants';
+} from './constants';
export const getInitialPageParams = (sortKey) =>
sortKey === RELATIVE_POSITION_ASC ? largePageSizeParams : defaultPageSizeParams;
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue
index 8cf6383c26a..25ba4bf12af 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue
@@ -43,8 +43,8 @@ export default {
class="gl-ml-3"
size="small"
:icon="glFeatures.restructuredMrWidget ? undefined : 'comment-next'"
- :variant="glFeatures.restructuredMrWidget && 'confirm'"
- :category="glFeatures.restructuredMrWidget && 'secondary'"
+ :variant="glFeatures.restructuredMrWidget ? 'confirm' : 'default'"
+ :category="glFeatures.restructuredMrWidget ? 'secondary' : 'primary'"
@click="jumpToFirstUnresolvedDiscussion"
>
{{ s__('mrWidget|Jump to first unresolved thread') }}
diff --git a/app/assets/stylesheets/pages/settings.scss b/app/assets/stylesheets/pages/settings.scss
index 633051918a4..5956368a977 100644
--- a/app/assets/stylesheets/pages/settings.scss
+++ b/app/assets/stylesheets/pages/settings.scss
@@ -130,10 +130,6 @@
border-radius: $border-radius-base;
}
-.empty-variables {
- padding: 20px 0;
-}
-
.warning-title {
color: $gray-900;
}
diff --git a/spec/frontend/ci_variable_list/components/ci_variable_table_spec.js b/spec/frontend/ci_variable_list/components/ci_variable_table_spec.js
index ecbbd78b87d..62f9ae4eb4e 100644
--- a/spec/frontend/ci_variable_list/components/ci_variable_table_spec.js
+++ b/spec/frontend/ci_variable_list/components/ci_variable_table_spec.js
@@ -1,6 +1,6 @@
-import { mount } from '@vue/test-utils';
-import Vue, { nextTick } from 'vue';
+import Vue from 'vue';
import Vuex from 'vuex';
+import { mountExtended } from 'helpers/vue_test_utils_helper';
import CiVariableTable from '~/ci_variable_list/components/ci_variable_table.vue';
import createStore from '~/ci_variable_list/store';
import mockData from '../services/mock_data';
@@ -14,15 +14,15 @@ describe('Ci variable table', () => {
const createComponent = () => {
store = createStore();
jest.spyOn(store, 'dispatch').mockImplementation();
- wrapper = mount(CiVariableTable, {
+ wrapper = mountExtended(CiVariableTable, {
attachTo: document.body,
store,
});
};
- const findRevealButton = () => wrapper.find({ ref: 'secret-value-reveal-button' });
- const findEditButton = () => wrapper.find({ ref: 'edit-ci-variable' });
- const findEmptyVariablesPlaceholder = () => wrapper.find({ ref: 'empty-variables' });
+ const findRevealButton = () => wrapper.findByText('Reveal values');
+ const findEditButton = () => wrapper.findByLabelText('Edit');
+ const findEmptyVariablesPlaceholder = () => wrapper.findByText('There are no variables yet.');
beforeEach(() => {
createComponent();
@@ -36,18 +36,36 @@ describe('Ci variable table', () => {
expect(store.dispatch).toHaveBeenCalledWith('fetchVariables');
});
- describe('Renders correct data', () => {
- it('displays empty message when variables are not present', () => {
+ describe('When table is empty', () => {
+ beforeEach(() => {
+ store.state.variables = [];
+ });
+
+ it('displays empty message', () => {
expect(findEmptyVariablesPlaceholder().exists()).toBe(true);
});
- it('displays correct amount of variables present and no empty message', async () => {
- store.state.variables = mockData.mockVariables;
+ it('hides the reveal button', () => {
+ expect(findRevealButton().exists()).toBe(false);
+ });
+ });
- await nextTick();
- expect(wrapper.findAll('.js-ci-variable-row').length).toBe(1);
+ describe('When table has variables', () => {
+ beforeEach(() => {
+ store.state.variables = mockData.mockVariables;
+ });
+
+ it('does not display the empty message', () => {
expect(findEmptyVariablesPlaceholder().exists()).toBe(false);
});
+
+ it('displays the reveal button', () => {
+ expect(findRevealButton().exists()).toBe(true);
+ });
+
+ it('displays the correct amount of variables', async () => {
+ expect(wrapper.findAll('.js-ci-variable-row')).toHaveLength(1);
+ });
});
describe('Table click actions', () => {
diff --git a/spec/frontend/issues/list/components/issues_list_app_spec.js b/spec/frontend/issues/list/components/issues_list_app_spec.js
index dbd28fb7c1b..6b5dd72ef55 100644
--- a/spec/frontend/issues/list/components/issues_list_app_spec.js
+++ b/spec/frontend/issues/list/components/issues_list_app_spec.js
@@ -62,6 +62,7 @@ describe('CE IssuesListApp component', () => {
Vue.use(VueApollo);
const defaultProvide = {
+ autocompleteAwardEmojisPath: 'autocomplete/award/emojis/path',
calendarPath: 'calendar/path',
canBulkUpdate: false,
emptyStateSvgPath: 'empty-state.svg',
@@ -73,10 +74,16 @@ describe('CE IssuesListApp component', () => {
hasIssuableHealthStatusFeature: true,
hasIssueWeightsFeature: true,
hasIterationsFeature: true,
+ hasMultipleIssueAssigneesFeature: true,
+ initialEmail: 'email@example.com',
+ initialSort: CREATED_DESC,
+ isAnonymousSearchDisabled: false,
+ isIssueRepositioningDisabled: false,
isProject: true,
isSignedIn: true,
jiraIntegrationPath: 'jira/integration/path',
newIssuePath: 'new/issue/path',
+ releasesPath: 'releases/path',
rssPath: 'rss/path',
showNewIssueLink: true,
signInPath: 'sign/in/path',