diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-05-23 21:08:14 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-05-23 21:08:14 +0300 |
commit | 5e555ebcf6ee2ce13e9956ae599fd811a79b4dbd (patch) | |
tree | 6dd67e2f8f49b54e0fb1f266d1720f461393df59 /app/assets/javascripts/issues | |
parent | 3e53902ee13fc4e0bf3162c0c392dcfe1a0ede4b (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/issues')
5 files changed, 42 insertions, 276 deletions
diff --git a/app/assets/javascripts/issues/list/components/issues_list_app.vue b/app/assets/javascripts/issues/list/components/issues_list_app.vue index 9d8b339e813..2da6a049703 100644 --- a/app/assets/javascripts/issues/list/components/issues_list_app.vue +++ b/app/assets/javascripts/issues/list/components/issues_list_app.vue @@ -13,8 +13,6 @@ import fuzzaldrinPlus from 'fuzzaldrin-plus'; import IssueCardTimeInfo from 'ee_else_ce/issues/list/components/issue_card_time_info.vue'; 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 getIssuesWithoutCrmQuery from 'ee_else_ce/issues/list/queries/get_issues_without_crm.query.graphql'; -import getIssuesCountsWithoutCrmQuery from 'ee_else_ce/issues/list/queries/get_issues_counts_without_crm.query.graphql'; import createFlash, { FLASH_TYPES } from '~/flash'; import { TYPE_USER } from '~/graphql_shared/constants'; import { convertToGraphQLId, getIdFromGraphQLId } from '~/graphql_shared/utils'; @@ -160,9 +158,7 @@ export default { }, apollo: { issues: { - query() { - return this.hasCrmParameter ? getIssuesQuery : getIssuesWithoutCrmQuery; - }, + query: getIssuesQuery, variables() { return this.queryVariables; }, @@ -186,9 +182,7 @@ export default { debounce: 200, }, issuesCounts: { - query() { - return this.hasCrmParameter ? getIssuesCountsQuery : getIssuesCountsWithoutCrmQuery; - }, + query: getIssuesCountsQuery, variables() { return this.queryVariables; }, @@ -403,12 +397,6 @@ export default { page_before: this.pageParams.beforeCursor, }; }, - hasCrmParameter() { - return ( - window.location.search.includes('crm_contact_id=') || - window.location.search.includes('crm_organization_id=') - ); - }, }, watch: { $route(newValue, oldValue) { diff --git a/app/assets/javascripts/issues/list/queries/get_issues_counts_without_crm.query.graphql b/app/assets/javascripts/issues/list/queries/get_issues_counts_without_crm.query.graphql deleted file mode 100644 index ab91aab1218..00000000000 --- a/app/assets/javascripts/issues/list/queries/get_issues_counts_without_crm.query.graphql +++ /dev/null @@ -1,136 +0,0 @@ -query getIssuesCountWithoutCrm( - $isProject: Boolean = false - $fullPath: ID! - $iid: String - $search: String - $assigneeId: String - $assigneeUsernames: [String!] - $authorUsername: String - $confidential: Boolean - $labelName: [String] - $milestoneTitle: [String] - $milestoneWildcardId: MilestoneWildcardId - $myReactionEmoji: String - $releaseTag: [String!] - $releaseTagWildcardId: ReleaseTagWildcardId - $types: [IssueType!] - $not: NegatedIssueFilterInput -) { - group(fullPath: $fullPath) @skip(if: $isProject) { - id - openedIssues: issues( - includeSubgroups: true - state: opened - iid: $iid - search: $search - assigneeId: $assigneeId - assigneeUsernames: $assigneeUsernames - authorUsername: $authorUsername - confidential: $confidential - labelName: $labelName - milestoneTitle: $milestoneTitle - milestoneWildcardId: $milestoneWildcardId - myReactionEmoji: $myReactionEmoji - types: $types - not: $not - ) { - count - } - closedIssues: issues( - includeSubgroups: true - state: closed - iid: $iid - search: $search - assigneeId: $assigneeId - assigneeUsernames: $assigneeUsernames - authorUsername: $authorUsername - confidential: $confidential - labelName: $labelName - milestoneTitle: $milestoneTitle - milestoneWildcardId: $milestoneWildcardId - myReactionEmoji: $myReactionEmoji - types: $types - not: $not - ) { - count - } - allIssues: issues( - includeSubgroups: true - state: all - iid: $iid - search: $search - assigneeId: $assigneeId - assigneeUsernames: $assigneeUsernames - authorUsername: $authorUsername - confidential: $confidential - labelName: $labelName - milestoneTitle: $milestoneTitle - milestoneWildcardId: $milestoneWildcardId - myReactionEmoji: $myReactionEmoji - types: $types - not: $not - ) { - count - } - } - project(fullPath: $fullPath) @include(if: $isProject) { - id - openedIssues: issues( - state: opened - iid: $iid - search: $search - assigneeId: $assigneeId - assigneeUsernames: $assigneeUsernames - authorUsername: $authorUsername - confidential: $confidential - labelName: $labelName - milestoneTitle: $milestoneTitle - milestoneWildcardId: $milestoneWildcardId - myReactionEmoji: $myReactionEmoji - releaseTag: $releaseTag - releaseTagWildcardId: $releaseTagWildcardId - types: $types - not: $not - ) { - count - } - closedIssues: issues( - state: closed - iid: $iid - search: $search - assigneeId: $assigneeId - assigneeUsernames: $assigneeUsernames - authorUsername: $authorUsername - confidential: $confidential - labelName: $labelName - milestoneTitle: $milestoneTitle - milestoneWildcardId: $milestoneWildcardId - myReactionEmoji: $myReactionEmoji - releaseTag: $releaseTag - releaseTagWildcardId: $releaseTagWildcardId - types: $types - not: $not - ) { - count - } - allIssues: issues( - state: all - iid: $iid - search: $search - assigneeId: $assigneeId - assigneeUsernames: $assigneeUsernames - authorUsername: $authorUsername - confidential: $confidential - labelName: $labelName - milestoneTitle: $milestoneTitle - milestoneWildcardId: $milestoneWildcardId - myReactionEmoji: $myReactionEmoji - releaseTag: $releaseTag - releaseTagWildcardId: $releaseTagWildcardId - types: $types - not: $not - ) { - count - } - } -} diff --git a/app/assets/javascripts/issues/list/queries/get_issues_without_crm.query.graphql b/app/assets/javascripts/issues/list/queries/get_issues_without_crm.query.graphql deleted file mode 100644 index 4a8b1dfd618..00000000000 --- a/app/assets/javascripts/issues/list/queries/get_issues_without_crm.query.graphql +++ /dev/null @@ -1,94 +0,0 @@ -#import "~/graphql_shared/fragments/page_info.fragment.graphql" -#import "./issue.fragment.graphql" - -query getIssuesWithoutCrm( - $hideUsers: Boolean = false - $isProject: Boolean = false - $isSignedIn: Boolean = false - $fullPath: ID! - $iid: String - $search: String - $sort: IssueSort - $state: IssuableState - $assigneeId: String - $assigneeUsernames: [String!] - $authorUsername: String - $confidential: Boolean - $labelName: [String] - $milestoneTitle: [String] - $milestoneWildcardId: MilestoneWildcardId - $myReactionEmoji: String - $releaseTag: [String!] - $releaseTagWildcardId: ReleaseTagWildcardId - $types: [IssueType!] - $not: NegatedIssueFilterInput - $beforeCursor: String - $afterCursor: String - $firstPageSize: Int - $lastPageSize: Int -) { - group(fullPath: $fullPath) @skip(if: $isProject) { - id - issues( - includeSubgroups: true - iid: $iid - search: $search - sort: $sort - state: $state - assigneeId: $assigneeId - assigneeUsernames: $assigneeUsernames - authorUsername: $authorUsername - confidential: $confidential - labelName: $labelName - milestoneTitle: $milestoneTitle - milestoneWildcardId: $milestoneWildcardId - myReactionEmoji: $myReactionEmoji - types: $types - not: $not - before: $beforeCursor - after: $afterCursor - first: $firstPageSize - last: $lastPageSize - ) { - pageInfo { - ...PageInfo - } - nodes { - ...IssueFragment - reference(full: true) - } - } - } - project(fullPath: $fullPath) @include(if: $isProject) { - id - issues( - iid: $iid - search: $search - sort: $sort - state: $state - assigneeId: $assigneeId - assigneeUsernames: $assigneeUsernames - authorUsername: $authorUsername - confidential: $confidential - labelName: $labelName - milestoneTitle: $milestoneTitle - milestoneWildcardId: $milestoneWildcardId - myReactionEmoji: $myReactionEmoji - releaseTag: $releaseTag - releaseTagWildcardId: $releaseTagWildcardId - types: $types - not: $not - before: $beforeCursor - after: $afterCursor - first: $firstPageSize - last: $lastPageSize - ) { - pageInfo { - ...PageInfo - } - nodes { - ...IssueFragment - } - } - } -} diff --git a/app/assets/javascripts/issues/show/components/description.vue b/app/assets/javascripts/issues/show/components/description.vue index 4f97458dcd1..daa1632c4aa 100644 --- a/app/assets/javascripts/issues/show/components/description.vue +++ b/app/assets/javascripts/issues/show/components/description.vue @@ -12,6 +12,7 @@ import Vue from 'vue'; import { getIdFromGraphQLId, convertToGraphQLId } from '~/graphql_shared/utils'; import { TYPE_WORK_ITEM } from '~/graphql_shared/constants'; import createFlash from '~/flash'; +import { IssuableType } from '~/issues/constants'; import { isPositiveInteger } from '~/lib/utils/number_utils'; import { getParameterByName, setUrlParams, updateHistory } from '~/lib/utils/url_utility'; import { __, s__, sprintf } from '~/locale'; @@ -66,7 +67,7 @@ export default { issuableType: { type: String, required: false, - default: 'issue', + default: IssuableType.Issue, }, updateUrl: { type: String, @@ -177,7 +178,9 @@ export default { onError: this.taskListUpdateError.bind(this), }); - this.renderSortableLists(); + if (this.issuableType === IssuableType.Issue) { + this.renderSortableLists(); + } } }, renderSortableLists() { @@ -185,6 +188,10 @@ export default { const lists = document.querySelectorAll('.description ul, .description ol'); lists.forEach((list) => { + if (list.children.length <= 1) { + return; + } + Array.from(list.children).forEach((listItem) => { listItem.prepend(this.createDragIconElement()); this.addPointerEventListeners(listItem); @@ -211,13 +218,18 @@ export default { }, addPointerEventListeners(listItem) { const pointeroverListener = (event) => { - if (isDragging() || this.isUpdating) { + const dragIcon = event.target.closest('li').querySelector('.drag-icon'); + if (!dragIcon || isDragging() || this.isUpdating) { return; } - event.target.closest('li').querySelector('.drag-icon').style.visibility = 'visible'; // eslint-disable-line no-param-reassign + dragIcon.style.visibility = 'visible'; }; const pointeroutListener = (event) => { - event.target.closest('li').querySelector('.drag-icon').style.visibility = 'hidden'; // eslint-disable-line no-param-reassign + const dragIcon = event.target.closest('li').querySelector('.drag-icon'); + if (!dragIcon) { + return; + } + dragIcon.style.visibility = 'hidden'; }; // We use pointerover/pointerout instead of CSS so that when we hover over a diff --git a/app/assets/javascripts/issues/show/utils.js b/app/assets/javascripts/issues/show/utils.js index 60e66f59f92..05b06586362 100644 --- a/app/assets/javascripts/issues/show/utils.js +++ b/app/assets/javascripts/issues/show/utils.js @@ -1,39 +1,35 @@ import { COLON, HYPHEN, NEWLINE } from '~/lib/utils/text_utility'; /** - * Get the index from sourcepos that represents the line of - * the description when the description is split by newline. + * Returns the start and end `sourcepos` rows, converted to zero-based numbering. * * @param {String} sourcepos Source position in format `23:3-23:14` - * @returns {Number} Index of description split by newline + * @returns {Array<Number>} Start and end `sourcepos` rows, zero-based numbered */ -const getDescriptionIndex = (sourcepos) => { - const [startRange] = sourcepos.split(HYPHEN); +const getSourceposRows = (sourcepos) => { + const [startRange, endRange] = sourcepos.split(HYPHEN); const [startRow] = startRange.split(COLON); - return startRow - 1; + const [endRow] = endRange.split(COLON); + return [startRow - 1, endRow - 1]; }; /** - * Given a `ul` or `ol` element containing a new sort order, this function performs - * a depth-first search to get the new sort order in the form of sourcepos indices. + * Given a `ul` or `ol` element containing a new sort order, this function returns + * an array of this new order which is derived from its list items' sourcepos values. * * @param {HTMLElement} list A `ul` or `ol` element containing a new sort order - * @returns {Array<Number>} An array representing the new order of the list + * @returns {Array<Number>} A numerical array representing the new order of the list. + * The numbers represent the rows of the original markdown source. */ const getNewSourcePositions = (list) => { const newSourcePositions = []; - function pushPositionOfChildListItems(el) { - if (!el) { - return; + Array.from(list.children).forEach((listItem) => { + const [start, end] = getSourceposRows(listItem.dataset.sourcepos); + for (let i = start; i <= end; i += 1) { + newSourcePositions.push(i); } - if (el.tagName === 'LI') { - newSourcePositions.push(getDescriptionIndex(el.dataset.sourcepos)); - } - Array.from(el.children).forEach(pushPositionOfChildListItems); - } - - pushPositionOfChildListItems(list); + }); return newSourcePositions; }; @@ -56,17 +52,17 @@ const getNewSourcePositions = (list) => { * And a reordered list (due to dragging Item 2 into Item 1's position) like: * * <pre> - * <ul data-sourcepos="3:1-8:0"> - * <li data-sourcepos="4:1-4:8"> + * <ul data-sourcepos="3:1-7:8"> + * <li data-sourcepos="4:1-6:10"> * Item 2 - * <ul data-sourcepos="5:1-6:10"> - * <li data-sourcepos="5:1-5:10">Item 3</li> - * <li data-sourcepos="6:1-6:10">Item 4</li> + * <ul data-sourcepos="5:3-6:10"> + * <li data-sourcepos="5:3-5:10">Item 3</li> + * <li data-sourcepos="6:3-6:10">Item 4</li> * </ul> * </li> * <li data-sourcepos="3:1-3:8">Item 1</li> - * <li data-sourcepos="7:1-8:0">Item 5</li> - * <ul> + * <li data-sourcepos="7:1-7:8">Item 5</li> + * </ul> * </pre> * * This function returns: @@ -87,7 +83,7 @@ const getNewSourcePositions = (list) => { */ export const convertDescriptionWithNewSort = (description, list) => { const descriptionLines = description.split(NEWLINE); - const startIndexOfList = getDescriptionIndex(list.dataset.sourcepos); + const [startIndexOfList] = getSourceposRows(list.dataset.sourcepos); getNewSourcePositions(list) .map((lineIndex) => descriptionLines[lineIndex]) |