Skip to content

Commit b124b36

Browse files
committed
make applying a license to a project slightly more discoverable
1 parent dfef472 commit b124b36

File tree

8 files changed

+78
-64
lines changed

8 files changed

+78
-64
lines changed

src/packages/frontend/account/licenses/licenses-page.tsx

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
* License: MS-RSL – see LICENSE.md for details
44
*/
55

6-
import { React } from "@cocalc/frontend/app-framework";
76
import { Footer } from "@cocalc/frontend/customize";
87
import { BuyLicenseForProject } from "@cocalc/frontend/site-licenses/purchase/buy-license-for-project";
98
import { DOC_LICENSE_URL } from "../../billing/data";
@@ -12,20 +11,23 @@ import { ProjectsWithLicenses } from "./projects-with-licenses";
1211
import Next from "@cocalc/frontend/components/next";
1312
import { A } from "@cocalc/frontend/components/A";
1413

15-
export const LicensesPage: React.FC = () => {
14+
export function LicensesPage() {
1615
return (
17-
<div>
16+
<div style={{ maxWidth: "1000px", margin: "auto" }}>
1817
<div style={{ fontSize: "12pt" }}>
1918
<h3>About</h3>
2019
<A href={DOC_LICENSE_URL}>Licenses</A> allow you to automatically
2120
upgrade projects whenever they start up, so that they have more memory,
22-
better hosting, run faster, etc.
21+
run faster, etc.
2322
</div>
2423
<br />
2524
<div>
26-
<BuyLicenseForProject />
25+
<BuyLicenseForProject noVoucher />
2726
</div>
27+
<ManagedLicenses />
28+
<ProjectsWithLicenses />
2829
<div>
30+
{/* kind of outdated */}
2931
<h3>Links</h3>
3032
<ul style={{ fontSize: "12pt" }}>
3133
<li>
@@ -45,12 +47,7 @@ export const LicensesPage: React.FC = () => {
4547
</li>
4648
</ul>
4749
</div>
48-
<br />
49-
<ManagedLicenses />
50-
<br />
51-
<ProjectsWithLicenses />
52-
<br />
5350
<Footer />
5451
</div>
5552
);
56-
};
53+
}

src/packages/frontend/account/licenses/managed-licenses.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ export const ManagedLicenses: React.FC = () => {
120120
return (
121121
<>
122122
<Title level={3}>
123-
Licenses that you manage {render_count()}
123+
Licenses You Manage {render_count()}
124124
<div style={{ float: "right" }}>{render_show_all()}</div>
125125
{loading && <Spin />}
126126
</Title>
@@ -148,7 +148,8 @@ function CancelSubscriptionBanner() {
148148
visit the Subscription tab above
149149
</a>
150150
. To edit a license <i>that you purchased</i> expand the license
151-
below, then click on the "Edit License..." button.
151+
below, then click on the "Edit License..." button. To apply a license
152+
to a project, select the project under Projects below.
152153
</>
153154
}
154155
/>

src/packages/frontend/account/licenses/projects-with-licenses.tsx

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,27 @@
33
* License: MS-RSL – see LICENSE.md for details
44
*/
55

6-
import { Row, Col } from "antd";
7-
import {
8-
React,
9-
useMemo,
10-
useTypedRedux,
11-
useEffect,
12-
redux,
13-
} from "../../app-framework";
6+
import { Alert, Row, Col } from "antd";
7+
import { useEffect, useMemo, useState } from "react";
8+
import { useTypedRedux, redux } from "../../app-framework";
149
import { Loading, TimeAgo } from "../../components";
1510
import { projects_with_licenses } from "./util";
1611
import { plural, trunc_middle } from "@cocalc/util/misc";
1712
import { LICENSES_STYLE } from "./managed-licenses";
1813
import { Virtuoso } from "react-virtuoso";
14+
import { SelectProject } from "@cocalc/frontend/projects/select-project";
15+
import { SiteLicense } from "@cocalc/frontend/project/settings/site-license";
1916

20-
function open_project(project_id: string): void {
21-
redux.getActions("projects").open_project({ project_id });
22-
redux.getProjectActions(project_id).set_active_tab("settings");
23-
}
24-
25-
export const ProjectsWithLicenses: React.FC = () => {
17+
export function ProjectsWithLicenses({}) {
18+
const [project_id, setProjectId] = useState<string | undefined>(undefined);
2619
const project_map = useTypedRedux("projects", "project_map");
2720
const all_projects_have_been_loaded = useTypedRedux(
2821
"projects",
29-
"all_projects_have_been_loaded"
22+
"all_projects_have_been_loaded",
3023
);
3124
const projects = useMemo(
3225
() => projects_with_licenses(project_map),
33-
[project_map]
26+
[project_map],
3427
);
3528

3629
useEffect(() => {
@@ -47,7 +40,7 @@ export const ProjectsWithLicenses: React.FC = () => {
4740
key={projects[index]?.project_id}
4841
style={{ borderBottom: "1px solid lightgrey", cursor: "pointer" }}
4942
onClick={() => {
50-
open_project(project_id);
43+
setProjectId(project_id);
5144
}}
5245
>
5346
<Col span={12} style={{ paddingLeft: "15px" }}>
@@ -74,7 +67,7 @@ export const ProjectsWithLicenses: React.FC = () => {
7467
}
7568
return (
7669
<div
77-
style={{ ...LICENSES_STYLE, height: "50vh" }}
70+
style={{ ...LICENSES_STYLE, height: "175px", marginTop: "5px" }}
7871
className={"smc-vfill"}
7972
>
8073
<Virtuoso
@@ -86,16 +79,32 @@ export const ProjectsWithLicenses: React.FC = () => {
8679
);
8780
}
8881

89-
function render_count() {
90-
if (projects == null || projects.length == 0) return;
91-
return <>({projects.length})</>;
92-
}
93-
9482
return (
9583
<div>
96-
{" "}
97-
<h3>Projects with licenses {render_count()}</h3>
84+
<h3>Projects</h3>
85+
<Alert
86+
style={{ marginBottom: "15px" }}
87+
banner
88+
type="info"
89+
message={
90+
<>
91+
Select a project below to add or remove a license from that project,
92+
or to buy a license for that project.
93+
</>
94+
}
95+
/>
96+
<SelectProject value={project_id} onChange={setProjectId} />
97+
{project_id && project_map && (
98+
<SiteLicense
99+
project_id={project_id}
100+
site_license={project_map.getIn([project_id, "site_license"]) as any}
101+
/>
102+
)}
103+
<div style={{ marginTop: "10px" }}>
104+
The following {projects.length} {plural(projects.length, "project")}{" "}
105+
have a license:
106+
</div>
98107
{render_projects_with_license()}
99108
</div>
100109
);
101-
};
110+
}

src/packages/frontend/project/settings/site-license.tsx

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import {
3232
} from "@cocalc/util/upgrades/quota";
3333
import { isBoostLicense } from "@cocalc/util/upgrades/utils";
3434
import { SiteLicense as SiteLicenseT } from "./types";
35+
import { ProjectTitle } from "@cocalc/frontend/projects/project-title";
3536

3637
interface Props {
3738
project_id: string;
@@ -60,8 +61,11 @@ export async function applyLicense(opts: ALOpts): Promise<void> {
6061
}
6162
}
6263

63-
export const SiteLicense: React.FC<Props> = (props: Props) => {
64-
const { project_id, site_license, mode = "project" } = props;
64+
export function SiteLicense({
65+
project_id,
66+
site_license,
67+
mode = "project",
68+
}: Props) {
6569
const isFlyout = mode === "flyout";
6670

6771
const intl = useIntl();
@@ -191,7 +195,12 @@ export const SiteLicense: React.FC<Props> = (props: Props) => {
191195
<Icon name="key" /> {intl.formatMessage(labels.licenses)}
192196
{isFlyout ? (
193197
<span style={{ float: "right" }}>{render_extra()}</span>
194-
) : undefined}
198+
) : (
199+
<>
200+
{" "}
201+
- <ProjectTitle project_id={project_id} />
202+
</>
203+
)}
195204
</Title>
196205
);
197206
}
@@ -267,4 +276,4 @@ export const SiteLicense: React.FC<Props> = (props: Props) => {
267276
</Card>
268277
);
269278
}
270-
};
279+
}

src/packages/frontend/project/settings/upgrade-usage.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -365,8 +365,11 @@ export const UpgradeUsage: React.FC<Props> = React.memo(
365365
}
366366

367367
function render_site_license(): Rendered {
368-
// site licenses are also used in on-prem setups to tweak project quotas
369-
if (!in_kucalc) return;
368+
if (!in_kucalc) {
369+
// site licenses are also used in on-prem setups to tweak project quotas, but
370+
// nowhere else (currently).
371+
return;
372+
}
370373
return (
371374
<SiteLicense
372375
project_id={project_id}

src/packages/frontend/projects/select-project.tsx

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,7 @@
66
// Component for selecting a project.
77

88
import { Checkbox, Select } from "antd";
9-
import {
10-
CSS,
11-
redux,
12-
React,
13-
useMemo,
14-
useState,
15-
useTypedRedux,
16-
} from "../app-framework";
9+
import { CSS, redux, useMemo, useState, useTypedRedux } from "../app-framework";
1710
import { webapp_client } from "../webapp-client";
1811
import { Loading } from "../components";
1912

@@ -28,18 +21,18 @@ interface Props {
2821
style?: CSS;
2922
}
3023

31-
export const SelectProject: React.FC<Props> = ({
24+
export function SelectProject({
3225
exclude,
3326
at_top,
3427
onChange,
3528
value,
3629
defaultValue,
3730
style,
38-
}) => {
31+
}: Props) {
3932
const project_map = useTypedRedux("projects", "project_map");
4033
const all_projects_have_been_loaded = useTypedRedux(
4134
"projects",
42-
"all_projects_have_been_loaded"
35+
"all_projects_have_been_loaded",
4336
);
4437

4538
// include deleted projects in the selector
@@ -106,7 +99,7 @@ export const SelectProject: React.FC<Props> = ({
10699
}
107100
}
108101
return data.concat(others);
109-
}, [project_map, exclude, at_top, include_deleted, include_hidden]);
102+
}, [project_map, exclude, at_top, include_deleted, include_hidden, value]);
110103

111104
if (data == null) {
112105
return <Loading />;
@@ -116,6 +109,7 @@ export const SelectProject: React.FC<Props> = ({
116109
<div style={style}>
117110
<div style={{ display: "flex", flexDirection: "row" }}>
118111
<Select
112+
allowClear
119113
style={{ marginRight: "15px", flex: 1 }}
120114
showSearch={true}
121115
placeholder={"Select a project..."}
@@ -164,4 +158,4 @@ export const SelectProject: React.FC<Props> = ({
164158
</div>
165159
</div>
166160
);
167-
};
161+
}

src/packages/frontend/site-licenses/purchase/buy-license-for-project.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
import { Button, Space } from "antd";
77
import { join } from "path";
8-
98
import { CSS, useTypedRedux } from "@cocalc/frontend/app-framework";
109
import { A, Icon } from "@cocalc/frontend/components";
1110
import { appBasePath } from "@cocalc/frontend/customize/app-base-path";
@@ -20,17 +19,19 @@ interface Props {
2019
style?: CSS;
2120
size?: "small" | "middle" | "large";
2221
wrap?: boolean;
22+
noVoucher?: boolean;
2323
}
2424

25-
export const BuyLicenseForProject: React.FC<Props> = ({
25+
export function BuyLicenseForProject({
2626
project_id,
2727
buyText = "Buy a license",
2828
voucherText = "Redeem a voucher",
2929
asLink = false,
3030
style,
3131
size = "large",
3232
wrap = false,
33-
}: Props) => {
33+
noVoucher,
34+
}: Props) {
3435
const commercial = useTypedRedux("customize", "commercial");
3536

3637
function url(path): string {
@@ -102,8 +103,8 @@ export const BuyLicenseForProject: React.FC<Props> = ({
102103
return (
103104
<Space wrap={wrap}>
104105
{renderBuyButton()}
105-
{renderVoucherButton()}
106+
{!noVoucher && renderVoucherButton()}
106107
</Space>
107108
);
108109
}
109-
};
110+
}

src/packages/frontend/site-licenses/purchase/purchase.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -726,7 +726,7 @@ export const PurchaseOneLicense: React.FC<Props> = React.memo(({ onClose }) => {
726726
/>
727727
You should see it listed under{" "}
728728
<A href={join(appBasePath, "/licenses/managed")}>
729-
Licenses that you manage
729+
Licenses You Manage
730730
</A>
731731
.
732732
</div>

0 commit comments

Comments
 (0)