Skip to content

Commit 9b0e913

Browse files
committed
fix #7721 -- Make it clear that the license is required when creating a project
1 parent 1b4a22a commit 9b0e913

File tree

4 files changed

+82
-93
lines changed

4 files changed

+82
-93
lines changed

src/packages/frontend/project/trial-banner.tsx

Lines changed: 46 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -439,44 +439,7 @@ function CountdownProject({ fontSize }: CountdownProjectProps) {
439439
<Paragraph strong>
440440
This shutdown timer only exists for projects without any upgrades!
441441
</Paragraph>
442-
<Alert
443-
banner
444-
type="info"
445-
showIcon={false}
446-
message={
447-
<>
448-
<Paragraph strong>
449-
This is a call to support <SiteName /> by{" "}
450-
<A href={BUY_A_LICENSE_URL}>purchasing a license</A>.
451-
</Paragraph>
452-
<Paragraph>
453-
Behind the curtain,{" "}
454-
<A href={"/about/team"}>humans are working hard</A> to keep the
455-
service running and improving it constantly. Your files and
456-
computations <A href={"/info/status"}>run in our cluster</A>,
457-
which costs money as well.
458-
</Paragraph>
459-
<Paragraph>
460-
<SiteName /> receives no funding from large organizations or
461-
charitable foundations. The site depends entirely{" "}
462-
<Text strong>on your financial support</Text> to continue
463-
operating. Without your financial support this service will not
464-
survive long-term!
465-
</Paragraph>
466-
<Paragraph>
467-
<A
468-
href={
469-
"/support/new?hideExtra=true&type=purchase&subject=Support+CoCalc&title=Support+CoCalc"
470-
}
471-
>
472-
Contact us
473-
</A>{" "}
474-
if you can give support in other ways or have any questions or
475-
comments.
476-
</Paragraph>
477-
</>
478-
}
479-
/>
442+
<CallToSupport />
480443
</Modal>
481444
);
482445
}
@@ -512,3 +475,48 @@ function CountdownProject({ fontSize }: CountdownProjectProps) {
512475
</>
513476
);
514477
}
478+
479+
export function CallToSupport({ onClose }: { onClose? }) {
480+
return (
481+
<Alert
482+
closable={onClose != null}
483+
onClose={onClose}
484+
banner
485+
type="info"
486+
showIcon={false}
487+
message={
488+
<>
489+
<Paragraph strong>
490+
This is a call to support <SiteName /> by{" "}
491+
<A href={BUY_A_LICENSE_URL}>purchasing a license</A>.
492+
</Paragraph>
493+
<Paragraph>
494+
Behind the scenes,{" "}
495+
<A href={"/about/team"}>people are working hard</A> to keep the
496+
service running and improve it constantly. Your files and
497+
computations <A href={"/info/status"}>run in our cluster</A>, which
498+
costs money as well.
499+
</Paragraph>
500+
<Paragraph>
501+
<SiteName /> receives no funding from large organizations or
502+
charitable foundations. The site depends entirely{" "}
503+
<Text strong>on your financial support</Text> to continue operating.
504+
Without your financial support this service will not survive
505+
long-term!
506+
</Paragraph>
507+
<Paragraph>
508+
<A
509+
href={
510+
"/support/new?hideExtra=true&type=purchase&subject=Support+CoCalc&title=Support+CoCalc"
511+
}
512+
>
513+
Contact us
514+
</A>{" "}
515+
if you can give support in other ways or have any questions or
516+
comments.
517+
</Paragraph>
518+
</>
519+
}
520+
/>
521+
);
522+
}

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

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,6 @@ export const NewProjectCreator: React.FC<Props> = ({
5252
start_in_edit_mode,
5353
default_value,
5454
}: Props) => {
55-
const managed_licenses = useTypedRedux("billing", "managed_licenses");
56-
5755
// view --> edit --> saving --> view
5856
const [state, set_state] = useState<EditState>(
5957
start_in_edit_mode ? "edit" : "view",
@@ -63,13 +61,9 @@ export const NewProjectCreator: React.FC<Props> = ({
6361
const [show_advanced, set_show_advanced] = useState<boolean>(false);
6462
const [title_prefill, set_title_prefill] = useState<boolean>(false);
6563
const [license_id, set_license_id] = useState<string>("");
66-
const [warnBoost, setWarnBoost] = useState<boolean>(false);
67-
6864
const [custom_software, set_custom_software] =
6965
useState<SoftwareEnvironmentState>({});
70-
7166
const new_project_title_ref = useRef(null);
72-
7367
const is_anonymous = useTypedRedux("account", "is_anonymous");
7468
const customize_kucalc = useTypedRedux("customize", "kucalc");
7569
const hasLegacyUpgrades = redux.getStore("account").hasLegacyUpgrades();
@@ -282,8 +276,6 @@ export const NewProjectCreator: React.FC<Props> = ({
282276
}
283277

284278
function addSiteLicense(lic: string): void {
285-
const license = managed_licenses?.get(lic)?.toJS();
286-
setWarnBoost(license?.quota?.boost === true);
287279
set_license_id(lic);
288280
}
289281

@@ -295,7 +287,7 @@ export const NewProjectCreator: React.FC<Props> = ({
295287
title={
296288
<>
297289
<div style={{ float: "right" }}>
298-
<BuyLicenseForProject size="small" />
290+
<BuyLicenseForProject />
299291
</div>
300292
<Icon name="key" /> Select License
301293
</>
@@ -306,14 +298,8 @@ export const NewProjectCreator: React.FC<Props> = ({
306298
requireValid
307299
confirmLabel={"Add this license"}
308300
onChange={addSiteLicense}
301+
requireLicense
309302
/>
310-
{warnBoost && (
311-
<Alert bsStyle="warning">
312-
This license is for boosting on top of an already applied and active
313-
license. This one alone will not provide any upgrades to this
314-
project!
315-
</Alert>
316-
)}
317303
</Card>
318304
);
319305
}

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

Lines changed: 7 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
// Inputing a site license, e.g., for a project, course, etc.
77

88
import {
9-
CSS,
10-
React,
119
redux,
1210
useEffect,
1311
useTypedRedux,
@@ -25,47 +23,18 @@ export function useManagedLicenses() {
2523
return managedLicenses;
2624
}
2725

28-
interface Props {
29-
onSave?: (licenseId: string) => void;
30-
onCancel?: () => void;
31-
onChange?: (licenseId: string) => void;
32-
confirmLabel?: string;
33-
exclude?: string[];
34-
style?: CSS;
35-
extra?: React.ReactNode;
36-
extraButtons?: React.ReactNode;
37-
requireValid?: boolean;
38-
}
39-
40-
export const SiteLicenseInput: React.FC<Props> = (props: Props) => {
41-
const {
42-
onSave,
43-
onCancel,
44-
onChange,
45-
exclude,
46-
style,
47-
confirmLabel = "Apply License",
48-
extra,
49-
extraButtons,
50-
requireValid,
51-
} = props;
52-
26+
export function SiteLicenseInput(props) {
5327
const managedLicenses = useManagedLicenses();
5428

55-
if (managedLicenses == null) return <Loading />;
29+
if (managedLicenses == null) {
30+
return <Loading />;
31+
}
5632

5733
return (
5834
<SelectLicense
59-
onSave={onSave}
60-
onCancel={onCancel}
61-
onChange={onChange}
62-
exclude={exclude}
6335
managedLicenses={managedLicenses.toJS() as { [id: string]: License }}
64-
confirmLabel={confirmLabel}
65-
style={style}
66-
extra={extra}
67-
extraButtons={extraButtons}
68-
requireValid={requireValid}
36+
confirmLabel="Apply License"
37+
{...props}
6938
/>
7039
);
71-
};
40+
}

src/packages/frontend/site-licenses/select-license.tsx

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ IMPORTANT: this component must work in *both* from nextjs and static.
99
import { Alert, Button, Checkbox, Popconfirm, Select, Space } from "antd";
1010
import { keys } from "lodash";
1111
import { ReactNode, useMemo, useRef, useState } from "react";
12-
1312
import { CSS, Rendered } from "@cocalc/frontend/app-framework";
1413
import { Icon } from "@cocalc/frontend/components/icon";
1514
import { describe_quota as describeQuota } from "@cocalc/util/licenses/describe-quota";
1615
import { days_ago as daysAgo, isValidUUID, len } from "@cocalc/util/misc";
1716
import { COLORS } from "@cocalc/util/theme";
17+
import { CallToSupport } from "@cocalc/frontend/project/trial-banner";
1818

1919
const { Option } = Select;
2020

@@ -36,6 +36,7 @@ interface Props {
3636
extra?: ReactNode; // plain-text node is ok
3737
extraButtons?: ReactNode;
3838
requireValid?: boolean;
39+
requireLicense?: boolean;
3940
}
4041

4142
export default function SelectLicense(props: Props) {
@@ -51,6 +52,7 @@ export default function SelectLicense(props: Props) {
5152
extra,
5253
extraButtons,
5354
requireValid,
55+
requireLicense,
5456
} = props;
5557
const isBlurredRef = useRef<boolean>(true);
5658
const [licenseId, setLicenseId] = useState<string>(defaultLicenseId ?? "");
@@ -69,6 +71,7 @@ export default function SelectLicense(props: Props) {
6971
}
7072
return v;
7173
}, [managedLicenses, showAll]);
74+
const [showCall, setShowCall] = useState<boolean>(false);
7275

7376
const options: JSX.Element[] = useMemo(() => {
7477
const v: JSX.Element[] = [];
@@ -178,6 +181,7 @@ export default function SelectLicense(props: Props) {
178181
flex: "1 1 0",
179182
marginRight: "10px",
180183
}}
184+
status={requireLicense && !licenseId ? "error" : undefined}
181185
placeholder={
182186
`Enter${requireValid ? " valid " : " "}license code ` +
183187
(options.length > 0
@@ -207,6 +211,28 @@ export default function SelectLicense(props: Props) {
207211
>
208212
{options}
209213
</Select>
214+
{requireLicense && !licenseId ? (
215+
<Alert
216+
style={{ marginTop: "10px" }}
217+
type="info"
218+
showIcon
219+
message={
220+
<div>
221+
A license is required.
222+
{showCall ? (
223+
<CallToSupport onClose={() => setShowCall(false)} />
224+
) : (
225+
<Button
226+
style={{ marginLeft: "15px" }}
227+
onClick={() => setShowCall(true)}
228+
>
229+
Why?
230+
</Button>
231+
)}
232+
</div>
233+
}
234+
/>
235+
) : undefined}
210236
</div>
211237
{!valid && licenseId && (
212238
<Alert

0 commit comments

Comments
 (0)