Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/account/upgrades/project-upgrades-table.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 { Map } from "immutable";
7
import { rclass, redux, rtypes, Component } from "../../app-framework";
8
import { UpgradeAdjustor, r_join } from "../../components";
9
import { PROJECT_UPGRADES } from "@cocalc/util/schema";
10
import { ProjectTitle } from "../../projects/project-title";
11
import { Row, Col, Panel } from "../../antd-bootstrap";
12
import { plural, len, round1 } from "@cocalc/util/misc";
13
14
interface reduxProps {
15
get_total_upgrades: Function;
16
help_email: string;
17
project_map: Map<string, any>;
18
get_total_upgrades_you_have_applied: Function;
19
get_upgrades_you_applied_to_project: Function;
20
get_total_project_quotas: Function;
21
get_upgrades_to_project: Function;
22
get_projects_upgraded_by: Function;
23
}
24
25
interface State {
26
show_adjustor: Map<string, boolean>; // project_id : bool
27
}
28
29
class ProjectUpgradesTable extends Component<reduxProps, State> {
30
static reduxProps() {
31
return {
32
account: {
33
get_total_upgrades: rtypes.func,
34
},
35
customize: {
36
help_email: rtypes.string,
37
},
38
projects: {
39
project_map: rtypes.immutable.Map,
40
get_total_upgrades_you_have_applied: rtypes.func,
41
get_upgrades_you_applied_to_project: rtypes.func,
42
get_total_project_quotas: rtypes.func,
43
get_upgrades_to_project: rtypes.func,
44
get_projects_upgraded_by: rtypes.func,
45
},
46
};
47
}
48
49
constructor(props, state) {
50
super(props, state);
51
this.state = {
52
show_adjustor: Map({}),
53
};
54
}
55
56
open_project_settings(e, project_id: string) {
57
redux.getActions("projects").open_project({
58
project_id,
59
target: "settings",
60
switch_to: !(e.which === 2 || e.ctrlKey || e.metaKey),
61
});
62
e.preventDefault();
63
}
64
65
submit_upgrade_quotas({ project_id, new_quotas }) {
66
redux
67
.getActions("projects")
68
.apply_upgrades_to_project(project_id, new_quotas);
69
this.toggle_adjustor(project_id);
70
}
71
72
generate_on_click_adjust(project_id: string) {
73
return (e) => {
74
e.preventDefault();
75
return this.toggle_adjustor(project_id);
76
};
77
}
78
79
toggle_adjustor(project_id: string) {
80
const status = this.state.show_adjustor.get(project_id);
81
const show_adjustor = this.state.show_adjustor.set(project_id, !status);
82
this.setState({ show_adjustor });
83
}
84
85
private render_upgrades_to_project(project_id: string, upgrades) {
86
const v: React.JSX.Element[] = [];
87
for (let param in upgrades) {
88
const val = upgrades[param];
89
if (!val) {
90
continue;
91
}
92
const info = PROJECT_UPGRADES.params[param];
93
if (info == null) {
94
console.warn(
95
`Invalid upgrades database entry for project_id='${project_id}' -- if this problem persists, email ${this.props.help_email} with the project_id: ${param}`,
96
);
97
continue;
98
}
99
const n = round1(val != null ? info.display_factor * val : 0);
100
v.push(
101
<span key={param}>
102
{info.display}: {n} {plural(n, info.display_unit)}
103
</span>,
104
);
105
}
106
return r_join(v);
107
}
108
109
private render_upgrade_adjustor(project_id: string) {
110
return (
111
<UpgradeAdjustor
112
key={`adjustor-${project_id}`}
113
total_project_quotas={this.props.get_total_project_quotas(project_id)}
114
upgrades_you_can_use={this.props.get_total_upgrades()}
115
upgrades_you_applied_to_all_projects={this.props.get_total_upgrades_you_have_applied()}
116
upgrades_you_applied_to_this_project={this.props.get_upgrades_you_applied_to_project(
117
project_id,
118
)}
119
quota_params={PROJECT_UPGRADES.params}
120
submit_upgrade_quotas={(new_quotas) =>
121
this.submit_upgrade_quotas({ new_quotas, project_id })
122
}
123
cancel_upgrading={() => this.toggle_adjustor(project_id)}
124
style={{ margin: "25px 0px 0px 0px" }}
125
omit_header={true}
126
/>
127
);
128
}
129
130
private render_upgraded_project(project_id: string, upgrades, darker) {
131
return (
132
<Row
133
key={project_id}
134
style={darker ? { backgroundColor: "#eee" } : undefined}
135
>
136
<Col sm={4}>
137
<ProjectTitle
138
project_id={project_id}
139
handle_click={(e) => this.open_project_settings(e, project_id)}
140
/>
141
</Col>
142
<Col sm={8}>
143
<a onClick={this.generate_on_click_adjust(project_id)} role="button">
144
{this.render_upgrades_to_project(project_id, upgrades)}
145
</a>
146
</Col>
147
{this.state.show_adjustor.get(project_id)
148
? this.render_upgrade_adjustor(project_id)
149
: undefined}
150
</Row>
151
);
152
}
153
154
private render_upgraded_projects_rows(upgraded_projects): React.JSX.Element[] {
155
let i = -1;
156
const result: React.JSX.Element[] = [];
157
for (let project_id in upgraded_projects) {
158
const upgrades = upgraded_projects[project_id];
159
i += 1;
160
result.push(
161
this.render_upgraded_project(project_id, upgrades, i % 2 === 0),
162
);
163
}
164
return result;
165
}
166
167
private render_header() {
168
return (
169
<div>
170
<Row>
171
<Col sm={12} style={{ display: "flex" }}>
172
<div style={{ flex: "1" }}>
173
Upgrades you have applied to projects
174
</div>
175
</Col>
176
</Row>
177
</div>
178
);
179
}
180
181
render() {
182
const upgraded_projects = this.props.get_projects_upgraded_by();
183
if (!len(upgraded_projects)) {
184
return null;
185
}
186
return (
187
<Panel header={this.render_header()}>
188
<Row key="header">
189
<Col sm={4}>
190
<strong>Project</strong>
191
</Col>
192
<Col sm={8}>
193
<strong>
194
Upgrades you have applied to this project (click to edit)
195
</strong>
196
</Col>
197
</Row>
198
{this.render_upgraded_projects_rows(upgraded_projects)}
199
</Panel>
200
);
201
}
202
}
203
204
const tmp = rclass(ProjectUpgradesTable);
205
export { tmp as ProjectUpgradesTable };
206
207