Line data Source code
1 : import * as dashql from '@ankoh/dashql-core';
2 : import * as React from 'react';
3 :
4 : import * as baseStyles from '../ui/foundations/banner_page.module.css';
5 : import * as styles from './core_panic_overlay.module.css';
6 :
7 : import { Button, ButtonVariant } from '../ui/foundations/button.js';
8 : import { useAppRestart } from '../platform/crosstab/app_hand_over.js';
9 : import { useLogger } from '../platform/logger/logger_provider.js';
10 :
11 1 : const LOG_CTX = 'core';
12 :
13 : /// Block the app after a panic of the core and ask for a reload.
14 : /// The core stays unusable after a panic, the restart flushes the storage writers before it reloads.
15 1 : export function CorePanicOverlay(props: { subscribe?: typeof dashql.onCorePanic }) {
16 1 : const logger = useLogger();
17 1 : const restart = useAppRestart();
18 1 : const subscribe = props.subscribe ?? dashql.onCorePanic;
19 1 : const [message, setMessage] = React.useState<string | null>(null);
20 1 : React.useEffect(() => subscribe(panic => {
21 1 : logger.error("Core panicked", { message: panic }, LOG_CTX);
22 1 : setMessage(current => current ?? panic);
23 1 : }), [logger, subscribe]);
24 :
25 1 : if (message == null) return null;
26 1 : return (
27 1 : <div className={styles.overlay} data-testid="core-panic">
28 1 : <div className={`${baseStyles.card} ${styles.card}`}>
29 1 : <div className={baseStyles.card_header}>
30 1 : <div className={baseStyles.card_header_left_container}>
31 1 : <div className={baseStyles.card_header_left_title}>
32 : Reload Required
33 1 : </div>
34 1 : </div>
35 1 : </div>
36 1 : <div className={baseStyles.card_section}>
37 1 : <div className={`${baseStyles.section_entries} ${styles.description}`}>
38 : DashQL hit an internal error and cannot continue. Your saved changes are kept, reload to continue.
39 1 : <div className={styles.message}>{message}</div>
40 1 : </div>
41 1 : <div className={baseStyles.card_actions}>
42 1 : <div className={baseStyles.card_actions_right}>
43 1 : <Button
44 1 : variant={ButtonVariant.Primary}
45 1 : data-testid="core-panic-reload"
46 1 : onClick={() => void restart()}
47 1 : >
48 : Reload
49 1 : </Button>
50 1 : </div>
51 1 : </div>
52 1 : </div>
53 1 : </div>
54 1 : </div>
55 : );
56 1 : }
|