Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/dashboard/src/teams/policies/MaxParallelWorkspaces.tsx
2501 views
1
/**
2
* Copyright (c) 2024 Gitpod GmbH. All rights reserved.
3
* Licensed under the GNU Affero General Public License (AGPL).
4
* See License.AGPL.txt in the project root for license information.
5
*/
6
7
import { OrganizationSettings } from "@gitpod/public-api/lib/gitpod/v1/organization_pb";
8
import { FormEvent, useEffect, useState } from "react";
9
import { ConfigurationSettingsField } from "../../repositories/detail/ConfigurationSettingsField";
10
import { Heading3, Subheading } from "@podkit/typography/Headings";
11
import { InputField } from "../../components/forms/InputField";
12
import { NumberInput } from "../../components/forms/TextInputField";
13
import { LoadingButton } from "@podkit/buttons/LoadingButton";
14
import { MAX_PARALLEL_WORKSPACES_FREE, MAX_PARALLEL_WORKSPACES_PAID } from "@gitpod/gitpod-protocol";
15
import { PlainMessage } from "@bufbuild/protobuf";
16
import { useInstallationConfiguration } from "../../data/installation/installation-config-query";
17
18
type Props = {
19
isOwner: boolean;
20
isLoading: boolean;
21
isPaidOrDedicated: boolean;
22
settings?: OrganizationSettings;
23
handleUpdateTeamSettings: (
24
newSettings: Partial<PlainMessage<OrganizationSettings>>,
25
options?: {
26
throwMutateError?: boolean;
27
},
28
) => Promise<void>;
29
};
30
31
export const MaxParallelWorkspaces = ({
32
isOwner,
33
isLoading,
34
settings,
35
isPaidOrDedicated,
36
handleUpdateTeamSettings,
37
}: Props) => {
38
const [error, setError] = useState<string | undefined>(undefined);
39
const [maxParallelWorkspaces, setMaxParallelWorkspaces] = useState<number>(
40
settings?.maxParallelRunningWorkspaces ?? 0,
41
);
42
43
const organizationDefault = isPaidOrDedicated ? MAX_PARALLEL_WORKSPACES_PAID : MAX_PARALLEL_WORKSPACES_FREE;
44
const { data: installationConfig } = useInstallationConfiguration();
45
const isDedicatedInstallation = !!installationConfig?.isDedicatedInstallation;
46
47
const handleSubmit = async (e: FormEvent) => {
48
e.preventDefault();
49
if (maxParallelWorkspaces < 0) {
50
setError("The maximum parallel running workspaces must be a positive number.");
51
return;
52
}
53
await handleUpdateTeamSettings({
54
maxParallelRunningWorkspaces: maxParallelWorkspaces,
55
});
56
};
57
58
useEffect(() => {
59
setMaxParallelWorkspaces(settings?.maxParallelRunningWorkspaces ?? 0);
60
}, [settings?.maxParallelRunningWorkspaces]);
61
62
return (
63
<ConfigurationSettingsField>
64
<Heading3>Maximum parallel running workspaces</Heading3>
65
<Subheading>
66
By default, every user in your organization can have <strong>{organizationDefault}</strong> workspaces
67
running at the same time. You can change this limit below or revert to this default by specifying{" "}
68
<strong>0</strong> as the limit.
69
</Subheading>
70
<form onSubmit={handleSubmit}>
71
<InputField label="Maximum parallel running workspaces" error={error} className="mb-4">
72
<NumberInput
73
value={maxParallelWorkspaces ?? ""}
74
onChange={(newValue) => {
75
setMaxParallelWorkspaces(newValue);
76
setError(undefined);
77
}}
78
disabled={isLoading || !isOwner}
79
min={0}
80
max={isDedicatedInstallation ? undefined : organizationDefault}
81
/>
82
</InputField>
83
<LoadingButton type="submit" loading={isLoading} disabled={!isOwner}>
84
Save
85
</LoadingButton>
86
</form>
87
</ConfigurationSettingsField>
88
);
89
};
90
91