CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/next/components/store/add-to-cart.tsx
Views: 687
1
/*
2
* This file is part of CoCalc: Copyright © 2022 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
import {
7
delete_local_storage,
8
get_local_storage,
9
} from "@cocalc/frontend/misc/local-storage";
10
import { getDedicatedDiskKey, PRICES } from "@cocalc/util/upgrades/dedicated";
11
import apiPost from "lib/api/post";
12
import { LS_KEY_LICENSE_PROJECT } from "./util";
13
import { ALL_FIELDS } from "./quota-query-params";
14
15
// these are the hidden type fields of the forms
16
// regular and boost end up as "quota" types
17
// where the description.boost flag is true or false
18
export type LicenseTypeInForms = "regular" | "boost" | "vm" | "disk";
19
20
interface Props {
21
form: any;
22
router: any;
23
setCartError: (msg: string) => void;
24
}
25
26
// this is used by the "addBox" and the thin "InfoBar" to add/modify the selected license configuration to the cart
27
28
export async function addToCart(props: Props) {
29
const { form, setCartError, router } = props;
30
31
// we make a copy, because otherwise this actually modifies the fields (user sees brief red errors)
32
const description = {
33
...form.getFieldsValue(true),
34
};
35
36
// exclude extra fields that are for UI only. See https://github.com/sagemathinc/cocalc/issues/6258
37
for (const field in description) {
38
if (!ALL_FIELDS.has(field)) {
39
delete description[field];
40
}
41
}
42
43
// unload the type parameter
44
switch (description.type) {
45
case "boost":
46
description.boost = true;
47
description.type = "quota";
48
break;
49
50
case "vm":
51
for (const k of ["disk-name", "disk-size_gb", "disk-speed"]) {
52
delete description[k];
53
}
54
const machine = description["vm-machine"];
55
if (PRICES.vms[machine] == null) {
56
setCartError(`Unknown machine type ${machine}`);
57
return;
58
}
59
description.dedicated_vm = {
60
machine,
61
};
62
delete description["vm-machine"];
63
description.type = "vm";
64
break;
65
66
case "disk":
67
delete description["vm-machine"];
68
69
const diskID = getDedicatedDiskKey({
70
size_gb: description["disk-size_gb"],
71
speed: description["disk-speed"],
72
});
73
const disk = PRICES.disks[diskID];
74
if (disk == null) {
75
setCartError(`Disk ${diskID} not found`);
76
return;
77
}
78
description.dedicated_disk = {
79
...disk.quota.dedicated_disk,
80
name: description["disk-name"],
81
};
82
for (const k of ["disk-name", "disk-size_gb", "disk-speed"]) {
83
delete description[k];
84
}
85
86
description.type = "disk";
87
break;
88
89
case "regular":
90
default:
91
description.type = "quota";
92
description.boost = false;
93
}
94
95
try {
96
setCartError("");
97
if (router.query.id != null) {
98
await apiPost("/shopping/cart/edit", {
99
id: router.query.id,
100
description,
101
});
102
} else {
103
// we get the project_id from local storage and save it to the new/edited license
104
const project_id = get_local_storage(LS_KEY_LICENSE_PROJECT);
105
delete_local_storage(LS_KEY_LICENSE_PROJECT);
106
107
await apiPost("/shopping/cart/add", {
108
product: "site-license",
109
description,
110
project_id,
111
});
112
}
113
router.push("/store/cart");
114
} catch (err) {
115
setCartError(err.message);
116
}
117
}
118
119