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

0% Statements 0/81
0% Branches 0/1
0% Functions 0/1
0% Lines 0/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 82                                                                                                                                                                   
/**
 * 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>
    );
}