All files / blong-browser/src/components/Error Error.tsx

81.48% Statements 66/81
57.14% Branches 4/7
25% Functions 1/4
81.48% Lines 66/81

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 821x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x     1x 8x 8x 8x 8x 8x 8x 8x                           8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x  
/**
 * Error — global error dialog.
 */
import {Dialog} from '../../primereact/index.js';
 
import {useBlong} from '../../context/BlongContext.js';
import {useAppStore} from '../../state/appStore.js';
import {Button} from '../Button/Button.js';
 
/**
 * Error types that indicate an expired or invalid session.
 */
const AUTH_ERROR_TYPES = new Set([
    'identity.unauthenticated',
    'identity.invalidCredentials',
    'identity.sessionExpired',
]);
 
function isAuthError(type?: string) {
    return !!type && AUTH_ERROR_TYPES.has(type);
}
 
export function ErrorDialog() {
    const error = useAppStore(s => s.error);
    const clearError = useAppStore(s => s.clearError);
    const {config: {portal}} = useBlong();
    const loginRoute = portal?.loginRoute;
 
    if (!error) return null;
 
    const unauthorized = isAuthError(error.type);
 
    const handleLogin = () => {
        clearError();
        if (loginRoute) window.location.href = loginRoute;
    };
 
    return (
        <Dialog
            visible
            header={
                <span className="blong-error-dialog__title">
                    <i className="pi pi-exclamation-circle blong-error-dialog__icon" /> Error
                </span>
            }
            onHide={unauthorized ? () => {} : clearError}
            closable={!unauthorized}
            className="blong-error-dialog"
            style={{width: '480px'}}
            modal
        >
            <div className="blong-error-dialog__body">
                <p className="blong-error-dialog__message">{error.print ?? error.message}</p>
                {error.validation && error.validation.length > 0 && (
                    <ul className="blong-error-dialog__validation">
                        {error.validation.map(v => (
                            <li key={v.field}>
                                <strong>{v.field}:</strong> {v.message}
                            </li>
                        ))}
                    </ul>
                )}
            </div>
            <div className="blong-error-dialog__footer">
                {unauthorized ? (
                    <Button
                        label="Login"
                        icon="pi pi-sign-in"
                        onClick={handleLogin}
                    />
                ) : (
                    <Button
                        label="Close"
                        icon="pi pi-times"
                        onClick={clearError}
                    />
                )}
            </div>
        </Dialog>
    );
}