vanta-auditor-tui
Version:
Beautiful terminal UI for exporting Vanta audit evidence with ZIP support and progress tracking
59 lines • 2.61 kB
JavaScript
import React, { useState, useEffect } from 'react';
import { Box, Text } from 'ink';
import { Spinner } from '../lib/inkModules.js';
import { theme } from '../theme.js';
import { AnimatedProgressBar } from './AnimatedProgressBar.js';
const loadingMessages = [
"🦙 Gathering your audit evidence...",
"🦙 Herding the documents...",
"🦙 Organizing compliance artifacts...",
"🦙 Preparing your audit package...",
"🦙 Collecting evidence files...",
];
const authMessages = [
"🦙 Authenticating with Vanta...",
"🦙 Establishing secure connection...",
"🦙 Verifying credentials...",
"🦙 Loading audit data...",
];
export function LoadingSpinner({ message, subMessage, type = 'dots' }) {
const [messageIndex, setMessageIndex] = useState(0);
const [progress, setProgress] = useState(0);
const messages = message ? [message] : (subMessage?.includes('auth') ? authMessages : loadingMessages);
useEffect(() => {
if (messages.length > 1) {
const interval = setInterval(() => {
setMessageIndex((prev) => (prev + 1) % messages.length);
}, 3000);
return () => clearInterval(interval);
}
}, [messages.length]);
// Indeterminate progress animation
useEffect(() => {
const interval = setInterval(() => {
setProgress(prev => {
// Create a wave effect that goes from 0 to 100 and back
const wave = Math.sin(Date.now() / 1000) * 50 + 50;
return wave;
});
}, 50);
return () => clearInterval(interval);
}, []);
return (React.createElement(Box, { flexDirection: "column", paddingY: 1 },
React.createElement(Box, null,
React.createElement(Box, { marginRight: 1 },
React.createElement(Spinner, { type: type })),
React.createElement(Text, { color: theme.colors.primary }, messages[messageIndex])),
subMessage && (React.createElement(Box, { paddingLeft: 3 },
React.createElement(Text, { color: theme.colors.dim }, subMessage))),
React.createElement(Box, { marginTop: 1 },
React.createElement(AnimatedProgressBar, { value: progress, width: 30, showPercentage: false, animationSpeed: 10 }))));
}
export function LoadingOverlay({ isLoading, message, children }) {
if (isLoading) {
return React.createElement(LoadingSpinner, { message: message });
}
return React.createElement(React.Fragment, null, children);
}
export default LoadingSpinner;
//# sourceMappingURL=LoadingSpinner.js.map