Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/app/connection-status.tsx
1496 views
1
import { Badge, Progress, Descriptions, Typography, Space, Alert } from "antd";
2
import {
3
CheckCircleOutlined,
4
CloseCircleOutlined,
5
SendOutlined,
6
DownloadOutlined,
7
UsergroupAddOutlined,
8
DatabaseOutlined,
9
} from "@ant-design/icons";
10
import type { ConatConnectionStatus } from "@cocalc/frontend/conat/client";
11
import { capitalize } from "@cocalc/util/misc";
12
import { MAX_SUBSCRIPTIONS_PER_CLIENT } from "@cocalc/conat/core/constants";
13
14
let MAX_SEND_MESSAGES = 1000,
15
MAX_SEND_BYTES = 1_000_000;
16
let MAX_RECV_MESSAGES = 2000,
17
MAX_RECV_BYTES = 10_000_000;
18
19
function bytesToStr(bytes: number): string {
20
if (bytes < 1024) return bytes + " B";
21
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + " KB";
22
return (bytes / (1024 * 1024)).toFixed(2) + " MB";
23
}
24
25
export function ConnectionStatsDisplay({
26
status,
27
hub,
28
}: {
29
status: ConatConnectionStatus;
30
hub?: string;
31
}) {
32
const connected = status.state === "connected";
33
const statusText = connected
34
? `Connected${hub ? " to hub " + hub : ""}`
35
: "Disconnected";
36
const statusColor = connected ? "green" : "red";
37
38
const icon = connected ? <CheckCircleOutlined /> : <CloseCircleOutlined />;
39
40
if (MAX_SEND_MESSAGES <= status.stats.send.messages) {
41
MAX_SEND_MESSAGES *= 1.2;
42
}
43
if (MAX_SEND_BYTES <= status.stats.send.bytes) {
44
MAX_SEND_BYTES *= 1.2;
45
}
46
if (MAX_RECV_MESSAGES <= status.stats.recv.messages) {
47
MAX_RECV_MESSAGES *= 1.2;
48
}
49
if (MAX_RECV_BYTES <= status.stats.recv.bytes) {
50
MAX_RECV_BYTES *= 1.2;
51
}
52
53
if (status?.stats == null) {
54
return null;
55
}
56
57
return (
58
<Space direction="vertical" size="large" style={{ width: "100%" }}>
59
<Typography.Title level={5}>
60
<Badge status={statusColor as any} text={statusText} /> {icon}
61
</Typography.Title>
62
63
{!connected && !!status.reason && (
64
<Alert
65
message={capitalize(status.reason)}
66
type="warning"
67
showIcon
68
style={{ marginBottom: 10 }}
69
/>
70
)}
71
72
<Descriptions bordered size="middle" column={1}>
73
<Descriptions.Item
74
label={
75
<>
76
<SendOutlined /> Messages sent
77
</>
78
}
79
>
80
<Progress
81
percent={Math.min(
82
100,
83
(100 * status.stats.send.messages) / MAX_SEND_MESSAGES,
84
)}
85
size="small"
86
status="active"
87
strokeColor="#1890ff"
88
format={() => `${status.stats.send.messages}`}
89
/>
90
</Descriptions.Item>
91
<Descriptions.Item
92
label={
93
<>
94
<DatabaseOutlined /> Bytes sent
95
</>
96
}
97
>
98
<Progress
99
percent={Math.min(
100
100,
101
(100 * status.stats.send.bytes) / MAX_SEND_BYTES,
102
)}
103
size="small"
104
status="active"
105
strokeColor="#40a9ff"
106
format={() => bytesToStr(status.stats.send.bytes)}
107
/>
108
</Descriptions.Item>
109
<Descriptions.Item
110
label={
111
<>
112
<DownloadOutlined /> Messages received
113
</>
114
}
115
>
116
<Progress
117
percent={Math.min(
118
100,
119
(100 * status.stats.recv.messages) / MAX_RECV_MESSAGES,
120
)}
121
size="small"
122
strokeColor="#52c41a"
123
status="active"
124
format={() => `${status.stats.recv.messages}`}
125
/>
126
</Descriptions.Item>
127
<Descriptions.Item
128
label={
129
<>
130
<DatabaseOutlined /> Bytes received
131
</>
132
}
133
>
134
<Progress
135
percent={Math.min(
136
100,
137
(100 * status.stats.recv.bytes) / MAX_RECV_BYTES,
138
)}
139
size="small"
140
strokeColor="#73d13d"
141
status="active"
142
format={() => bytesToStr(status.stats.recv.bytes)}
143
/>
144
</Descriptions.Item>
145
<Descriptions.Item
146
label={
147
<>
148
<UsergroupAddOutlined /> Subscriptions
149
</>
150
}
151
>
152
<Progress
153
percent={Math.min(
154
100,
155
(100 * status.stats.subs) / MAX_SUBSCRIPTIONS_PER_CLIENT,
156
)}
157
size="small"
158
strokeColor="purple"
159
status="active"
160
format={() => `${status.stats.subs}`}
161
/>
162
</Descriptions.Item>
163
</Descriptions>
164
165
{/* Optionally, details debugging */}
166
{status.details && (
167
<Typography.Paragraph
168
copyable
169
code
170
style={{ maxHeight: 120, overflow: "auto", marginTop: 12 }}
171
>
172
{JSON.stringify(status.details, null, 2)}
173
</Typography.Paragraph>
174
)}
175
</Space>
176
);
177
}
178
179