Files
superwork/vscode/src/panel/kanbanSnapshot.ts
T

62 lines
2.3 KiB
TypeScript

import type { Issue } from '../gitea/types'
export const KANBAN_SNAPSHOT_KEY = 'superpowers.kanbanSnapshot'
export interface KanbanSnapshot {
issues: Issue[]
scope: 'mine' | 'all'
me?: string
/** Gitea login → 头像 data URI;团队视图下卡片按人贴头像。 */
avatars?: Record<string, string>
globalAutoReview: boolean
youtrackConfigured: boolean
}
function isAvatarMap(raw: unknown): raw is Record<string, string> {
return !!raw && typeof raw === 'object' && Object.values(raw).every(v => typeof v === 'string')
}
export function parseKanbanSnapshot(raw: unknown): KanbanSnapshot | null {
if (!raw || typeof raw !== 'object')
return null
const obj = raw as Record<string, unknown>
if (!Array.isArray(obj.issues))
return null
if (obj.scope !== 'mine' && obj.scope !== 'all')
return null
return {
issues: obj.issues as Issue[],
scope: obj.scope,
me: typeof obj.me === 'string' ? obj.me : undefined,
avatars: isAvatarMap(obj.avatars) ? obj.avatars : undefined,
globalAutoReview: obj.globalAutoReview === true,
youtrackConfigured: obj.youtrackConfigured === true,
}
}
/** 看板上现在摆着的工单,和它从哪来:面板这次会话里加载好的(loaded)、上次存下的快照(saved)。 */
export interface BoardIssues {
issues: Issue[]
from: 'loaded' | 'saved'
}
/**
* 看板上现在摆着的工单:面板这次会话里加载好了就用它最近一次加载的,否则用上次存下的快照
* (重开窗口时看板先画的也是它);都没有时 undefined,看板还没加载过。
*/
export function boardIssues(loaded: Issue[] | undefined, persisted: unknown): BoardIssues | undefined {
if (loaded)
return { issues: loaded, from: 'loaded' }
const snapshot = parseKanbanSnapshot(persisted)
return snapshot ? { issues: snapshot.issues, from: 'saved' } : undefined
}
/** 写入 HTML 的 JSON:小于号换成 \\u003c,避免 script 标签被提前关掉。 */
export function snapshotToScriptJson(snapshot: KanbanSnapshot): string {
return JSON.stringify(snapshot).replace(/</g, '\\u003c')
}
export function snapshotScriptTag(nonce: string, snapshot: KanbanSnapshot): string {
return `<script nonce="${nonce}" type="application/json" id="kanban-snapshot">${snapshotToScriptJson(snapshot)}</script>`
}