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/frontend/account/licenses/projects-with-licenses.tsx
Views: 687
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, Col, Row } from "antd";
7
import { useEffect, useMemo, useState } from "react";
8
import { Virtuoso } from "react-virtuoso";
9
10
import { redux, useTypedRedux } from "@cocalc/frontend/app-framework";
11
import { Loading, TimeAgo } from "@cocalc/frontend/components";
12
import { SiteLicense } from "@cocalc/frontend/project/settings/site-license";
13
import { SelectProject } from "@cocalc/frontend/projects/select-project";
14
import { plural, trunc_middle } from "@cocalc/util/misc";
15
import { LICENSES_STYLE } from "./managed-licenses";
16
import { projects_with_licenses } from "./util";
17
18
export function ProjectsWithLicenses({}) {
19
const [project_id, setProjectId] = useState<string | undefined>(undefined);
20
const project_map = useTypedRedux("projects", "project_map");
21
const all_projects_have_been_loaded = useTypedRedux(
22
"projects",
23
"all_projects_have_been_loaded",
24
);
25
const projects = useMemo(
26
() => projects_with_licenses(project_map),
27
[project_map],
28
);
29
30
useEffect(() => {
31
if (!all_projects_have_been_loaded) {
32
// Mounted this component, but all projects aren't loaded, so ensure they get loaded.
33
redux.getActions("projects").load_all_projects();
34
}
35
}, []);
36
37
function sanitize(s: any): string {
38
return typeof s === "string" ? s : "";
39
}
40
41
function row_renderer({ index }) {
42
const { project_id, last_edited, num_licenses } = projects[index];
43
const project_title = sanitize(project_map?.getIn([project_id, "title"]));
44
return (
45
<Row
46
key={projects[index]?.project_id}
47
style={{ borderBottom: "1px solid lightgrey", cursor: "pointer" }}
48
onClick={() => {
49
setProjectId(project_id);
50
}}
51
>
52
<Col span={12} style={{ paddingLeft: "15px" }}>
53
<a>{trunc_middle(project_title, 80)}</a>
54
</Col>
55
<Col span={6}>
56
{num_licenses} {plural(num_licenses, "License")}
57
</Col>
58
<Col span={6}>{last_edited && <TimeAgo date={last_edited} />}</Col>
59
</Row>
60
);
61
}
62
63
function render_projects_with_license() {
64
if (projects == null || projects.length == 0) {
65
return (
66
<span>
67
You do not have any licensed projects yet. Please purchase a license
68
or apply a license to one of your projects in Project Settings.
69
</span>
70
);
71
}
72
return (
73
<div
74
style={{ ...LICENSES_STYLE, height: "175px", marginTop: "5px" }}
75
className={"smc-vfill"}
76
>
77
<Virtuoso
78
totalCount={projects.length}
79
itemContent={(index) => row_renderer({ index })}
80
/>
81
{!all_projects_have_been_loaded && <Loading theme={"medium"} />}
82
</div>
83
);
84
}
85
86
return (
87
<div>
88
<h3>Projects</h3>
89
<Alert
90
style={{ marginBottom: "15px" }}
91
banner
92
type="info"
93
message={
94
<>
95
Select a project below to add or remove a license from that project,
96
or to buy a license for that project.
97
</>
98
}
99
/>
100
<SelectProject value={project_id} onChange={setProjectId} />
101
{project_id && project_map && (
102
<SiteLicense
103
project_id={project_id}
104
site_license={project_map.getIn([project_id, "site_license"]) as any}
105
/>
106
)}
107
<div style={{ marginTop: "10px" }}>
108
The following {projects.length} {plural(projects.length, "project")}{" "}
109
have a license:
110
</div>
111
{render_projects_with_license()}
112
</div>
113
);
114
}
115
116