mirror of
https://github.com/stablyai/orca.git
synced 2026-09-21 16:02:20 +00:00
Fix inactive workspace scan loading copy (#2577)
Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
@@ -231,6 +231,8 @@ Apply one of these to overflow containers; don't write a fourth style.
|
||||
|
||||
These are the rules a contributor will most often get wrong if they're working in isolation. They apply to every UI change.
|
||||
|
||||
**UI copy must not overclaim.** Never imply the app has taken an action, made a decision, or observed a fact unless the code has real state or result data to support it. Use neutral process language while work is pending, and reserve result verbs like "skipped", "protected", "found", "verified", or "deleted" for actual results.
|
||||
|
||||
### 1. Match in-flight feedback to perceived duration
|
||||
|
||||
The right question isn't *"should this control change while it's working?"* — it's *"how long does the action take, and what does the user need to know during that time?"*
|
||||
|
||||
@@ -44,21 +44,6 @@ const TIER_LABELS: Record<WorkspaceCleanupTier, string> = {
|
||||
|
||||
type CleanupView = WorkspaceCleanupTier | 'hidden'
|
||||
|
||||
const SCAN_LOADING_STEPS = [
|
||||
{
|
||||
title: 'Finding inactive workspaces',
|
||||
detail: 'Listing old worktrees before any cleanup decision is made.'
|
||||
},
|
||||
{
|
||||
title: 'Checking git safety',
|
||||
detail: 'Looking for changed files and commits that only exist locally.'
|
||||
},
|
||||
{
|
||||
title: 'Protecting active work',
|
||||
detail: 'Skipping workspaces with open tabs, terminals, live agents, or unavailable remotes.'
|
||||
}
|
||||
] as const
|
||||
|
||||
const BLOCKER_LABELS: Record<WorkspaceCleanupBlocker, string> = {
|
||||
'main-worktree': 'Main workspace',
|
||||
'folder-repo': 'Folder project',
|
||||
@@ -202,7 +187,6 @@ export default function WorkspaceCleanupDialog(): React.JSX.Element {
|
||||
const [removing, setRemoving] = useState(false)
|
||||
const [rowFailures, setRowFailures] = useState<Record<string, string>>({})
|
||||
const [repoSelection, setRepoSelection] = useState<ReadonlySet<string>>(() => new Set())
|
||||
const [loadingStepIndex, setLoadingStepIndex] = useState(0)
|
||||
const eligibleRepos = useMemo(() => repos.filter((repo) => isGitRepoKind(repo)), [repos])
|
||||
const eligibleRepoIds = useMemo(() => eligibleRepos.map((repo) => repo.id), [eligibleRepos])
|
||||
|
||||
@@ -225,19 +209,6 @@ export default function WorkspaceCleanupDialog(): React.JSX.Element {
|
||||
setRepoSelection(new Set(eligibleRepoIds))
|
||||
}, [eligibleRepoIds, open])
|
||||
|
||||
useEffect(() => {
|
||||
if (!open || !loading) {
|
||||
setLoadingStepIndex(0)
|
||||
return
|
||||
}
|
||||
|
||||
const timer = window.setInterval(() => {
|
||||
setLoadingStepIndex((index) => (index + 1) % SCAN_LOADING_STEPS.length)
|
||||
}, 2600)
|
||||
|
||||
return () => window.clearInterval(timer)
|
||||
}, [loading, open])
|
||||
|
||||
const candidates = useMemo(() => scan?.candidates ?? [], [scan?.candidates])
|
||||
const effectiveRepoSelection = useMemo<ReadonlySet<string>>(() => {
|
||||
if (repoSelection.size > 0 || eligibleRepoIds.length === 0) {
|
||||
@@ -318,7 +289,6 @@ export default function WorkspaceCleanupDialog(): React.JSX.Element {
|
||||
const inactiveCount = filteredCandidates.length
|
||||
const hasAnyCandidates = candidates.length > 0
|
||||
const initialLoading = loading && !scan
|
||||
const loadingStep = SCAN_LOADING_STEPS[loadingStepIndex]
|
||||
const activeRows = activeView === 'hidden' ? hiddenCandidates : groups[activeView]
|
||||
const activeQueueableRows = useMemo(
|
||||
() => activeRows.filter(canQueueWorkspaceCleanupCandidate),
|
||||
@@ -511,8 +481,13 @@ export default function WorkspaceCleanupDialog(): React.JSX.Element {
|
||||
<div className="flex items-start gap-2 border-b border-border bg-muted/25 px-5 py-3">
|
||||
<Loader2 className="mt-0.5 size-3.5 shrink-0 animate-spin text-muted-foreground" />
|
||||
<div className="min-w-0">
|
||||
<div className="text-xs font-medium text-foreground">{loadingStep.title}</div>
|
||||
<div className="mt-0.5 text-xs text-muted-foreground">{loadingStep.detail}</div>
|
||||
<div className="text-xs font-medium text-foreground">
|
||||
Checking workspace safety
|
||||
</div>
|
||||
<div className="mt-0.5 text-xs text-muted-foreground">
|
||||
Scanning worktrees and git state, then combining open tab, terminal, live agent,
|
||||
and remote availability signals before suggesting deletions.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : hasAnyCandidates ? (
|
||||
|
||||
Reference in New Issue
Block a user