Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb73e66e

Browse files
authored
feat: show workspace name suggestions below the name field (#12001)
1 parent52ec3ed commitb73e66e

File tree

10 files changed

+104
-74
lines changed

10 files changed

+104
-74
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import{
2+
NumberDictionary,
3+
animals,
4+
colors,
5+
uniqueNamesGenerator,
6+
}from"unique-names-generator";
7+
8+
exportconstgenerateWorkspaceName=()=>{
9+
constnumberDictionary=NumberDictionary.generate({min:0,max:99});
10+
returnuniqueNamesGenerator({
11+
dictionaries:[colors,animals,numberDictionary],
12+
separator:"-",
13+
length:3,
14+
style:"lowerCase",
15+
});
16+
};

‎site/src/pages/CreateWorkspacePage/CreateWorkspacePage.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ describe("CreateWorkspacePage", () => {
214214
it("Detects when a workspace is being created with the 'duplicate' mode",async()=>{
215215
constparams=newURLSearchParams({
216216
mode:"duplicate",
217-
name:MockWorkspace.name,
217+
name:`${MockWorkspace.name}-copy`,
218218
version:MockWorkspace.template_active_version_id,
219219
});
220220

‎site/src/pages/CreateWorkspacePage/CreateWorkspacePage.tsx

Lines changed: 13 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import{typeFC,useCallback,useEffect,useState}from"react";
2+
import{Helmet}from"react-helmet-async";
3+
import{useMutation,useQuery,useQueryClient}from"react-query";
4+
import{useNavigate,useParams,useSearchParams}from"react-router-dom";
15
import{getUserParameters}from"api/api";
26
import{checkAuthorization}from"api/queries/authCheck";
37
import{
@@ -6,7 +10,7 @@ import {
610
templateVersionExternalAuth,
711
}from"api/queries/templates";
812
import{autoCreateWorkspace,createWorkspace}from"api/queries/workspaces";
9-
import{
13+
importtype{
1014
TemplateVersionParameter,
1115
UserParameter,
1216
Workspace,
@@ -16,21 +20,12 @@ import { Loader } from "components/Loader/Loader";
1620
import{useMe}from"contexts/auth/useMe";
1721
import{useOrganizationId}from"contexts/auth/useOrganizationId";
1822
import{useEffectEvent}from"hooks/hookPolyfills";
19-
import{useCallback,useEffect,useMemo,useState,typeFC}from"react";
20-
import{Helmet}from"react-helmet-async";
21-
import{useMutation,useQuery,useQueryClient}from"react-query";
22-
import{useNavigate,useParams,useSearchParams}from"react-router-dom";
23-
import{
24-
NumberDictionary,
25-
animals,
26-
colors,
27-
uniqueNamesGenerator,
28-
}from"unique-names-generator";
2923
import{pageTitle}from"utils/page";
3024
import{AutofillBuildParameter}from"utils/richParameters";
3125
import{paramsUsedToCreateWorkspace}from"utils/workspace";
3226
import{CreateWorkspacePageView}from"./CreateWorkspacePageView";
3327
import{CreateWSPermissions,createWorkspaceChecks}from"./permissions";
28+
import{generateWorkspaceName}from"modules/workspaces/generateWorkspaceName";
3429

3530
exportconstcreateWorkspaceModes=["form","auto","duplicate"]asconst;
3631
exporttypeCreateWorkspaceMode=(typeofcreateWorkspaceModes)[number];
@@ -46,14 +41,7 @@ const CreateWorkspacePage: FC = () => {
4641
constmode=getWorkspaceMode(searchParams);
4742
constcustomVersionId=searchParams.get("version")??undefined;
4843

49-
constdefaultName=useMemo(()=>{
50-
constparamsName=searchParams.get("name");
51-
if(mode==="duplicate"&&paramsName){
52-
return`${paramsName}-copy`;
53-
}
54-
55-
returnparamsName??generateUniqueName();
56-
},[mode,searchParams]);
44+
constdefaultName=searchParams.get("name");
5745

5846
constqueryClient=useQueryClient();
5947
constautoCreateWorkspaceMutation=useMutation(
@@ -63,13 +51,11 @@ const CreateWorkspacePage: FC = () => {
6351

6452
consttemplateQuery=useQuery(templateByName(organizationId,templateName));
6553

66-
constuserParametersQuery=useQuery(
67-
["userParameters"],
68-
()=>getUserParameters(templateQuery.data!.id),
69-
{
70-
enabled:templateQuery.isSuccess,
71-
},
72-
);
54+
constuserParametersQuery=useQuery({
55+
queryKey:["userParameters"],
56+
queryFn:()=>getUserParameters(templateQuery.data!.id),
57+
enabled:templateQuery.isSuccess,
58+
});
7359

7460
constpermissionsQuery=useQuery(
7561
checkAuthorization({
@@ -122,7 +108,7 @@ const CreateWorkspacePage: FC = () => {
122108
templateName,
123109
organizationId,
124110
defaultBuildParameters:autofillParameters,
125-
defaultName,
111+
defaultName:defaultName??generateWorkspaceName(),
126112
versionId:realizedVersionId,
127113
});
128114

@@ -269,16 +255,6 @@ const getAutofillParameters = (
269255
returnbuildValues;
270256
};
271257

272-
constgenerateUniqueName=()=>{
273-
constnumberDictionary=NumberDictionary.generate({min:0,max:99});
274-
returnuniqueNamesGenerator({
275-
dictionaries:[colors,animals,numberDictionary],
276-
separator:"-",
277-
length:3,
278-
style:"lowerCase",
279-
});
280-
};
281-
282258
exportdefaultCreateWorkspacePage;
283259

284260
functiongetWorkspaceMode(params:URLSearchParams):CreateWorkspaceMode{

‎site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.stories.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,18 @@ export const CreateWorkspaceError: Story = {
4848
},
4949
};
5050

51+
exportconstSpecificVersion:Story={
52+
args:{
53+
versionId:"specific-version",
54+
},
55+
};
56+
57+
exportconstDuplicate:Story={
58+
args:{
59+
mode:"duplicate",
60+
},
61+
};
62+
5163
exportconstParameters:Story={
5264
args:{
5365
parameters:[

‎site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx

Lines changed: 53 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
import{typeInterpolation,typeTheme}from"@emotion/react";
22
importTextFieldfrom"@mui/material/TextField";
3-
importtype*asTypesGenfrom"api/typesGenerated";
4-
import{UserAutocomplete}from"components/UserAutocomplete/UserAutocomplete";
3+
importButtonfrom"@mui/material/Button";
4+
importFormHelperTextfrom"@mui/material/FormHelperText";
55
import{FormikContextType,useFormik}from"formik";
6-
import{typeFC,useEffect,useState,useMemo}from"react";
6+
import{typeFC,useEffect,useState,useMemo,useCallback}from"react";
7+
import{useSearchParams}from"react-router-dom";
8+
import*asYupfrom"yup";
9+
importtype*asTypesGenfrom"api/typesGenerated";
710
import{
811
getFormHelpers,
912
nameValidator,
1013
onChangeTrimmed,
1114
}from"utils/formUtils";
12-
import*asYupfrom"yup";
1315
import{
1416
FormFields,
1517
FormSection,
1618
FormFooter,
1719
HorizontalForm,
1820
}from"components/Form/Form";
21+
import{UserAutocomplete}from"components/UserAutocomplete/UserAutocomplete";
1922
import{
2023
AutofillBuildParameter,
2124
AutofillSource,
@@ -24,16 +27,8 @@ import {
2427
}from"utils/richParameters";
2528
import{ErrorAlert}from"components/Alert/ErrorAlert";
2629
import{Stack}from"components/Stack/Stack";
27-
import{
28-
CreateWorkspaceMode,
29-
ExternalAuthPollingState,
30-
}from"./CreateWorkspacePage";
31-
import{useSearchParams}from"react-router-dom";
32-
import{CreateWSPermissions}from"./permissions";
3330
import{Alert}from"components/Alert/Alert";
34-
import{ExternalAuthBanner}from"./ExternalAuthBanner/ExternalAuthBanner";
3531
import{Margins}from"components/Margins/Margins";
36-
importButtonfrom"@mui/material/Button";
3732
import{Avatar}from"components/Avatar/Avatar";
3833
import{
3934
PageHeader,
@@ -42,6 +37,13 @@ import {
4237
}from"components/PageHeader/PageHeader";
4338
import{Pill}from"components/Pill/Pill";
4439
import{RichParameterInput}from"components/RichParameterInput/RichParameterInput";
40+
import{generateWorkspaceName}from"modules/workspaces/generateWorkspaceName";
41+
import{
42+
CreateWorkspaceMode,
43+
ExternalAuthPollingState,
44+
}from"./CreateWorkspacePage";
45+
import{ExternalAuthBanner}from"./ExternalAuthBanner/ExternalAuthBanner";
46+
import{CreateWSPermissions}from"./permissions";
4547

4648
exportconstLanguage={
4749
duplicationWarning:
@@ -52,7 +54,7 @@ export interface CreateWorkspacePageViewProps {
5254
mode:CreateWorkspaceMode;
5355
error:unknown;
5456
resetMutation:()=>void;
55-
defaultName:string;
57+
defaultName?:string|null;
5658
defaultOwner:TypesGen.User;
5759
template:TypesGen.Template;
5860
versionId?:string;
@@ -92,11 +94,18 @@ export const CreateWorkspacePageView: FC<CreateWorkspacePageViewProps> = ({
9294
const[searchParams]=useSearchParams();
9395
constdisabledParamsList=searchParams?.get("disable_params")?.split(",");
9496
constrequiresExternalAuth=externalAuth.some((auth)=>!auth.authenticated);
97+
const[suggestedName,setSuggestedName]=useState(()=>
98+
generateWorkspaceName(),
99+
);
100+
101+
constrerollSuggestedName=useCallback(()=>{
102+
setSuggestedName(()=>generateWorkspaceName());
103+
},[]);
95104

96105
constform:FormikContextType<TypesGen.CreateWorkspaceRequest>=
97106
useFormik<TypesGen.CreateWorkspaceRequest>({
98107
initialValues:{
99-
name:defaultName,
108+
name:defaultName??"",
100109
template_id:template.id,
101110
rich_parameter_values:getInitialRichParameterValues(
102111
parameters,
@@ -205,16 +214,29 @@ export const CreateWorkspacePageView: FC<CreateWorkspacePageViewProps> = ({
205214
</span>
206215
</Stack>
207216
)}
208-
209-
<TextField
210-
{...getFieldHelpers("name")}
211-
disabled={creatingWorkspace}
212-
// resetMutation facilitates the clearing of validation errors
213-
onChange={onChangeTrimmed(form,resetMutation)}
214-
autoFocus
215-
fullWidth
216-
label="Workspace Name"
217-
/>
217+
<div>
218+
<TextField
219+
{...getFieldHelpers("name")}
220+
disabled={creatingWorkspace}
221+
// resetMutation facilitates the clearing of validation errors
222+
onChange={onChangeTrimmed(form,resetMutation)}
223+
fullWidth
224+
label="Workspace Name"
225+
/>
226+
<FormHelperTextdata-chromatic="ignore">
227+
Need a suggestion?{" "}
228+
<Button
229+
variant="text"
230+
css={styles.nameSuggestion}
231+
onClick={async()=>{
232+
awaitform.setFieldValue("name",suggestedName);
233+
rerollSuggestedName();
234+
}}
235+
>
236+
{suggestedName}
237+
</Button>
238+
</FormHelperText>
239+
</div>
218240

219241
{permissions.createWorkspaceForUser&&(
220242
<UserAutocomplete
@@ -279,6 +301,13 @@ export const CreateWorkspacePageView: FC<CreateWorkspacePageViewProps> = ({
279301
};
280302

281303
conststyles={
304+
nameSuggestion:(theme)=>({
305+
color:theme.roles.info.fill.solid,
306+
padding:"4px 8px",
307+
lineHeight:"inherit",
308+
fontSize:"inherit",
309+
height:"unset",
310+
}),
282311
hasDescription:{
283312
paddingBottom:16,
284313
},

‎site/src/pages/CreateWorkspacePage/useWorkspaceDuplication.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ describe(`${useWorkspaceDuplication.name}`, () => {
8888
constparsedParams=newURLSearchParams(router.state.location.search);
8989
constextraMetadataEntries=[
9090
["mode","duplicate"],
91-
["name",MockWorkspace.name],
91+
["name",`${MockWorkspace.name}-copy`],
9292
["version",MockWorkspace.template_active_version_id],
9393
]asconst;
9494

‎site/src/pages/CreateWorkspacePage/useWorkspaceDuplication.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
import{useNavigate}from"react-router-dom";
1+
import{useCallback}from"react";
22
import{useQuery}from"react-query";
3-
import{typeCreateWorkspaceMode}from"./CreateWorkspacePage";
4-
import{
5-
typeWorkspace,
6-
typeWorkspaceBuildParameter,
7-
}from"api/typesGenerated";
3+
import{useNavigate}from"react-router-dom";
4+
importtype{Workspace,WorkspaceBuildParameter}from"api/typesGenerated";
85
import{workspaceBuildParameters}from"api/queries/workspaceBuilds";
9-
import{useCallback}from"react";
6+
import{typeCreateWorkspaceMode}from"./CreateWorkspacePage";
107

118
functiongetDuplicationUrlParams(
129
workspaceParams:readonlyWorkspaceBuildParameter[],
@@ -23,7 +20,7 @@ function getDuplicationUrlParams(
2320
returnnewURLSearchParams({
2421
...consolidatedParams,
2522
mode:"duplicate"satisfiesCreateWorkspaceMode,
26-
name:workspace.name,
23+
name:`${workspace.name}-copy`,
2724
version:workspace.template_active_version_id,
2825
});
2926
}

‎site/src/theme/dark/roles.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export default {
6767
outline:colors.blue[400],
6868
text:colors.blue[50],
6969
fill:{
70-
solid:colors.blue[600],
70+
solid:colors.blue[500],
7171
outline:colors.blue[600],
7272
text:colors.white,
7373
},

‎site/src/theme/darkBlue/roles.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export default {
6868
text:colors.blue[50],
6969
fill:{
7070
solid:colors.blue[500],
71-
outline:colors.blue[500],
71+
outline:colors.blue[600],
7272
text:colors.white,
7373
},
7474
},

‎site/src/theme/light/roles.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export default {
6767
outline:colors.blue[400],
6868
text:colors.blue[950],
6969
fill:{
70-
solid:colors.blue[600],
70+
solid:colors.blue[700],
7171
outline:colors.blue[600],
7272
text:colors.white,
7373
},

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp