Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/compute/automatic-shutdown.tsx
1503 views
1
/*
2
Configuration to automate turning server off via backend maintenance task involving many
3
different rules:
4
5
- idle timeout
6
- spend limit
7
8
*/
9
10
import {
11
Alert,
12
Button,
13
Card,
14
Checkbox,
15
Flex,
16
Modal,
17
Popconfirm,
18
Space,
19
Spin,
20
Switch,
21
} from "antd";
22
import { useState } from "react";
23
import Inline from "./inline";
24
import { IdleTimeout } from "./idle-timeout";
25
import { SpendLimit } from "./spend-limit";
26
import { HealthCheck } from "./health-check";
27
import { ShutdownTime } from "./shutdown-time";
28
import ShowError from "@cocalc/frontend/components/error";
29
import { Icon } from "@cocalc/frontend/components";
30
31
export function AutomaticShutdownCard(props) {
32
return (
33
<Card
34
styles={{
35
body: props.enabled ? undefined : { display: "none" },
36
title: { fontSize: "15px" },
37
}}
38
title={<CardTitle {...props} />}
39
>
40
{props.children}
41
<ShowError
42
error={props.error}
43
setError={props.setError}
44
style={{ width: "100%", marginTop: "15px" }}
45
/>
46
</Card>
47
);
48
}
49
50
function CardTitle({
51
icon,
52
title,
53
enabled,
54
setEnabled,
55
saving,
56
setSaving,
57
setError,
58
save,
59
hasUnsavedChanges,
60
savedEnabled,
61
confirmSave = false,
62
}) {
63
const [justSaved, setJustSaved] = useState<boolean>(false);
64
const doSave = async () => {
65
try {
66
setSaving(true);
67
setJustSaved(true);
68
await save();
69
} catch (err) {
70
setError(`${err}`);
71
} finally {
72
setSaving(false);
73
setTimeout(() => {
74
setJustSaved(false);
75
}, 1000);
76
}
77
};
78
let saveButton = (
79
<Button
80
type="primary"
81
disabled={saving || !hasUnsavedChanges || justSaved}
82
onClick={confirmSave ? undefined : doSave}
83
>
84
<Icon name="save" /> Save{" "}
85
{saving && <Spin style={{ marginLeft: "5px" }} delay={500} />}
86
</Button>
87
);
88
if (confirmSave) {
89
saveButton = (
90
<Popconfirm title={confirmSave} onConfirm={doSave}>
91
{saveButton}
92
</Popconfirm>
93
);
94
}
95
return (
96
<Flex style={{ alignItems: "center" }}>
97
<div
98
style={{
99
width: "150px",
100
overflow: "hidden",
101
textOverflow: "ellipsis",
102
}}
103
>
104
<Icon name={icon as any} style={{ marginRight: "10px" }} /> {title}
105
</div>
106
<div style={{ flex: 1 }} />
107
<Space>
108
<Checkbox
109
disabled={saving}
110
checked={enabled}
111
onChange={(e) => {
112
setEnabled(e.target.checked);
113
}}
114
>
115
Enable{enabled ? "d" : ""}
116
</Checkbox>
117
{saveButton}
118
</Space>
119
<div style={{ flex: 1 }} />
120
<div style={{ marginLeft: "15px", width: "105px" }}>
121
{savedEnabled ? (
122
<Alert type="success" showIcon message={"Enabled"} />
123
) : undefined}
124
</div>
125
</Flex>
126
);
127
}
128
129
export function AutomaticShutdownModal({ id, project_id, close }) {
130
const [help, setHelp] = useState<boolean>(false);
131
return (
132
<Modal
133
width={900}
134
open
135
onCancel={close}
136
onOk={close}
137
cancelText="Close"
138
okButtonProps={{ style: { display: "none" } }}
139
title={
140
<div>
141
<Inline
142
id={id}
143
style={{
144
display: "block",
145
textAlign: "center",
146
margin: "-5px 15px 5px 0",
147
}}
148
/>
149
<Flex style={{ marginRight: "20px", alignItems: "center" }}>
150
<div style={{ fontSize: "18px", margin: "15px 0" }}>
151
Configure Automatic Shutdown and Health Check Strategies
152
</div>
153
<div style={{ flex: 1 }} />
154
<Switch
155
checkedChildren={"Help"}
156
unCheckedChildren={"Help"}
157
checked={help}
158
onChange={(val) => setHelp(val)}
159
/>
160
</Flex>
161
{help && (
162
<div style={{ fontSize: "14px", fontWeight: "normal" }}>
163
<Button
164
href="https://youtu.be/Kx_47fs_xcI"
165
target="_blank"
166
style={{ float: "right" }}
167
>
168
<Icon name="youtube" style={{ color: "red" }} />
169
YouTube Video
170
</Button>
171
Each strategy automatically turns this compute server off when a
172
condition is met. This can save you money keeping spending under
173
control. When the server is shutdown, a message is also sent and a
174
log entry is created.
175
</div>
176
)}
177
</div>
178
}
179
>
180
<IdleTimeout id={id} project_id={project_id} help={help} />
181
<div style={{ height: "15px" }} />
182
<ShutdownTime id={id} project_id={project_id} help={help} />
183
<div style={{ height: "15px" }} />
184
<SpendLimit id={id} project_id={project_id} help={help} />
185
<div style={{ height: "15px" }} />
186
<HealthCheck id={id} project_id={project_id} help={help} />
187
</Modal>
188
);
189
}
190
191