Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/dashboard/src/repositories/detail/general/ConfigurationName.tsx
2502 views
1
/**
2
* Copyright (c) 2023 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 type { Configuration } from "@gitpod/public-api/lib/gitpod/v1/configuration_pb";
8
import { LoadingButton } from "@podkit/buttons/LoadingButton";
9
import { FC, useCallback, useState } from "react";
10
import { TextInputField } from "../../../components/forms/TextInputField";
11
import { useToast } from "../../../components/toasts/Toasts";
12
import { useOnBlurError } from "../../../hooks/use-onblur-error";
13
import { ConfigurationSettingsField } from "../ConfigurationSettingsField";
14
import { useConfigurationMutation } from "../../../data/configurations/configuration-queries";
15
import { InputWithCopy } from "../../../components/InputWithCopy";
16
import { InputField } from "../../../components/forms/InputField";
17
import { usePrettyRepoURL } from "../../../hooks/use-pretty-repo-url";
18
19
const MAX_LENGTH = 100;
20
21
type Props = {
22
configuration: Configuration;
23
};
24
export const ConfigurationNameForm: FC<Props> = ({ configuration }) => {
25
const { toast } = useToast();
26
const updateConfiguration = useConfigurationMutation();
27
const [configurationName, setConfigurationName] = useState(configuration.name);
28
29
const nameChanged = configurationName !== configuration.name;
30
const nameError = useOnBlurError("Sorry, this name is too long.", configurationName.length <= MAX_LENGTH);
31
32
const url = usePrettyRepoURL(configuration.cloneUrl);
33
34
const updateName = useCallback(
35
async (e: React.FormEvent) => {
36
e.preventDefault();
37
38
if (!nameError.isValid) {
39
toast("Please correct the errors with the name.");
40
return;
41
}
42
43
updateConfiguration.mutate(
44
{
45
configurationId: configuration.id,
46
name: configurationName,
47
},
48
{
49
onSuccess: (configuration) => {
50
toast(`Configuration name set to "${configuration.name}".`);
51
},
52
onError: (err) => {
53
toast(`Updating configuration name failed: ${err.message}`);
54
},
55
},
56
);
57
},
58
[nameError.isValid, updateConfiguration, configuration.id, configurationName, toast],
59
);
60
61
return (
62
<ConfigurationSettingsField>
63
<form onSubmit={updateName}>
64
<TextInputField
65
label="Display name"
66
hint={
67
<a href={configuration.cloneUrl} target="_blank" rel="noopener noreferrer" className="gp-link">
68
{url}
69
</a>
70
}
71
value={configurationName}
72
error={nameError.message}
73
onChange={setConfigurationName}
74
onBlur={nameError.onBlur}
75
/>
76
77
<InputField label="Repository ID">
78
<InputWithCopy value={configuration.id} tip="Click to copy configuration ID" />
79
</InputField>
80
81
<div className="flex flex-row items-center justify-start gap-2 mt-4 w-full">
82
<LoadingButton type="submit" disabled={!nameChanged} loading={updateConfiguration.isLoading}>
83
Save
84
</LoadingButton>
85
</div>
86
</form>
87
</ConfigurationSettingsField>
88
);
89
};
90
91