Commit c85ff3fe authored by Coung Ngo's avatar Coung Ngo Committed by Natalia Tepluhina

Add spam icon and disabled reordering alert to issues refactor

parent 5fe28a8f
......@@ -185,6 +185,13 @@ export default {
:title="__('Confidential')"
:aria-label="__('Confidential')"
/>
<gl-icon
v-if="issuable.hidden"
v-gl-tooltip
name="spam"
:title="__('This issue is hidden because its author has been banned')"
:aria-label="__('Hidden')"
/>
<gl-link class="issue-title-text" dir="auto" :href="webUrl" v-bind="issuableTitleProps">
{{ issuable.title }}
<gl-icon v-if="isIssuableUrlExternal" name="external-link" class="gl-ml-2" />
......@@ -202,7 +209,7 @@ export default {
<span v-else data-testid="issuable-reference" class="issuable-reference">
{{ reference }}
</span>
<span class="gl-display-none gl-sm-display-inline-block">
<span class="gl-display-none gl-sm-display-inline">
<span aria-hidden="true">&middot;</span>
<span class="issuable-authored gl-mr-3">
<gl-sprintf :message="__('created %{timeAgo} by %{author}')">
......
......@@ -11,7 +11,7 @@ import {
import fuzzaldrinPlus from 'fuzzaldrin-plus';
import getIssuesQuery from 'ee_else_ce/issues_list/queries/get_issues.query.graphql';
import getIssuesCountsQuery from 'ee_else_ce/issues_list/queries/get_issues_counts.query.graphql';
import createFlash from '~/flash';
import createFlash, { FLASH_TYPES } from '~/flash';
import { TYPE_USER } from '~/graphql_shared/constants';
import { convertToGraphQLId, getIdFromGraphQLId } from '~/graphql_shared/utils';
import { ITEM_TYPE } from '~/groups/constants';
......@@ -157,6 +157,9 @@ export default {
initialEmail: {
default: '',
},
isIssueRepositioningDisabled: {
default: false,
},
isProject: {
default: false,
},
......@@ -184,8 +187,13 @@ export default {
},
data() {
const state = getParameterByName(PARAM_STATE);
const sortKey = getSortKey(getParameterByName(PARAM_SORT));
const defaultSortKey = state === IssuableStates.Closed ? UPDATED_DESC : CREATED_DESC;
let sortKey = getSortKey(getParameterByName(PARAM_SORT)) || defaultSortKey;
if (this.isIssueRepositioningDisabled && sortKey === RELATIVE_POSITION_ASC) {
this.showIssueRepositioningMessage();
sortKey = defaultSortKey;
}
return {
dueDateFilter: getDueDateValue(getParameterByName(PARAM_DUE_DATE)),
......@@ -196,7 +204,7 @@ export default {
pageInfo: {},
pageParams: getInitialPageParams(sortKey),
showBulkEditSidebar: false,
sortKey: sortKey || defaultSortKey,
sortKey,
state: state || IssuableStates.Opened,
};
},
......@@ -611,11 +619,22 @@ export default {
});
},
handleSort(sortKey) {
if (this.isIssueRepositioningDisabled && sortKey === RELATIVE_POSITION_ASC) {
this.showIssueRepositioningMessage();
return;
}
if (this.sortKey !== sortKey) {
this.pageParams = getInitialPageParams(sortKey);
}
this.sortKey = sortKey;
},
showIssueRepositioningMessage() {
createFlash({
message: this.$options.i18n.issueRepositioningMessage,
type: FLASH_TYPES.NOTICE,
});
},
toggleBulkEditSidebar(showBulkEditSidebar) {
this.showBulkEditSidebar = showBulkEditSidebar;
},
......
......@@ -75,6 +75,9 @@ export const i18n = {
editIssues: __('Edit issues'),
errorFetchingCounts: __('An error occurred while getting issue counts'),
errorFetchingIssues: __('An error occurred while loading issues'),
issueRepositioningMessage: __(
'Issues are being rebalanced at the moment, so manual reordering is disabled.',
),
jiraIntegrationMessage: s__(
'JiraService|%{jiraDocsLinkStart}Enable the Jira integration%{jiraDocsLinkEnd} to view your Jira issues in GitLab.',
),
......
......@@ -129,6 +129,7 @@ export function mountIssuesListApp() {
hasMultipleIssueAssigneesFeature,
importCsvIssuesPath,
initialEmail,
isIssueRepositioningDisabled,
isProject,
isSignedIn,
jiraIntegrationPath,
......@@ -161,6 +162,7 @@ export function mountIssuesListApp() {
hasIssueWeightsFeature: parseBoolean(hasIssueWeightsFeature),
hasIterationsFeature: parseBoolean(hasIterationsFeature),
hasMultipleIssueAssigneesFeature: parseBoolean(hasMultipleIssueAssigneesFeature),
isIssueRepositioningDisabled: parseBoolean(isIssueRepositioningDisabled),
isProject: parseBoolean(isProject),
isSignedIn: parseBoolean(isSignedIn),
jiraIntegrationPath,
......
......@@ -6,6 +6,7 @@ fragment IssueFragment on Issue {
createdAt
downvotes
dueDate
hidden
humanTimeEstimate
mergeRequestsCount
moved
......
......@@ -212,6 +212,7 @@ module IssuesHelper
calendar_path: url_for(safe_params.merge(calendar_url_options)),
empty_state_svg_path: image_path('illustrations/issues.svg'),
full_path: namespace.full_path,
is_issue_repositioning_disabled: issue_repositioning_disabled?.to_s,
is_signed_in: current_user.present?.to_s,
jira_integration_path: help_page_url('integration/jira/issues', anchor: 'view-jira-issues'),
rss_path: url_for(safe_params.merge(rss_url_options)),
......
......@@ -17092,6 +17092,9 @@ msgstr ""
msgid "Hi %{username}!"
msgstr ""
msgid "Hidden"
msgstr ""
msgid "Hide"
msgstr ""
......
......@@ -17,7 +17,7 @@ import {
locationSearch,
urlParams,
} from 'jest/issues_list/mock_data';
import createFlash from '~/flash';
import createFlash, { FLASH_TYPES } from '~/flash';
import { convertToGraphQLId, getIdFromGraphQLId } from '~/graphql_shared/utils';
import CsvImportExportButtons from '~/issuable/components/csv_import_export_buttons.vue';
import IssuableByEmail from '~/issuable/components/issuable_by_email.vue';
......@@ -29,6 +29,8 @@ import {
CREATED_DESC,
DUE_DATE_OVERDUE,
PARAM_DUE_DATE,
RELATIVE_POSITION,
RELATIVE_POSITION_ASC,
TOKEN_TYPE_ASSIGNEE,
TOKEN_TYPE_AUTHOR,
TOKEN_TYPE_CONFIDENTIAL,
......@@ -314,6 +316,29 @@ describe('IssuesListApp component', () => {
},
});
});
describe('when issue repositioning is disabled and the sort is manual', () => {
beforeEach(() => {
setWindowLocation(`?sort=${RELATIVE_POSITION}`);
wrapper = mountComponent({ provide: { isIssueRepositioningDisabled: true } });
});
it('changes the sort to the default of created descending', () => {
expect(findIssuableList().props()).toMatchObject({
initialSortBy: CREATED_DESC,
urlParams: {
sort: urlSortParams[CREATED_DESC],
},
});
});
it('shows an alert to tell the user that manual reordering is disabled', () => {
expect(createFlash).toHaveBeenCalledWith({
message: IssuesListApp.i18n.issueRepositioningMessage,
type: FLASH_TYPES.NOTICE,
});
});
});
});
describe('state', () => {
......@@ -762,6 +787,30 @@ describe('IssuesListApp component', () => {
});
},
);
describe('when issue repositioning is disabled', () => {
const initialSort = CREATED_DESC;
beforeEach(() => {
setWindowLocation(`?sort=${initialSort}`);
wrapper = mountComponent({ provide: { isIssueRepositioningDisabled: true } });
findIssuableList().vm.$emit('sort', RELATIVE_POSITION_ASC);
});
it('does not update the sort to manual', () => {
expect(findIssuableList().props('urlParams')).toMatchObject({
sort: urlSortParams[initialSort],
});
});
it('shows an alert to tell the user that manual reordering is disabled', () => {
expect(createFlash).toHaveBeenCalledWith({
message: IssuesListApp.i18n.issueRepositioningMessage,
type: FLASH_TYPES.NOTICE,
});
});
});
});
describe('when "update-legacy-bulk-edit" event is emitted by IssuableList', () => {
......
......@@ -22,6 +22,7 @@ export const getIssuesQueryResponse = {
createdAt: '2021-05-22T04:08:01Z',
downvotes: 2,
dueDate: '2021-05-29',
hidden: false,
humanTimeEstimate: null,
mergeRequestsCount: false,
moved: false,
......
......@@ -302,6 +302,7 @@ RSpec.describe IssuesHelper do
allow(helper).to receive(:can?).and_return(true)
allow(helper).to receive(:image_path).and_return('#')
allow(helper).to receive(:import_csv_namespace_project_issues_path).and_return('#')
allow(helper).to receive(:issue_repositioning_disabled?).and_return(true)
allow(helper).to receive(:url_for).and_return('#')
expected = {
......@@ -318,6 +319,7 @@ RSpec.describe IssuesHelper do
has_any_issues: project_issues(project).exists?.to_s,
import_csv_issues_path: '#',
initial_email: project.new_issuable_address(current_user, 'issue'),
is_issue_repositioning_disabled: 'true',
is_project: 'true',
is_signed_in: current_user.present?.to_s,
jira_integration_path: help_page_url('integration/jira/issues', anchor: 'view-jira-issues'),
......
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