mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 16:02:32 +00:00
* fix: reordered default columns in kanban board * Introduce dedicated flag to repair reversed default workspace statuses - Add `_workspaceStatusesReorderedDefaultRepaired` to decouple the one-shot repair from the initial status order migration. - Ensure the repair runs for users who saved the reversed default payload (with "Done" on the left) during a short-lived broken build. - Support both "Completed" and "Done" labels when identifying default status shapes to migrate or repair. --------- Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
84 lines
2.7 KiB
TypeScript
84 lines
2.7 KiB
TypeScript
const DEFAULT_STATUS_LABELS: Record<string, readonly string[]> = {
|
|
todo: ['Todo'],
|
|
'in-progress': ['In progress'],
|
|
'in-review': ['In review'],
|
|
// Why: both labels have shipped as defaults; either raw shape is safe to migrate.
|
|
completed: ['Completed', 'Done']
|
|
}
|
|
|
|
const CONDUCTOR_DEFAULT_STATUS_VISUALS: Record<string, { color: string; icon: string }> = {
|
|
todo: { color: 'neutral', icon: 'circle' },
|
|
'in-progress': { color: 'conductor-progress', icon: 'conductor-progress' },
|
|
'in-review': { color: 'conductor-review', icon: 'conductor-review' },
|
|
completed: { color: 'conductor-done', icon: 'conductor-done' }
|
|
}
|
|
|
|
const LEGACY_DEFAULT_STATUS_VISUALS: Record<string, { color: string; icon: string }> = {
|
|
todo: { color: 'neutral', icon: 'circle' },
|
|
'in-progress': { color: 'blue', icon: 'circle-dot' },
|
|
'in-review': { color: 'violet', icon: 'git-pull-request' },
|
|
completed: { color: 'emerald', icon: 'circle-check' }
|
|
}
|
|
|
|
const LEGACY_TODO_FIRST_DEFAULT_STATUS_IDS = [
|
|
'todo',
|
|
'in-progress',
|
|
'in-review',
|
|
'completed'
|
|
] as const
|
|
const WORKFLOW_DEFAULT_STATUS_IDS = ['completed', 'in-review', 'in-progress', 'todo'] as const
|
|
|
|
function isLegacyDefaultStatusPayload(
|
|
value: unknown,
|
|
orderedIds: readonly string[],
|
|
visuals: Record<string, { color: string; icon: string }>
|
|
): boolean {
|
|
if (!Array.isArray(value) || value.length !== orderedIds.length) {
|
|
return false
|
|
}
|
|
return value.every((rawStatus, index) => {
|
|
if (!rawStatus || typeof rawStatus !== 'object' || Array.isArray(rawStatus)) {
|
|
return false
|
|
}
|
|
const raw = rawStatus as Record<string, unknown>
|
|
const expectedId = orderedIds[index]!
|
|
const expectedVisual = visuals[expectedId]
|
|
return (
|
|
Object.keys(raw).length === 4 &&
|
|
raw.id === expectedId &&
|
|
DEFAULT_STATUS_LABELS[expectedId]?.includes(raw.label as string) === true &&
|
|
raw.color === expectedVisual?.color &&
|
|
raw.icon === expectedVisual?.icon
|
|
)
|
|
})
|
|
}
|
|
|
|
export function isLegacyDefaultWorkflowStatusPayload(value: unknown): boolean {
|
|
return (
|
|
isLegacyDefaultStatusPayload(
|
|
value,
|
|
LEGACY_TODO_FIRST_DEFAULT_STATUS_IDS,
|
|
CONDUCTOR_DEFAULT_STATUS_VISUALS
|
|
) ||
|
|
isLegacyDefaultStatusPayload(
|
|
value,
|
|
LEGACY_TODO_FIRST_DEFAULT_STATUS_IDS,
|
|
LEGACY_DEFAULT_STATUS_VISUALS
|
|
) ||
|
|
isLegacyDefaultStatusPayload(
|
|
value,
|
|
WORKFLOW_DEFAULT_STATUS_IDS,
|
|
CONDUCTOR_DEFAULT_STATUS_VISUALS
|
|
) ||
|
|
isLegacyDefaultStatusPayload(value, WORKFLOW_DEFAULT_STATUS_IDS, LEGACY_DEFAULT_STATUS_VISUALS)
|
|
)
|
|
}
|
|
|
|
export function isKnownBadPRReorderedDefaultStatusPayload(value: unknown): boolean {
|
|
return isLegacyDefaultStatusPayload(
|
|
value,
|
|
WORKFLOW_DEFAULT_STATUS_IDS,
|
|
CONDUCTOR_DEFAULT_STATUS_VISUALS
|
|
)
|
|
}
|