diff --git a/.vscode/launch.json b/.vscode/launch.json index 5a6d694..64db220 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -3,7 +3,7 @@ // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 { - "version": "1.0.1", + "version": "1.1.0", "configurations": [ { "name": "Run Extension", diff --git a/package.json b/package.json index 99f43fe..84ac953 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "publisher": "Pullflow", "displayName": "Pullflow", "description": "Code review collaboration across GitHub, Slack, and VS Code.", - "version": "1.0.1", + "version": "1.1.0", "preview": true, "license": "MIT", "engines": { diff --git a/src/api/pullRequestQuickActionsApi.ts b/src/api/pullRequestQuickActionsApi.ts index 40d686c..20467d0 100644 --- a/src/api/pullRequestQuickActionsApi.ts +++ b/src/api/pullRequestQuickActionsApi.ts @@ -41,6 +41,15 @@ const REQUEST_REVIEW = ` } ` +const SET_REMINDER = ` +mutation setCodeReviewReminder($codeReviewId: String!, $duration: Int!) { + setCodeReviewReminder(codeReviewId: $codeReviewId, duration: $duration) { + success + message + } +} +` + export const PullRequestQuickActionsApi = { addLabels: async ({ authToken, @@ -149,4 +158,30 @@ export const PullRequestQuickActionsApi = { return { error } } }, + + setReminder: async ({ + duration, + codeReviewId, + authToken, + context, + }: { + duration: number + codeReviewId: string + authToken: string + context: ExtensionContext + }) => { + log.info(`setting reminder: ${{ duration, codeReviewId }}}`, module) + + const pullflowApi = new PullflowApi(context, authToken) + try { + const data = await pullflowApi.fetch(SET_REMINDER, { + codeReviewId, + duration, + }) + return data.setCodeReviewReminder + } catch (error) { + log.error(`error in requesting review, ${error}`, module) + return { error } + } + }, } diff --git a/src/pullRequestQuickActions/pullRequestQuickActions.ts b/src/pullRequestQuickActions/pullRequestQuickActions.ts index 8aa12b3..b9c23ba 100644 --- a/src/pullRequestQuickActions/pullRequestQuickActions.ts +++ b/src/pullRequestQuickActions/pullRequestQuickActions.ts @@ -11,6 +11,8 @@ import { spaceUserPicker } from '../views/quickpicks/spaceUserPicker' import { Presence } from '../models/presence' import { Store } from '../utils/store' import { StatusBar } from '../views/statusBar/statusBar' +import { TimeSelectionItem, timePicker } from '../views/quickpicks/timePicker' +import moment = require('moment') export const PullRequestQuickActions = { applyLabel: async ({ @@ -209,4 +211,37 @@ export const PullRequestQuickActions = { statusBar, }) }, + setReminder: ({ + codeReview, + context, + }: { + codeReview: CodeReviewSelectionItem + context: ExtensionContext + }) => { + const onDidChangeSelection = async (item: readonly TimeSelectionItem[]) => { + if (!item[0]?.label) return false + const selectedTime = item[0] + const session = await Authorization.currentSession(context) + const duration = computeTime(selectedTime.value) + const response = await PullRequestQuickActionsApi.setReminder({ + codeReviewId: codeReview.id, + duration, + authToken: session?.accessToken ?? '', + context, + }) + if (response.message || response.error || !response.success) { + window.showInformationMessage( + 'Something went wrong, failed to set reminder' + ) + return false + } + window.showInformationMessage(`Pullflow: Successfully set reminder.`) + return true + } + + timePicker({ title: 'Remind me in', onDidChangeSelection }) + }, } + +const computeTime = (minutes: number) => + Math.floor(moment().add(minutes, 'minutes').valueOf() / 1000) diff --git a/src/utils/types.ts b/src/utils/types.ts index 07f480a..b133ba9 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -75,6 +75,10 @@ export interface ReviewerSelectionItem extends QuickPickItem { hasUser: boolean xid: string } +export interface SpaceUserSelectionItem extends QuickPickItem { + label: string + description: string +} export enum CodeReviewType { Pending, Authored, @@ -89,6 +93,7 @@ export enum ActivePullRequestActions { ApplyLabel = 'Add label', AddAssignee = 'Add assignee', RequestReview = 'Add reviewer', + SetReminder = 'Set a reminder', } export type SpaceUser = { id: string @@ -112,6 +117,7 @@ export type ApiVariables = | AddAssigneeVariables | RequestReviewVariables | CodeReviewApproveVariables + | CodeReviewRemindersVariables export type ThreadMessageVariables = { body: string parentMessageXid: string @@ -149,6 +155,10 @@ export type CodeReviewApproveVariables = { codeReviewId: string body?: string } +export type CodeReviewRemindersVariables = { + codeReviewId: string + duration: number +} export type RepoInfo = { repoName?: string branch?: string diff --git a/src/views/quickpicks/pullRequestActionPicker.ts b/src/views/quickpicks/pullRequestActionPicker.ts index ffc6848..5c5aee1 100644 --- a/src/views/quickpicks/pullRequestActionPicker.ts +++ b/src/views/quickpicks/pullRequestActionPicker.ts @@ -32,6 +32,7 @@ const getActionItems = (type: CodeReviewType) => [ { label: ActivePullRequestActions.RequestReview, }, + { label: ActivePullRequestActions.SetReminder }, ] export const pullRequestActionPicker = ({ diff --git a/src/views/quickpicks/quickPick.ts b/src/views/quickpicks/quickPick.ts index 75788db..0b0222e 100644 --- a/src/views/quickpicks/quickPick.ts +++ b/src/views/quickpicks/quickPick.ts @@ -1,18 +1,18 @@ import { QuickPickItem, window } from 'vscode' export const QuickPick = { - create: ({ + create: ({ items, title, placeholder, onDidChangeSelection, }: { - items: QuickPickItem[] + items: Type[] title: string placeholder: string - onDidChangeSelection: (selection: readonly QuickPickItem[]) => void + onDidChangeSelection: (selection: readonly Type[]) => void }) => { - const quickPick = window.createQuickPick() + const quickPick = window.createQuickPick() quickPick.items = items quickPick.title = title quickPick.placeholder = placeholder diff --git a/src/views/quickpicks/selectHandlers/pullRequestActionHandler.ts b/src/views/quickpicks/selectHandlers/pullRequestActionHandler.ts index 82deee6..d1288ff 100644 --- a/src/views/quickpicks/selectHandlers/pullRequestActionHandler.ts +++ b/src/views/quickpicks/selectHandlers/pullRequestActionHandler.ts @@ -87,6 +87,12 @@ export const pullRequestActionHandler = async ({ statusBar, }) } + if (selectedItem?.label === ActivePullRequestActions.SetReminder) { + await PullRequestQuickActions.setReminder({ + codeReview: codeReviewItem, + context, + }) + } } const openLink = (link: string) => env.openExternal(Uri.parse(link)) diff --git a/src/views/quickpicks/spaceUserPicker.ts b/src/views/quickpicks/spaceUserPicker.ts index 9a136c4..c73a8c7 100644 --- a/src/views/quickpicks/spaceUserPicker.ts +++ b/src/views/quickpicks/spaceUserPicker.ts @@ -1,6 +1,6 @@ import { ExtensionContext, window } from 'vscode' import { Store } from '../../utils/store' -import { SpaceUser } from '../../utils' +import { SpaceUser, SpaceUserSelectionItem } from '../../utils' import { QuickPick } from './quickPick' export const spaceUserPicker = ({ @@ -12,7 +12,9 @@ export const spaceUserPicker = ({ context: ExtensionContext placeholder: string title: string - onDidChangeSelection: (item: any) => Promise + onDidChangeSelection: ( + item: readonly SpaceUserSelectionItem[] + ) => Promise }) => { const spaceUsers = Store.get(context)?.spaceUsers if (!spaceUsers) { diff --git a/src/views/quickpicks/timePicker.ts b/src/views/quickpicks/timePicker.ts new file mode 100644 index 0000000..1be02d4 --- /dev/null +++ b/src/views/quickpicks/timePicker.ts @@ -0,0 +1,41 @@ +import { QuickPickItem } from 'vscode' +import { QuickPick } from './quickPick' + +export interface TimeSelectionItem extends QuickPickItem { + value: number +} +export const TimeIntervals: TimeSelectionItem[] = [ + { + label: '30 minutes', + value: 30, + }, + { + label: '45 minutes', + value: 45, + }, + { + label: '1 hour', + value: 60, + }, + { + label: '2 hours', + value: 120, + }, +] + +export const timePicker = ({ + title, + onDidChangeSelection, +}: { + title: string + onDidChangeSelection: ( + selection: readonly TimeSelectionItem[] + ) => Promise +}) => { + QuickPick.create({ + items: TimeIntervals, + title, + placeholder: 'Choose time interval', + onDidChangeSelection, + }) +}