databuild/databuild/dashboard/utils.ts
soaxelbrooke bfec05e065
Some checks are pending
/ setup (push) Waiting to run
Big change
2025-07-13 21:18:15 -07:00

101 lines
No EOL
3.3 KiB
TypeScript

// URL encoding utilities for partition references
export function encodePartitionRef(ref: string): string {
return btoa(ref).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
}
export function decodePartitionRef(encoded: string): string {
// Add padding if needed
const padding = '='.repeat((4 - (encoded.length % 4)) % 4);
const padded = encoded.replace(/-/g, '+').replace(/_/g, '/') + padding;
return atob(padded);
}
// Job label encoding utilities (same pattern as partition refs)
export function encodeJobLabel(label: string): string {
return btoa(label).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
}
export function decodeJobLabel(encoded: string): string {
// Add padding if needed
const padding = '='.repeat((4 - (encoded.length % 4)) % 4);
const padded = encoded.replace(/-/g, '+').replace(/_/g, '/') + padding;
return atob(padded);
}
import m from 'mithril';
// Mithril components for status badges - encapsulates both logic and presentation
export const BuildStatusBadge = {
view(vnode: any) {
const { status, size = 'sm', ...attrs } = vnode.attrs;
const normalizedStatus = status.toLowerCase();
let badgeClass = 'badge-neutral';
if (normalizedStatus.includes('completed')) {
badgeClass = 'badge-success';
} else if (normalizedStatus.includes('executing') || normalizedStatus.includes('planning')) {
badgeClass = 'badge-warning';
} else if (normalizedStatus.includes('received')) {
badgeClass = 'badge-info';
} else if (normalizedStatus.includes('failed') || normalizedStatus.includes('cancelled')) {
badgeClass = 'badge-error';
}
return m(`span.badge.badge-${size}.${badgeClass}`, attrs, status);
}
};
export const PartitionStatusBadge = {
view(vnode: any) {
const { status, size = 'sm', ...attrs } = vnode.attrs;
if (!status) {
return m(`span.badge.badge-${size}.badge-neutral`, attrs, 'Unknown');
}
const normalizedStatus = status.toLowerCase();
let badgeClass = 'badge-neutral';
if (normalizedStatus.includes('available')) {
badgeClass = 'badge-success';
} else if (normalizedStatus.includes('building') || normalizedStatus.includes('analyzed')) {
badgeClass = 'badge-warning';
} else if (normalizedStatus.includes('requested') || normalizedStatus.includes('delegated')) {
badgeClass = 'badge-info';
} else if (normalizedStatus.includes('failed')) {
badgeClass = 'badge-error';
}
return m(`span.badge.badge-${size}.${badgeClass}`, attrs, status);
}
};
export const EventTypeBadge = {
view(vnode: any) {
const { eventType, size = 'sm', ...attrs } = vnode.attrs;
let badgeClass = 'badge-ghost';
let displayName = eventType;
switch (eventType) {
case 'build_request':
badgeClass = 'badge-primary';
displayName = 'Build';
break;
case 'job':
badgeClass = 'badge-secondary';
displayName = 'Job';
break;
case 'partition':
badgeClass = 'badge-accent';
displayName = 'Partition';
break;
case 'delegation':
badgeClass = 'badge-info';
displayName = 'Delegation';
break;
}
return m(`span.badge.badge-${size}.${badgeClass}`, attrs, displayName);
}
};