Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/components/error-display.tsx
1503 views
1
/*
2
* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
import { Alert } from "antd";
7
8
// use "style" to customize
9
const ELEMENT_STYLE: React.CSSProperties = {
10
overflowY: "auto",
11
} as const;
12
13
// use "body_style" prop to customize
14
const BODY_STYLE: React.CSSProperties = {
15
marginRight: "10px",
16
whiteSpace: "pre-wrap",
17
} as const;
18
19
interface Props {
20
error?: string | object;
21
error_component?: React.JSX.Element | React.JSX.Element[];
22
title?: string;
23
style?: React.CSSProperties;
24
body_style?: React.CSSProperties;
25
componentStyle?: React.CSSProperties;
26
bsStyle?: string;
27
onClose?: () => void;
28
banner?: boolean;
29
}
30
31
export function ErrorDisplay({
32
error,
33
error_component,
34
title,
35
body_style,
36
componentStyle,
37
style,
38
bsStyle,
39
onClose,
40
banner = false,
41
}: Props) {
42
function render_title() {
43
return <h4>{title}</h4>;
44
}
45
46
function render_error() {
47
if (error) {
48
let e = typeof error == "string" ? error : `${error}`;
49
// common prefix with errors due to how they get constructed
50
while (e.startsWith("Error: Error")) {
51
e = e.slice("Error: ".length);
52
}
53
return e;
54
} else {
55
return error_component;
56
}
57
}
58
59
function type(): string {
60
if (
61
// only types that antd has...
62
bsStyle != null &&
63
["success", "info", "warning", "error"].includes(bsStyle)
64
) {
65
return bsStyle;
66
} else {
67
return "error";
68
}
69
}
70
71
function msgdesc() {
72
const body = (
73
<div style={{ ...BODY_STYLE, ...body_style }}>{render_error()}</div>
74
);
75
if (title) {
76
return [render_title(), body];
77
} else {
78
return [body, undefined];
79
}
80
}
81
82
function render_alert() {
83
const [message, description] = msgdesc();
84
// tweak the case where it's not a banner
85
const extra = banner ? undefined : { closable: true, onClose };
86
return (
87
<Alert
88
banner={banner}
89
showIcon
90
style={{ ...ELEMENT_STYLE, ...style }}
91
type={type() as any}
92
message={message}
93
description={description}
94
onClose={onClose}
95
closable={onClose != null || banner}
96
{...extra}
97
/>
98
);
99
}
100
101
return <div style={componentStyle}>{render_alert()}</div>;
102
}
103
104