vitess.io/vitess@v0.16.2/web/vtadmin/src/components/routes/createKeyspace/CreateKeyspace.tsx (about) 1 /** 2 * Copyright 2022 The Vitess Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 import { useState } from 'react'; 17 import { useQueryClient } from 'react-query'; 18 import { Link, useHistory } from 'react-router-dom'; 19 20 import { useClusters, useCreateKeyspace } from '../../../hooks/api'; 21 import { useDocumentTitle } from '../../../hooks/useDocumentTitle'; 22 import { Label } from '../../inputs/Label'; 23 import { Select } from '../../inputs/Select'; 24 import { ContentContainer } from '../../layout/ContentContainer'; 25 import { NavCrumbs } from '../../layout/NavCrumbs'; 26 import { WorkspaceHeader } from '../../layout/WorkspaceHeader'; 27 import { WorkspaceTitle } from '../../layout/WorkspaceTitle'; 28 import { TextInput } from '../../TextInput'; 29 import { success } from '../../Snackbar'; 30 import { FormError } from '../../forms/FormError'; 31 32 interface FormData { 33 clusterID: string; 34 keyspaceName: string; 35 } 36 37 const DEFAULT_FORM_DATA: FormData = { 38 clusterID: '', 39 keyspaceName: '', 40 }; 41 42 export const CreateKeyspace = () => { 43 useDocumentTitle('Create a Keyspace'); 44 45 const queryClient = useQueryClient(); 46 const history = useHistory(); 47 48 const [formData, setFormData] = useState<FormData>(DEFAULT_FORM_DATA); 49 50 const { data: clusters = [], ...clustersQuery } = useClusters(); 51 52 const mutation = useCreateKeyspace( 53 { 54 clusterID: formData.clusterID, 55 options: { 56 name: formData.keyspaceName, 57 }, 58 }, 59 { 60 onSuccess: (res) => { 61 queryClient.invalidateQueries('keyspaces'); 62 success(`Created keyspace ${res?.keyspace?.keyspace?.name}`, { autoClose: 1600 }); 63 history.push(`/keyspace/${res?.keyspace?.cluster?.id}/${res?.keyspace?.keyspace?.name}`); 64 }, 65 } 66 ); 67 68 let selectedCluster = null; 69 if (!!formData.clusterID) { 70 selectedCluster = clusters.find((c) => c.id === formData.clusterID); 71 } 72 73 const isValid = !!selectedCluster && !!formData.keyspaceName; 74 const isDisabled = !isValid || mutation.isLoading; 75 76 const onSubmit: React.FormEventHandler<HTMLFormElement> = (e) => { 77 e.preventDefault(); 78 mutation.mutate(); 79 }; 80 81 return ( 82 <div> 83 <WorkspaceHeader> 84 <NavCrumbs> 85 <Link to="/keyspaces">Keyspaces</Link> 86 </NavCrumbs> 87 88 <WorkspaceTitle>Create a Keyspace</WorkspaceTitle> 89 </WorkspaceHeader> 90 91 <ContentContainer className="max-w-screen-sm"> 92 <form onSubmit={onSubmit}> 93 <Select 94 className="block w-full" 95 disabled={clustersQuery.isLoading} 96 inputClassName="block w-full" 97 itemToString={(cluster) => cluster?.name || ''} 98 items={clusters} 99 label="Cluster" 100 onChange={(c) => setFormData({ ...formData, clusterID: c?.id || '' })} 101 placeholder={clustersQuery.isLoading ? 'Loading clusters...' : 'Select a cluster'} 102 renderItem={(c) => `${c?.name} (${c?.id})`} 103 selectedItem={selectedCluster} 104 /> 105 106 {clustersQuery.isError && ( 107 <FormError 108 error={clustersQuery.error} 109 title="Couldn't load clusters. Please reload the page to try again." 110 /> 111 )} 112 113 <Label className="block my-8" label="Keyspace Name"> 114 <TextInput 115 onChange={(e) => setFormData({ ...formData, keyspaceName: e.target.value })} 116 value={formData.keyspaceName || ''} 117 /> 118 </Label> 119 120 {mutation.isError && !mutation.isLoading && ( 121 <FormError error={mutation.error} title="Couldn't create keyspace. Please try again." /> 122 )} 123 124 <div className="my-12"> 125 <button className="btn" disabled={isDisabled} type="submit"> 126 {mutation.isLoading ? 'Creating Keyspace...' : 'Create Keyspace'} 127 </button> 128 </div> 129 </form> 130 </ContentContainer> 131 </div> 132 ); 133 };