✨ feat(vscode): 选工单也列「进行中」列里已经有 PR 的工单(开发完了没走自动审查的),弹框按「审查」「进行中」分组,进审查、刷新、重开窗口按同一条列规则判断
This commit is contained in:
1 parent
f2b17e5389
commit
489d0ef41f
7 files changed
+159
-68
No files matched your search
@@ -1,8 +1,8 @@
|
||||
import type { Issue } from '../../gitea/types'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { boardIssues } from '../../panel/kanbanSnapshot'
|
||||
import { countingFiles, pickEntries, pickItemText, withFileCount } from './pickList'
|
||||
import { inReviewColumn } from './reviewRules'
|
||||
import { countingFiles, pickEntries, pickItemText, pickRows, withFileCount } from './pickList'
|
||||
import { reviewCandidates } from './reviewRules'
|
||||
|
||||
function issue(number: number, title: string, pr?: string): Issue {
|
||||
return { id: `o/r#${number}`, number, title, column: 'review', ...(pr ? { pr } : {}), assignees: [], htmlUrl: `https://x/${number}` }
|
||||
@@ -76,6 +76,29 @@ describe('弹框的各项:先摆出来,文件数读到一个换一个', () =
|
||||
})
|
||||
})
|
||||
|
||||
describe('弹框按列分组', () => {
|
||||
const idle = { ...issue(449, '开发完了没走自动审查', '450'), column: 'in-progress' as const }
|
||||
const older = { ...issue(300, '也停在进行中', '301'), column: 'in-progress' as const }
|
||||
const rows = (entries: ReturnType<typeof pickEntries<Issue>>): (string | number)[] =>
|
||||
pickRows(entries).map(row => 'separator' in row ? row.separator : row.entry.issue.number)
|
||||
|
||||
it('先「审查」一组再「进行中」一组,每组前面一行列名', () => {
|
||||
const entries = pickEntries(reviewCandidates([older, noPr, idle, avatar, settings]), () => false)
|
||||
expect(rows(entries)).toEqual(['审查', 452, 451, 446, '进行中', 449, 300])
|
||||
})
|
||||
|
||||
it('没有工单的列不出标题', () => {
|
||||
expect(rows(pickEntries([idle, older], () => false))).toEqual(['进行中', 449, 300])
|
||||
expect(rows(pickEntries([avatar], () => false))).toEqual(['审查', 446])
|
||||
expect(rows([])).toEqual([])
|
||||
})
|
||||
|
||||
it('读到文件数换掉一项后分组不变', () => {
|
||||
const entries = pickEntries(reviewCandidates([idle, avatar]), () => true)
|
||||
expect(rows(withFileCount(entries, 449, { count: 3 }))).toEqual(['审查', 446, '进行中', 449])
|
||||
})
|
||||
})
|
||||
|
||||
describe('弹框列的工单从哪来', () => {
|
||||
// 存下的看板快照是 JSON,PR 号是字符串
|
||||
const saved = JSON.parse(JSON.stringify({
|
||||
@@ -83,7 +106,8 @@ describe('弹框列的工单从哪来', () => {
|
||||
{ ...issue(460, '已经合并', '461'), column: 'done' },
|
||||
{ ...issue(454, '看板快照里的审查工单', '454'), worktreePath: '~/Sources/worktree/p/x' },
|
||||
{ ...issue(12, 'YouTrack 的审查工单'), source: 'youtrack' },
|
||||
{ ...issue(300, '进行中'), column: 'in-progress' },
|
||||
{ ...issue(300, '进行中、还没有 PR'), column: 'in-progress' },
|
||||
{ ...issue(310, '进行中、已经有 PR', '311'), column: 'in-progress' },
|
||||
],
|
||||
scope: 'all',
|
||||
globalAutoReview: false,
|
||||
@@ -94,11 +118,11 @@ describe('弹框列的工单从哪来', () => {
|
||||
expect(boardIssues([avatar], saved)).toEqual({ issues: [avatar], from: 'loaded' })
|
||||
})
|
||||
|
||||
it('这次还没加载过:用存下的快照;「审查」列的 Gitea 工单照常列出,字符串的 PR 号认得', () => {
|
||||
it('这次还没加载过:用存下的快照;「审查」列和有 PR 的「进行中」列的 Gitea 工单照常列出,字符串的 PR 号认得', () => {
|
||||
const board = boardIssues(undefined, saved)
|
||||
expect(board?.from).toBe('saved')
|
||||
const entries = pickEntries(inReviewColumn(board!.issues), () => false)
|
||||
expect(entries.map(entry => [entry.issue.number, entry.pr?.number])).toEqual([[454, 454]])
|
||||
const entries = pickEntries(reviewCandidates(board!.issues), () => false)
|
||||
expect(entries.map(entry => [entry.issue.number, entry.pr?.number])).toEqual([[454, 454], [310, 311]])
|
||||
})
|
||||
|
||||
it('都没有、快照是坏的:undefined(看板还没加载过)', () => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Issue } from '../../gitea/types'
|
||||
import { prNumberOf } from './reviewRules'
|
||||
import { columnLabel, prNumberOf } from './reviewRules'
|
||||
|
||||
/** PR 改了几个文件:还在读、没读到、读到了。 */
|
||||
export type FileCount = 'loading' | 'failed' | { count: number }
|
||||
@@ -30,6 +30,16 @@ export function withFileCount<T extends Pick<Issue, 'number' | 'title'>>(entries
|
||||
return entries.map(entry => entry.issue.number === issueNumber && entry.pr ? { ...entry, pr: { ...entry.pr, files } } : entry)
|
||||
}
|
||||
|
||||
/** 弹框里的一行:分组标题(列名)或一项。 */
|
||||
export type PickRow<T extends Pick<Issue, 'number' | 'title' | 'column'>> = { separator: string } | { entry: PickEntry<T> }
|
||||
|
||||
/** 给按列排好的各项插上分组标题:列一变先插一行列名(没有工单的列不出标题)。 */
|
||||
export function pickRows<T extends Pick<Issue, 'number' | 'title' | 'column'>>(entries: readonly PickEntry<T>[]): PickRow<T>[] {
|
||||
return entries.flatMap((entry, index) => index > 0 && entries[index - 1].issue.column === entry.issue.column
|
||||
? [{ entry }]
|
||||
: [{ separator: columnLabel(entry.issue.column) }, { entry }])
|
||||
}
|
||||
|
||||
/** 还有 PR 的文件数没读完:弹框接着转圈。 */
|
||||
export function countingFiles(entries: readonly PickEntry<Pick<Issue, 'number' | 'title'>>[]): boolean {
|
||||
return entries.some(entry => entry.pr?.files === 'loading')
|
||||
|
||||
@@ -5,13 +5,13 @@ import type { Issue } from '../../gitea/types'
|
||||
import type { FileNode, FileTreeProvider } from '../explorer/fileTree'
|
||||
import type { FileCount } from './pickList'
|
||||
import * as path from 'node:path'
|
||||
import { commands, Uri, window, workspace } from 'vscode'
|
||||
import { commands, QuickPickItemKind, Uri, window, workspace } from 'vscode'
|
||||
import { logger } from '../../logging/logger'
|
||||
import { ChangeDecorations } from './changeDecorations'
|
||||
import { buildChangedTree, changeOf } from './changedFiles'
|
||||
import { countingFiles, pickEntries, pickItemText, withFileCount } from './pickList'
|
||||
import { reviewableIssue, reviewablePullRequest, reviewDescription, reviewMessage } from './reviewRules'
|
||||
import { loadIssue, loadPullRequest, loadPullRequestFiles, requireRepo, reviewColumnIssues } from './reviewSource'
|
||||
import { countingFiles, pickEntries, pickItemText, pickRows, withFileCount } from './pickList'
|
||||
import { columnLabel, REVIEW_COLUMNS_TEXT, reviewableIssue, reviewablePullRequest, reviewDescription, reviewMessage } from './reviewRules'
|
||||
import { loadIssue, loadPullRequest, loadPullRequestFiles, requireRepo, reviewCandidateIssues } from './reviewSource'
|
||||
import { localWorktree, prepareWorktree } from './reviewWorktree'
|
||||
|
||||
/** workspaceState:正在审查的工单号,重开窗口接着审查。 */
|
||||
@@ -33,8 +33,9 @@ interface Loaded {
|
||||
worktree: string
|
||||
}
|
||||
|
||||
interface IssuePick extends QuickPickItem {
|
||||
issue: Issue
|
||||
/** 弹框里的一行:工单的一项带着工单,分组标题(列名)没有。 */
|
||||
interface PickerItem extends QuickPickItem {
|
||||
issue?: Issue
|
||||
}
|
||||
|
||||
function errorText(err: unknown): string {
|
||||
@@ -42,7 +43,7 @@ function errorText(err: unknown): string {
|
||||
}
|
||||
|
||||
/**
|
||||
* 侧栏按审查工单筛文件:「选工单」列出看板「审查」列的工单,选中后树里只剩这张工单的 PR 改过的文件(按改动着色),
|
||||
* 侧栏按审查工单筛文件:「选工单」列出看板「审查」「进行中」列里能审查的工单,选中后树里只剩这张工单的 PR 改过的文件(按改动着色),
|
||||
* 点开的是本机这张工单的工作副本里 PR 最新的代码;「显示全部」回到工作区文件树。选的工单按工作区记住。
|
||||
*/
|
||||
export class ReviewMode implements Disposable {
|
||||
@@ -80,14 +81,13 @@ export class ReviewMode implements Disposable {
|
||||
return this.reviewing !== undefined
|
||||
}
|
||||
|
||||
/** 「选工单」:顶部弹出快速选择,读看板「审查」列的工单和各自改了几个文件时转圈。 */
|
||||
/**
|
||||
* 「选工单」:顶部弹出快速选择,列出看板上现在摆着的「审查」列工单,马上就有;
|
||||
* 「选工单」:顶部弹出快速选择,列出看板上现在摆着的「审查」「进行中」列里能审查的工单(按列分组),马上就有;
|
||||
* 各 PR 改了几个文件一起去读,读到一个换一项,都读完才停止转圈。
|
||||
*/
|
||||
async pick(): Promise<void> {
|
||||
const picker = window.createQuickPick<IssuePick>()
|
||||
picker.title = '选工单 · 看板「审查」列'
|
||||
const picker = window.createQuickPick<PickerItem>()
|
||||
picker.title = `选工单 · 看板${REVIEW_COLUMNS_TEXT}列`
|
||||
picker.placeholder = '输入工单号或标题筛选'
|
||||
picker.busy = true
|
||||
let open = true
|
||||
@@ -96,11 +96,11 @@ export class ReviewMode implements Disposable {
|
||||
picker.dispose()
|
||||
})
|
||||
picker.onDidAccept(() => {
|
||||
const chosen = picker.selectedItems[0]
|
||||
const chosen = picker.selectedItems[0]?.issue
|
||||
if (!chosen)
|
||||
return
|
||||
picker.hide()
|
||||
void this.review(chosen.issue.number, 'pick')
|
||||
void this.review(chosen.number, 'pick')
|
||||
})
|
||||
picker.show()
|
||||
|
||||
@@ -114,7 +114,7 @@ export class ReviewMode implements Disposable {
|
||||
void window.showErrorMessage(`没法选工单:${errorText(err)}`)
|
||||
return
|
||||
}
|
||||
const board = reviewColumnIssues(this.context)
|
||||
const board = reviewCandidateIssues(this.context)
|
||||
if (!open)
|
||||
return
|
||||
if (!board) {
|
||||
@@ -126,21 +126,23 @@ export class ReviewMode implements Disposable {
|
||||
logger.add({
|
||||
level: 'info',
|
||||
source: 'codeReader',
|
||||
message: `选工单:看板「审查」列 ${board.issues.length} 张(${board.from === 'loaded' ? '看板这次加载的' : '上次存下的看板快照'})`,
|
||||
details: board.issues.map(issue => `#${issue.number} PR ${issue.pr ?? '无'}`).join('\n'),
|
||||
message: `选工单:看板${REVIEW_COLUMNS_TEXT}列能审查的 ${board.issues.length} 张(${board.from === 'loaded' ? '看板这次加载的' : '上次存下的看板快照'})`,
|
||||
details: board.issues.map(issue => `#${issue.number} ${columnLabel(issue.column)} PR ${issue.pr ?? '无'}`).join('\n'),
|
||||
})
|
||||
if (board.issues.length === 0)
|
||||
picker.placeholder = '看板「审查」列里没有工单'
|
||||
picker.placeholder = `看板${REVIEW_COLUMNS_TEXT}列里没有能审查的工单`
|
||||
|
||||
let entries = pickEntries(board.issues, issue => localWorktree(this.context, repo.workspaceRoot, issue) !== undefined)
|
||||
// 换 items 时 VS Code 会把光标挪回第一项:按工单号挪回用户停着的那一项
|
||||
const render = (): void => {
|
||||
if (!open)
|
||||
return
|
||||
const active = picker.activeItems[0]?.issue.number
|
||||
const items = entries.map(entry => ({ issue: entry.issue, ...pickItemText(entry) }))
|
||||
const active = picker.activeItems[0]?.issue?.number
|
||||
const items: PickerItem[] = pickRows(entries).map(row => 'separator' in row
|
||||
? { label: row.separator, kind: QuickPickItemKind.Separator }
|
||||
: { issue: row.entry.issue, ...pickItemText(row.entry) })
|
||||
picker.items = items
|
||||
const stay = items.find(item => item.issue.number === active)
|
||||
const stay = items.find(item => item.issue !== undefined && item.issue.number === active)
|
||||
if (stay)
|
||||
picker.activeItems = [stay]
|
||||
picker.busy = countingFiles(entries)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { inReviewColumn, prNumberOf, reviewableIssue, reviewablePullRequest, reviewDescription, reviewMessage } from './reviewRules'
|
||||
import { columnLabel, prNumberOf, REVIEW_COLUMNS_TEXT, reviewableIssue, reviewablePullRequest, reviewCandidates, reviewDescription, reviewMessage } from './reviewRules'
|
||||
|
||||
const issue = { number: 446, title: '用户资料:上传头像,收紧非管理员改资料的权限' }
|
||||
|
||||
@@ -10,25 +10,43 @@ describe('审查时的视图标题', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('看板「审查」列', () => {
|
||||
it('只要审查列的,工单号大的在前(和看板列里一样)', () => {
|
||||
describe('选工单弹框列哪些工单', () => {
|
||||
it('「审查」列的都列(没 PR 的也列),「进行中」列的只列有 PR 的,别的列不列', () => {
|
||||
const issues = [
|
||||
{ number: 438, column: 'review' as const },
|
||||
{ number: 452, column: 'review' as const },
|
||||
{ number: 452, column: 'review' as const, pr: '455' },
|
||||
{ number: 451, column: 'in-progress' as const },
|
||||
{ number: 446, column: 'review' as const },
|
||||
{ number: 460, column: 'done' as const },
|
||||
{ number: 449, column: 'in-progress' as const, pr: '450' },
|
||||
{ number: 460, column: 'done' as const, pr: '461' },
|
||||
{ number: 470, column: 'todo' as const, pr: '471' },
|
||||
]
|
||||
expect(inReviewColumn(issues).map(item => item.number)).toEqual([452, 446, 438])
|
||||
expect(reviewCandidates(issues).map(item => item.number)).toEqual([452, 438, 449])
|
||||
})
|
||||
|
||||
it('先「审查」一组再「进行中」一组,组里工单号大的在前(和看板列里一样)', () => {
|
||||
const issues = [
|
||||
{ number: 300, column: 'in-progress' as const, pr: '301' },
|
||||
{ number: 438, column: 'review' as const, pr: '440' },
|
||||
{ number: 500, column: 'in-progress' as const, pr: '501' },
|
||||
{ number: 446, column: 'review' as const, pr: '447' },
|
||||
]
|
||||
expect(reviewCandidates(issues).map(item => item.number)).toEqual([446, 438, 500, 300])
|
||||
})
|
||||
|
||||
it('只要 Gitea 的工单(PR 在 Gitea 上),YouTrack 的不算,没写来源的算 Gitea 的', () => {
|
||||
const issues = [
|
||||
{ number: 12, column: 'review' as const, source: 'youtrack' as const },
|
||||
{ number: 13, column: 'in-progress' as const, source: 'youtrack' as const, pr: '14' },
|
||||
{ number: 446, column: 'review' as const, source: 'gitea' as const },
|
||||
{ number: 438, column: 'review' as const },
|
||||
]
|
||||
expect(inReviewColumn(issues).map(item => item.number)).toEqual([446, 438])
|
||||
expect(reviewCandidates(issues).map(item => item.number)).toEqual([446, 438])
|
||||
})
|
||||
|
||||
it('列名:分组标题和连着写的几列', () => {
|
||||
expect(columnLabel('review')).toBe('审查')
|
||||
expect(columnLabel('in-progress')).toBe('进行中')
|
||||
expect(REVIEW_COLUMNS_TEXT).toBe('「审查」「进行中」')
|
||||
})
|
||||
|
||||
it('工单的 PR 号取 state JSON 里的正整数(看板快照里也是字符串)', () => {
|
||||
@@ -42,16 +60,19 @@ describe('看板「审查」列', () => {
|
||||
})
|
||||
|
||||
describe('还能不能审查(选中、刷新、重开窗口时判断)', () => {
|
||||
it('在审查列、有 PR:带上工单和 PR 号', () => {
|
||||
const current = { column: 'review' as const, pr: '447' }
|
||||
expect(reviewableIssue(446, current)).toEqual({ issue: current, pr: 447 })
|
||||
it('在「审查」或「进行中」列、有 PR:带上工单和 PR 号', () => {
|
||||
const inReview = { column: 'review' as const, pr: '447' }
|
||||
const inProgress = { column: 'in-progress' as const, pr: '450' }
|
||||
expect(reviewableIssue(446, inReview)).toEqual({ issue: inReview, pr: 447 })
|
||||
expect(reviewableIssue(449, inProgress)).toEqual({ issue: inProgress, pr: 450 })
|
||||
})
|
||||
|
||||
it('工单没了、离开了审查列、没有 PR:给出原因', () => {
|
||||
it('工单没了、两列都离开了、没有 PR:给出原因', () => {
|
||||
expect(reviewableIssue(446, null)).toEqual({ blocked: '#446 已经不存在' })
|
||||
expect(reviewableIssue(446, { column: 'done', pr: '447' })).toEqual({ blocked: '#446 已经不在看板「审查」列' })
|
||||
expect(reviewableIssue(446, { column: 'in-progress', pr: '447' })).toEqual({ blocked: '#446 已经不在看板「审查」列' })
|
||||
expect(reviewableIssue(446, { column: 'done', pr: '447' })).toEqual({ blocked: '#446 已经不在看板「审查」「进行中」列' })
|
||||
expect(reviewableIssue(446, { column: 'todo', pr: '447' })).toEqual({ blocked: '#446 已经不在看板「审查」「进行中」列' })
|
||||
expect(reviewableIssue(446, { column: 'review' })).toEqual({ blocked: '#446 没有关联 PR' })
|
||||
expect(reviewableIssue(449, { column: 'in-progress' })).toEqual({ blocked: '#449 没有关联 PR' })
|
||||
})
|
||||
|
||||
it('关联的 PR 开着:带上它;没了、合并了、关了:给出原因', () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Issue } from '../../gitea/types'
|
||||
import type { Issue, IssueColumn } from '../../gitea/types'
|
||||
|
||||
/** 工单关联的 PR 号;state JSON 里没有、或不是正整数时没有。 */
|
||||
export function prNumberOf(issue: Pick<Issue, 'pr'>): number | undefined {
|
||||
@@ -6,19 +6,50 @@ export function prNumberOf(issue: Pick<Issue, 'pr'>): number | undefined {
|
||||
return Number.isInteger(pr) && pr > 0 ? pr : undefined
|
||||
}
|
||||
|
||||
/** 看板「审查」列里的 Gitea 工单(PR 在 Gitea 上,YouTrack 的不算),照看板列里的次序(工单号大的在前)。 */
|
||||
export function inReviewColumn<T extends Pick<Issue, 'number' | 'column' | 'source'>>(issues: readonly T[]): T[] {
|
||||
return issues
|
||||
.filter(issue => issue.column === 'review' && (issue.source ?? 'gitea') === 'gitea')
|
||||
.sort((a, b) => b.number - a.number)
|
||||
/**
|
||||
* 能拿来审查的看板列,也是选工单弹框里分组的次序:先「审查」,再「进行中」
|
||||
* (开发完了、没走自动审查,停在「进行中」的工单)。
|
||||
*/
|
||||
export const REVIEW_COLUMNS: readonly { column: IssueColumn, label: string }[] = [
|
||||
{ column: 'review', label: '审查' },
|
||||
{ column: 'in-progress', label: '进行中' },
|
||||
]
|
||||
|
||||
/** 这几列连着写:「审查」「进行中」。 */
|
||||
export const REVIEW_COLUMNS_TEXT = REVIEW_COLUMNS.map(({ label }) => `「${label}」`).join('')
|
||||
|
||||
/** 列的名字(选工单弹框的分组标题)。 */
|
||||
export function columnLabel(column: IssueColumn): string {
|
||||
return REVIEW_COLUMNS.find(item => item.column === column)?.label ?? column
|
||||
}
|
||||
|
||||
/** 这张工单(最新状态,工单已经不存在时 null)现在能不能审查:能时带上它和它的 PR 号,不能时给出原因(给人看的话)。 */
|
||||
function inReviewColumns(column: IssueColumn): boolean {
|
||||
return REVIEW_COLUMNS.some(item => item.column === column)
|
||||
}
|
||||
|
||||
/**
|
||||
* 选工单弹框列哪些工单:只要 Gitea 的(PR 在 Gitea 上,YouTrack 的不算);「审查」列的都列(没 PR 的选中时说一声),
|
||||
* 「进行中」列的只列已经有 PR 的(没 PR 的还在开发,列出来只会添乱)。按列分组(REVIEW_COLUMNS 的次序),
|
||||
* 组里工单号大的在前(和看板列里一样)。
|
||||
*/
|
||||
export function reviewCandidates<T extends Pick<Issue, 'number' | 'column' | 'source' | 'pr'>>(issues: readonly T[]): T[] {
|
||||
const order = (issue: T): number => REVIEW_COLUMNS.findIndex(item => item.column === issue.column)
|
||||
return issues
|
||||
.filter(issue => (issue.source ?? 'gitea') === 'gitea'
|
||||
&& inReviewColumns(issue.column)
|
||||
&& (issue.column === 'review' || prNumberOf(issue) !== undefined))
|
||||
.sort((a, b) => order(a) - order(b) || b.number - a.number)
|
||||
}
|
||||
|
||||
/**
|
||||
* 这张工单(最新状态,工单已经不存在时 null)现在能不能审查:在「审查」「进行中」列、有 PR 才能,
|
||||
* 能时带上它和它的 PR 号,不能时给出原因(给人看的话)。选中、刷新、重开窗口接着审查都按它判断。
|
||||
*/
|
||||
export function reviewableIssue<T extends Pick<Issue, 'column' | 'pr'>>(issueNumber: number, issue: T | null): { issue: T, pr: number } | { blocked: string } {
|
||||
if (!issue)
|
||||
return { blocked: `#${issueNumber} 已经不存在` }
|
||||
if (issue.column !== 'review')
|
||||
return { blocked: `#${issueNumber} 已经不在看板「审查」列` }
|
||||
if (!inReviewColumns(issue.column))
|
||||
return { blocked: `#${issueNumber} 已经不在看板${REVIEW_COLUMNS_TEXT}列` }
|
||||
const pr = prNumberOf(issue)
|
||||
if (pr === undefined)
|
||||
return { blocked: `#${issueNumber} 没有关联 PR` }
|
||||
|
||||
@@ -13,7 +13,7 @@ import { loadSingleIssue } from '../../gitea/issueLoader'
|
||||
import { resolveRepoContext } from '../../gitea/repoContext'
|
||||
import { overlayLocalIssueState } from '../../issues/localState'
|
||||
import { KanbanWebviewPanel } from '../../panel/KanbanPanel'
|
||||
import { inReviewColumn } from './reviewRules'
|
||||
import { reviewCandidates } from './reviewRules'
|
||||
|
||||
/** 当前工作区的 Gitea 仓库和 token;没有时抛出给人看的错。 */
|
||||
export async function requireRepo(context: ExtensionContext): Promise<RepoContext> {
|
||||
@@ -24,12 +24,12 @@ export async function requireRepo(context: ExtensionContext): Promise<RepoContex
|
||||
}
|
||||
|
||||
/**
|
||||
* 看板「审查」列里的工单:取看板上现在摆着的(用户看到的就是它),不再加载一遍;
|
||||
* 选工单弹框列的工单(哪些列、哪些工单见 reviewCandidates):取看板上现在摆着的(用户看到的就是它),不再加载一遍;
|
||||
* 看板还没加载过时 undefined。进审查时再单独重读选中的那张(loadIssue)。
|
||||
*/
|
||||
export function reviewColumnIssues(context: ExtensionContext): BoardIssues | undefined {
|
||||
export function reviewCandidateIssues(context: ExtensionContext): BoardIssues | undefined {
|
||||
const board = KanbanWebviewPanel.issuesOnBoard(context)
|
||||
return board && { ...board, issues: inReviewColumn(board.issues) }
|
||||
return board && { ...board, issues: reviewCandidates(board.issues) }
|
||||
}
|
||||
|
||||
/** 一张工单的最新状态;工单已经不存在时 null。 */
|
||||
|
||||
Reference in new issue
Block a user