Line data Source code
1 : import * as React from 'react';
2 : import * as styles from './log_viewer.module.css';
3 :
4 : import { XIcon, ChevronUpIcon, ChevronDownIcon } from '../foundations/symbol_icon.js';
5 :
6 : import { LogRecord } from '../../platform/logger/log_buffer.js';
7 : import { ButtonVariant, IconButton } from '../foundations/button.js';
8 : import { AnchoredOverlay } from '../foundations/anchored_overlay.js';
9 : import { OverlaySize } from '../foundations/overlay.js';
10 : import { AnchorAlignment, AnchorSide } from '../foundations/anchored_position.js';
11 : import { JsonView } from '../json/json_view.js';
12 :
13 : export interface LogJsonModalProps {
14 : record: LogRecord | null;
15 : recordIndex: number;
16 : maxIndex: number;
17 : anchorRef: React.RefObject<HTMLElement | null>;
18 : returnFocusRef?: React.RefObject<HTMLElement | null>;
19 : align?: AnchorAlignment;
20 : side?: AnchorSide;
21 : onClose: () => void;
22 : onPrevious: () => void;
23 : onNext: () => void;
24 : }
25 :
26 1 : export const LogJsonModal: React.FC<LogJsonModalProps> = (props) => {
27 1 : const beforeCopy = React.useCallback((copyText: string, _keyName?: string | number, value?: object) => {
28 : // If the value is a string, remove the JSON quotes and unescape
29 0 : if (typeof value === 'string') {
30 0 : return value;
31 : }
32 0 : return copyText;
33 1 : }, []);
34 :
35 1 : return (
36 1 : <AnchoredOverlay
37 1 : renderAnchor={null}
38 1 : anchorRef={props.anchorRef}
39 1 : returnFocusRef={props.returnFocusRef}
40 1 : open={props.record !== null}
41 1 : onClose={() => props.onClose()}
42 1 : width={OverlaySize.L}
43 1 : align={props.align ?? AnchorAlignment.End}
44 1 : side={props.side ?? AnchorSide.OutsideLeft}
45 : >
46 1 : <div className={styles.json_modal}>
47 1 : <div className={styles.json_modal_main}>
48 1 : <div className={styles.json_modal_content}>
49 1 : {props.record && <JsonView value={props.record as object} variant="explorer" beforeCopy={beforeCopy} />}
50 1 : </div>
51 1 : </div>
52 1 : <div className={styles.json_modal_sidebar}>
53 1 : <div className={styles.json_modal_sidebar_top}>
54 1 : <IconButton
55 1 : variant={ButtonVariant.Invisible}
56 1 : aria-label="Close"
57 1 : onClick={props.onClose}
58 : >
59 1 : <XIcon />
60 1 : </IconButton>
61 1 : </div>
62 1 : <div className={styles.json_modal_sidebar_bottom}>
63 1 : <IconButton
64 1 : variant={ButtonVariant.Invisible}
65 1 : aria-label="Previous log"
66 1 : onClick={props.onPrevious}
67 1 : disabled={props.recordIndex <= 0}
68 : >
69 1 : <ChevronUpIcon />
70 1 : </IconButton>
71 1 : <IconButton
72 1 : variant={ButtonVariant.Invisible}
73 1 : aria-label="Next log"
74 1 : onClick={props.onNext}
75 1 : disabled={props.recordIndex >= props.maxIndex}
76 : >
77 1 : <ChevronDownIcon />
78 1 : </IconButton>
79 1 : </div>
80 1 : </div>
81 1 : </div>
82 1 : </AnchoredOverlay>
83 : );
84 1 : };
|