Sort active provisioning jobs by progress

This commit is contained in:
2026-10-08 12:09:18 -04:00
parent a33b897cd0
commit 26de43639f
3 changed files with 89 additions and 1 deletions
+19 -1
View File
@@ -15,6 +15,7 @@ import { canCancelProvisioningJob, provisioningCancelled } from './cancellation.
import { nativeDeployment } from '../backends/native.js';
import { safetyOverride, safetyOverrideAvailability } from './safety-override.js';
import { serverTitle } from '../../ui/server-labels.js';
import { provisioningQueueStatus } from '../../ui/provisioning-queue.js';
import { provisioningPageSize, provisioningPageOffset, type ProvisioningListOptions, type ProvisioningListPage, type ProvisioningListRow } from '../../provisioning-list.js';
export function beginDeployment(server: string, action: ProvisioningAction, triggeredBy = 'ui'): string {
@@ -301,11 +302,28 @@ function deploymentListQuery(options: ProvisioningListOptions) {
limit: provisioningPageSize(options.limit ?? 25), offset: provisioningPageOffset(options.offset ?? 0) };
}
function activeDeploymentRank(row: ProvisioningListRow): number {
const { group } = provisioningQueueStatus(row);
if (group === 'verifying') return 0;
if (group === 'running') return 1;
// Launch preparation keeps its queued/waiting state until command submission.
if (row.phase === 'prepare' && !row.waitCode) return 1;
// Remote file staging currently records its progress only in the stage message.
if (row.waitCode === 'native-host' && ['Staging and verifying files on the host.',
'Waiting for verified remote file staging.'].includes(row.stage)) return 1;
if (group === 'queued') return 3;
// A submitted command remains in progress while its agent result is pending.
if (row.state === 'running' && row.phase === 'container-action' && row.waitCode === 'native-host') return 1;
return 2;
}
function deploymentListRows(query: ReturnType<typeof deploymentListQuery>, active: boolean): ProvisioningListRow[] {
const rows = db().prepare(`SELECT ${deploymentListColumns} FROM server_deployments d WHERE ${query.where}
ORDER BY d.started_at DESC, d.rowid DESC ${active ? '' : 'LIMIT ? OFFSET ?'}`)
ORDER BY ${active ? 'd.started_at ASC, d.rowid ASC' : 'd.started_at DESC, d.rowid DESC LIMIT ? OFFSET ?'}`)
.all(REMOVING_SERVER, ...query.parameters, ...(active ? [] : [query.limit, query.offset])) as ProvisioningListRow[];
if (!rows.length) return rows;
// Stable sorting keeps request/insertion order within each progress group.
if (active) rows.sort((left, right) => activeDeploymentRank(left) - activeDeploymentRank(right));
const links = db().prepare(`SELECT operation_id,kind,source_id FROM provisioning_sources
WHERE operation_id IN (SELECT value FROM json_each(?)) ORDER BY kind,source_id`).all(JSON.stringify(rows.map(row => row.id))) as
(Omit<ProvisioningSource, 'label' | 'href'> & { operation_id: string })[];