diff --git a/README.md b/README.md index b97d432b6cfd3c6c133243d6c3fd79d54d25484e..7992f02fc5de4355adba3875c3286355f38826f0 100644 --- a/README.md +++ b/README.md @@ -228,6 +228,8 @@ Each query is an entry of the json array. Each entry can have the following valu **`pipelineId`** _(required: false)_ : Returns vulnerabilities belonging to specified pipeline. "branch" returns vulnerabilities belonging to latest pipeline of the current branch. Works only with vulnerabilities. +**`reviewer`** _(required: false)_ : Returns GitLab Merge Requests assigned for review to the given username. When set to `""`, the extension uses the current user's username. + ## Usage - Open up Command Palette by pressing `Cmd+Shift+P`. diff --git a/package.json b/package.json index eb4d959bfee972d20bafb45bd5740f1fba38d85b..267f4f4a8e9553b92667020f55fee6b5340bfd42 100644 --- a/package.json +++ b/package.json @@ -572,6 +572,10 @@ "pipelineId": { "type": "number | string", "description": "Returns vulnerabilities belonging to specified pipeline. \"branch\" returns vulnerabilities belonging to latest pipeline of the current branch. Works only with vulnerabilities" + }, + "reviewer": { + "type": "string", + "description": "Returns GitLab Merge Requests assigned for review to the given username. When set to \"\", the extension uses the current user's username." } } }, @@ -597,6 +601,13 @@ "state": "opened", "noItemText": "There is no MR assigned to you." }, + { + "name": "Merge requests I'm reviewing", + "type": "merge_requests", + "reviewer": "", + "state": "opened", + "noItemText": "There is no MR for you to review." + }, { "name": "Merge requests created by me", "type": "merge_requests", diff --git a/src/gitlab/custom_query.ts b/src/gitlab/custom_query.ts index 3f81ae4006e013de639b05ffdbbecb3b36ef4166..65a4ba0ad81d2d261f22f8278679b37152332e6d 100644 --- a/src/gitlab/custom_query.ts +++ b/src/gitlab/custom_query.ts @@ -31,4 +31,5 @@ export interface CustomQuery { searchIn: string; pipelineId?: number | 'branch'; noItemText: string; + reviewer?: string; } diff --git a/src/gitlab_service.test.ts b/src/gitlab_service.test.ts index 0c8a03684d5fa76e90abdaf7dc09205cfbe96b99..f525bc80c1a1623657162f3db0846ea024250bdf 100644 --- a/src/gitlab_service.test.ts +++ b/src/gitlab_service.test.ts @@ -191,6 +191,13 @@ describe('fetchIssueables', () => { }); }); + it('sets reviewer parameter', async () => { + setupFetchIssuable(); + await fetchIssuablesHelper({ type: CustomQueryType.MR, reviewer: 'reviewer' }); + const search = new URLSearchParams(request.mock.calls[1][0]); + expect(search.get('reviewer_username')).toEqual('reviewer'); + }); + describe('searchIn parameters', () => { it('sets "all" parameter', async () => { setupFetchIssuable(); diff --git a/src/gitlab_service.ts b/src/gitlab_service.ts index aae59b6c2a933dbd4893a59ccddde5646514ad01..bf2aaf3f230cb59cdcbac470a0199a83b6f5227e 100644 --- a/src/gitlab_service.ts +++ b/src/gitlab_service.ts @@ -146,9 +146,10 @@ export async function fetchCurrentPipelineProject(workspaceFolder: string) { } } -export async function fetchCurrentUser() { +export async function fetchCurrentUser(): Promise { try { const { response: user } = await fetch('/user'); + if (!user) throw new Error('Could not retrieve current user.'); return user; } catch (e) { throw new ApiError(e, 'get current user'); @@ -217,7 +218,7 @@ type QueryValue = string | boolean | string[] | number | undefined; export async function fetchIssuables(params: CustomQuery, workspaceFolder: string) { const { type, scope, state, author, assignee, wip } = params; - let { searchIn, pipelineId } = params; + let { searchIn, pipelineId, reviewer } = params; const config = { type: type || 'merge_requests', scope: scope || 'all', @@ -291,6 +292,17 @@ export async function fetchIssuables(params: CustomQuery, workspaceFolder: strin search.append('assignee_id', (assigneeUser && assigneeUser.id) || '-1'); } + /** + * Reviewer parameters + */ + if (reviewer) { + if (reviewer === '') { + const user = await fetchCurrentUser(); + reviewer = user.username; + } + search.append('reviewer_username', reviewer); + } + /** * Search in parameters */ diff --git a/src/openers.ts b/src/openers.ts index 5c6915f6df476682ec8f5f0dece9fa9b74ce76e2..15a7ce4a76c10c42b43743dcf710bf989203ce7d 100644 --- a/src/openers.ts +++ b/src/openers.ts @@ -31,7 +31,7 @@ async function getLink(linkTemplate: string, workspaceFolder: string) { const project = await gitLabService.fetchCurrentProject(workspaceFolder); assert(project, 'Failed to fetch project'); - return linkTemplate.replace('$userId', user.id).replace('$projectUrl', project.webUrl); + return linkTemplate.replace('$userId', user.id.toString()).replace('$projectUrl', project.webUrl); } async function openLink(linkTemplate: string, workspaceFolder: string) { diff --git a/src/types.d.ts b/src/types.d.ts index 5ffe70994c6b3a2432d3bd1d9b67470fc4dde5d5..a5f0e47b408b1ea1176b3734416a3a86cc8aee33 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -62,3 +62,11 @@ interface RestPipeline { project_id: number; web_url: string; } + +// Incomplete reference of the GitLab user model +interface RestUser { + id: number; + username: string; + email: string; + state: string; +}