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  };