diff options
Diffstat (limited to 'app/assets/javascripts/issues_list')
14 files changed, 194 insertions, 48 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 fd225223a7f..8e37339fca6 100644 --- a/app/assets/javascripts/issues_list/components/issues_list_app.vue +++ b/app/assets/javascripts/issues_list/components/issues_list_app.vue @@ -14,6 +14,7 @@ import getIssuesCountsQuery from 'ee_else_ce/issues_list/queries/get_issues_coun import createFlash from '~/flash'; import { TYPE_USER } from '~/graphql_shared/constants'; import { convertToGraphQLId, getIdFromGraphQLId } from '~/graphql_shared/utils'; +import { ITEM_TYPE } from '~/groups/constants'; import CsvImportExportButtons from '~/issuable/components/csv_import_export_buttons.vue'; import IssuableByEmail from '~/issuable/components/issuable_by_email.vue'; import IssuableList from '~/issuable_list/components/issuable_list_root.vue'; @@ -140,11 +141,11 @@ export default { initialEmail: { default: '', }, - isSignedIn: { + isProject: { default: false, }, - issuesPath: { - default: '', + isSignedIn: { + default: false, }, jiraIntegrationPath: { default: '', @@ -186,9 +187,11 @@ export default { variables() { return this.queryVariables; }, - update: ({ project }) => project?.issues.nodes ?? [], + update(data) { + return data[this.namespace]?.issues.nodes ?? []; + }, result({ data }) { - this.pageInfo = data.project?.issues.pageInfo ?? {}; + this.pageInfo = data[this.namespace]?.issues.pageInfo ?? {}; this.exportCsvPathWithQuery = this.getExportCsvPathWithQuery(); }, error(error) { @@ -204,7 +207,9 @@ export default { variables() { return this.queryVariables; }, - update: ({ project }) => project ?? {}, + update(data) { + return data[this.namespace] ?? {}; + }, error(error) { createFlash({ message: this.$options.i18n.errorFetchingCounts, captureError: true, error }); }, @@ -220,8 +225,9 @@ export default { computed: { queryVariables() { return { - isSignedIn: this.isSignedIn, fullPath: this.fullPath, + isProject: this.isProject, + isSignedIn: this.isSignedIn, search: this.searchQuery, sort: this.sortKey, state: this.state, @@ -229,6 +235,9 @@ export default { ...this.apiFilterParams, }; }, + namespace() { + return this.isProject ? ITEM_TYPE.PROJECT : ITEM_TYPE.GROUP; + }, hasSearch() { return this.searchQuery || Object.keys(this.urlFilterParams).length; }, @@ -242,7 +251,7 @@ export default { return this.state === IssuableStates.Opened; }, showCsvButtons() { - return this.isSignedIn; + return this.isProject && this.isSignedIn; }, apiFilterParams() { return convertToApiParams(this.filterTokens); @@ -447,39 +456,41 @@ export default { return this.$apollo .query({ query: searchLabelsQuery, - variables: { fullPath: this.fullPath, search }, + variables: { fullPath: this.fullPath, search, isProject: this.isProject }, }) - .then(({ data }) => data.project.labels.nodes); + .then(({ data }) => data[this.namespace]?.labels.nodes); }, fetchMilestones(search) { return this.$apollo .query({ query: searchMilestonesQuery, - variables: { fullPath: this.fullPath, search }, + variables: { fullPath: this.fullPath, search, isProject: this.isProject }, }) - .then(({ data }) => data.project.milestones.nodes); + .then(({ data }) => data[this.namespace]?.milestones.nodes); }, fetchIterations(search) { const id = Number(search); const variables = !search || Number.isNaN(id) - ? { fullPath: this.fullPath, search } - : { fullPath: this.fullPath, id }; + ? { fullPath: this.fullPath, search, isProject: this.isProject } + : { fullPath: this.fullPath, id, isProject: this.isProject }; return this.$apollo .query({ query: searchIterationsQuery, variables, }) - .then(({ data }) => data.project.iterations.nodes); + .then(({ data }) => data[this.namespace]?.iterations.nodes); }, fetchUsers(search) { return this.$apollo .query({ query: searchUsersQuery, - variables: { fullPath: this.fullPath, search }, + variables: { fullPath: this.fullPath, search, isProject: this.isProject }, }) - .then(({ data }) => data.project.projectMembers.nodes.map((member) => member.user)); + .then(({ data }) => + data[this.namespace]?.[`${this.namespace}Members`].nodes.map((member) => member.user), + ); }, getExportCsvPathWithQuery() { return `${this.exportCsvPath}${window.location.search}`; @@ -560,15 +571,16 @@ export default { } return axios - .put(joinPaths(this.issuesPath, issueToMove.iid, 'reorder'), { + .put(joinPaths(issueToMove.webPath, 'reorder'), { move_before_id: isMovingToBeginning ? null : getIdFromGraphQLId(moveBeforeId), move_after_id: isMovingToEnd ? null : getIdFromGraphQLId(moveAfterId), + group_full_path: this.isProject ? undefined : this.fullPath, }) .then(() => { const serializedVariables = JSON.stringify(this.queryVariables); return this.$apollo.mutate({ mutation: reorderIssuesMutation, - variables: { oldIndex, newIndex, serializedVariables }, + variables: { oldIndex, newIndex, namespace: this.namespace, serializedVariables }, }); }) .catch((error) => { diff --git a/app/assets/javascripts/issues_list/index.js b/app/assets/javascripts/issues_list/index.js index 03ab524d719..e89e3e8e681 100644 --- a/app/assets/javascripts/issues_list/index.js +++ b/app/assets/javascripts/issues_list/index.js @@ -85,17 +85,17 @@ export function mountIssuesListApp() { const resolvers = { Mutation: { - reorderIssues: (_, { oldIndex, newIndex, serializedVariables }, { cache }) => { + reorderIssues: (_, { oldIndex, newIndex, namespace, serializedVariables }, { cache }) => { const variables = JSON.parse(serializedVariables); const sourceData = cache.readQuery({ query: getIssuesQuery, variables }); const data = produce(sourceData, (draftData) => { - const issues = draftData.project.issues.nodes.slice(); + const issues = draftData[namespace].issues.nodes.slice(); const issueToMove = issues[oldIndex]; issues.splice(oldIndex, 1); issues.splice(newIndex, 0, issueToMove); - draftData.project.issues.nodes = issues; + draftData[namespace].issues.nodes = issues; }); cache.writeQuery({ query: getIssuesQuery, variables, data }); @@ -128,8 +128,8 @@ export function mountIssuesListApp() { hasMultipleIssueAssigneesFeature, importCsvIssuesPath, initialEmail, + isProject, isSignedIn, - issuesPath, jiraIntegrationPath, markdownHelpPath, maxAttachmentSize, @@ -158,8 +158,8 @@ export function mountIssuesListApp() { hasIssueWeightsFeature: parseBoolean(hasIssueWeightsFeature), hasIterationsFeature: parseBoolean(hasIterationsFeature), hasMultipleIssueAssigneesFeature: parseBoolean(hasMultipleIssueAssigneesFeature), + isProject: parseBoolean(isProject), isSignedIn: parseBoolean(isSignedIn), - issuesPath, jiraIntegrationPath, newIssuePath, rssPath, diff --git a/app/assets/javascripts/issues_list/queries/get_issues.query.graphql b/app/assets/javascripts/issues_list/queries/get_issues.query.graphql index 1cb6fef0a12..6df72cf6596 100644 --- a/app/assets/javascripts/issues_list/queries/get_issues.query.graphql +++ b/app/assets/javascripts/issues_list/queries/get_issues.query.graphql @@ -2,6 +2,7 @@ #import "./issue.fragment.graphql" query getIssues( + $isProject: Boolean = false $isSignedIn: Boolean = false $fullPath: ID! $search: String @@ -20,7 +21,35 @@ query getIssues( $firstPageSize: Int $lastPageSize: Int ) { - project(fullPath: $fullPath) { + group(fullPath: $fullPath) @skip(if: $isProject) { + issues( + includeSubgroups: true + search: $search + sort: $sort + state: $state + assigneeId: $assigneeId + assigneeUsernames: $assigneeUsernames + authorUsername: $authorUsername + labelName: $labelName + milestoneTitle: $milestoneTitle + milestoneWildcardId: $milestoneWildcardId + 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) { issues( search: $search sort: $sort diff --git a/app/assets/javascripts/issues_list/queries/get_issues_counts.query.graphql b/app/assets/javascripts/issues_list/queries/get_issues_counts.query.graphql index a3765d39ed2..7bcdbbb28fc 100644 --- a/app/assets/javascripts/issues_list/queries/get_issues_counts.query.graphql +++ b/app/assets/javascripts/issues_list/queries/get_issues_counts.query.graphql @@ -1,4 +1,5 @@ query getIssuesCount( + $isProject: Boolean = false $fullPath: ID! $search: String $assigneeId: String @@ -10,7 +11,54 @@ query getIssuesCount( $types: [IssueType!] $not: NegatedIssueFilterInput ) { - project(fullPath: $fullPath) { + group(fullPath: $fullPath) @skip(if: $isProject) { + openedIssues: issues( + includeSubgroups: true + state: opened + search: $search + assigneeId: $assigneeId + assigneeUsernames: $assigneeUsernames + authorUsername: $authorUsername + labelName: $labelName + milestoneTitle: $milestoneTitle + milestoneWildcardId: $milestoneWildcardId + types: $types + not: $not + ) { + count + } + closedIssues: issues( + includeSubgroups: true + state: closed + search: $search + assigneeId: $assigneeId + assigneeUsernames: $assigneeUsernames + authorUsername: $authorUsername + labelName: $labelName + milestoneTitle: $milestoneTitle + milestoneWildcardId: $milestoneWildcardId + types: $types + not: $not + ) { + count + } + allIssues: issues( + includeSubgroups: true + state: all + search: $search + assigneeId: $assigneeId + assigneeUsernames: $assigneeUsernames + authorUsername: $authorUsername + labelName: $labelName + milestoneTitle: $milestoneTitle + milestoneWildcardId: $milestoneWildcardId + types: $types + not: $not + ) { + count + } + } + project(fullPath: $fullPath) @include(if: $isProject) { openedIssues: issues( state: opened search: $search diff --git a/app/assets/javascripts/issues_list/queries/issue.fragment.graphql b/app/assets/javascripts/issues_list/queries/issue.fragment.graphql index 633b06eced8..9c46cb3ef64 100644 --- a/app/assets/javascripts/issues_list/queries/issue.fragment.graphql +++ b/app/assets/javascripts/issues_list/queries/issue.fragment.graphql @@ -13,6 +13,7 @@ fragment IssueFragment on Issue { updatedAt upvotes userDiscussionsCount @include(if: $isSignedIn) + webPath webUrl assignees { nodes { diff --git a/app/assets/javascripts/issues_list/queries/iteration.fragment.graphql b/app/assets/javascripts/issues_list/queries/iteration.fragment.graphql new file mode 100644 index 00000000000..78a368089a8 --- /dev/null +++ b/app/assets/javascripts/issues_list/queries/iteration.fragment.graphql @@ -0,0 +1,4 @@ +fragment Iteration on Iteration { + id + title +} diff --git a/app/assets/javascripts/issues_list/queries/label.fragment.graphql b/app/assets/javascripts/issues_list/queries/label.fragment.graphql new file mode 100644 index 00000000000..bb1d8f1ac9b --- /dev/null +++ b/app/assets/javascripts/issues_list/queries/label.fragment.graphql @@ -0,0 +1,6 @@ +fragment Label on Label { + id + color + textColor + title +} diff --git a/app/assets/javascripts/issues_list/queries/milestone.fragment.graphql b/app/assets/javascripts/issues_list/queries/milestone.fragment.graphql new file mode 100644 index 00000000000..3cdf69bf585 --- /dev/null +++ b/app/assets/javascripts/issues_list/queries/milestone.fragment.graphql @@ -0,0 +1,4 @@ +fragment Milestone on Milestone { + id + title +} diff --git a/app/assets/javascripts/issues_list/queries/reorder_issues.mutation.graphql b/app/assets/javascripts/issues_list/queries/reorder_issues.mutation.graphql index 5927e3e83c7..160026a4742 100644 --- a/app/assets/javascripts/issues_list/queries/reorder_issues.mutation.graphql +++ b/app/assets/javascripts/issues_list/queries/reorder_issues.mutation.graphql @@ -1,7 +1,13 @@ -mutation reorderIssues($oldIndex: Int, $newIndex: Int, $serializedVariables: String) { +mutation reorderIssues( + $oldIndex: Int + $newIndex: Int + $namespace: String + $serializedVariables: String +) { reorderIssues( oldIndex: $oldIndex newIndex: $newIndex + namespace: $namespace serializedVariables: $serializedVariables ) @client } diff --git a/app/assets/javascripts/issues_list/queries/search_iterations.query.graphql b/app/assets/javascripts/issues_list/queries/search_iterations.query.graphql index 0bdf3bfda96..93600c62905 100644 --- a/app/assets/javascripts/issues_list/queries/search_iterations.query.graphql +++ b/app/assets/javascripts/issues_list/queries/search_iterations.query.graphql @@ -1,9 +1,17 @@ -query searchIterations($fullPath: ID!, $search: String, $id: ID) { - project(fullPath: $fullPath) { - iterations(title: $search, id: $id) { +#import "./iteration.fragment.graphql" + +query searchIterations($fullPath: ID!, $search: String, $id: ID, $isProject: Boolean = false) { + group(fullPath: $fullPath) @skip(if: $isProject) { + iterations(title: $search, id: $id, includeAncestors: true) { nodes { - id - title + ...Iteration + } + } + } + project(fullPath: $fullPath) @include(if: $isProject) { + iterations(title: $search, id: $id, includeAncestors: true) { + nodes { + ...Iteration } } } diff --git a/app/assets/javascripts/issues_list/queries/search_labels.query.graphql b/app/assets/javascripts/issues_list/queries/search_labels.query.graphql index bdbb0675a24..1515bd91da3 100644 --- a/app/assets/javascripts/issues_list/queries/search_labels.query.graphql +++ b/app/assets/javascripts/issues_list/queries/search_labels.query.graphql @@ -1,11 +1,17 @@ -query searchLabels($fullPath: ID!, $search: String) { - project(fullPath: $fullPath) { +#import "./label.fragment.graphql" + +query searchLabels($fullPath: ID!, $search: String, $isProject: Boolean = false) { + group(fullPath: $fullPath) @skip(if: $isProject) { + labels(searchTerm: $search, includeAncestorGroups: true, includeDescendantGroups: true) { + nodes { + ...Label + } + } + } + project(fullPath: $fullPath) @include(if: $isProject) { labels(searchTerm: $search, includeAncestorGroups: true) { nodes { - id - color - textColor - title + ...Label } } } 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 93802bd8dd5..8c6c50e9dc2 100644 --- a/app/assets/javascripts/issues_list/queries/search_milestones.query.graphql +++ b/app/assets/javascripts/issues_list/queries/search_milestones.query.graphql @@ -1,9 +1,17 @@ -query searchMilestones($fullPath: ID!, $search: String) { - project(fullPath: $fullPath) { +#import "./milestone.fragment.graphql" + +query searchMilestones($fullPath: ID!, $search: String, $isProject: Boolean = false) { + group(fullPath: $fullPath) @skip(if: $isProject) { + milestones(searchTitle: $search, includeAncestors: true, includeDescendants: true) { + nodes { + ...Milestone + } + } + } + project(fullPath: $fullPath) @include(if: $isProject) { milestones(searchTitle: $search, includeAncestors: true) { nodes { - id - title + ...Milestone } } } diff --git a/app/assets/javascripts/issues_list/queries/search_users.query.graphql b/app/assets/javascripts/issues_list/queries/search_users.query.graphql index 182ab9dd577..0211fc66235 100644 --- a/app/assets/javascripts/issues_list/queries/search_users.query.graphql +++ b/app/assets/javascripts/issues_list/queries/search_users.query.graphql @@ -1,12 +1,20 @@ -query searchUsers($fullPath: ID!, $search: String) { - project(fullPath: $fullPath) { +#import "./user.fragment.graphql" + +query searchUsers($fullPath: ID!, $search: String, $isProject: Boolean = false) { + group(fullPath: $fullPath) @skip(if: $isProject) { + groupMembers(search: $search) { + nodes { + user { + ...User + } + } + } + } + project(fullPath: $fullPath) @include(if: $isProject) { projectMembers(search: $search) { nodes { user { - id - avatarUrl - name - username + ...User } } } diff --git a/app/assets/javascripts/issues_list/queries/user.fragment.graphql b/app/assets/javascripts/issues_list/queries/user.fragment.graphql new file mode 100644 index 00000000000..3e5bc0f7b93 --- /dev/null +++ b/app/assets/javascripts/issues_list/queries/user.fragment.graphql @@ -0,0 +1,6 @@ +fragment User on User { + id + avatarUrl + name + username +} |