vitess.io/vitess@v0.16.2/web/vtadmin/src/components/routes/keyspace/Keyspace.tsx (about)

     1  /**
     2   * Copyright 2021 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 { Switch, useLocation, useParams, useRouteMatch } from 'react-router';
    17  import { Link, Redirect, Route } from 'react-router-dom';
    18  
    19  import { useKeyspace } from '../../../hooks/api';
    20  import { useDocumentTitle } from '../../../hooks/useDocumentTitle';
    21  import { isReadOnlyMode } from '../../../util/env';
    22  import { Code } from '../../Code';
    23  import { ContentContainer } from '../../layout/ContentContainer';
    24  import { NavCrumbs } from '../../layout/NavCrumbs';
    25  import { WorkspaceHeader } from '../../layout/WorkspaceHeader';
    26  import { WorkspaceTitle } from '../../layout/WorkspaceTitle';
    27  import { QueryLoadingPlaceholder } from '../../placeholders/QueryLoadingPlaceholder';
    28  import { ReadOnlyGate } from '../../ReadOnlyGate';
    29  import { Tab } from '../../tabs/Tab';
    30  import { TabContainer } from '../../tabs/TabContainer';
    31  import { Advanced } from './Advanced';
    32  import style from './Keyspace.module.scss';
    33  import { KeyspaceShards } from './KeyspaceShards';
    34  import { KeyspaceVSchema } from './KeyspaceVSchema';
    35  
    36  interface RouteParams {
    37      clusterID: string;
    38      name: string;
    39  }
    40  
    41  export const Keyspace = () => {
    42      const { clusterID, name } = useParams<RouteParams>();
    43      const { path, url } = useRouteMatch();
    44      const { search } = useLocation();
    45  
    46      useDocumentTitle(`${name} (${clusterID})`);
    47  
    48      const kq = useKeyspace({ clusterID, name });
    49      const { data: keyspace } = kq;
    50  
    51      if (kq.error) {
    52          return (
    53              <div className={style.placeholder}>
    54                  <span className={style.errorEmoji}>😰</span>
    55                  <h1>An error occurred</h1>
    56                  <code>{(kq.error as any).response?.error?.message || kq.error?.message}</code>
    57                  <p>
    58                      <Link to="/keyspaces">← All keyspaces</Link>
    59                  </p>
    60              </div>
    61          );
    62      }
    63  
    64      if (!kq.isLoading && !keyspace) {
    65          return (
    66              <div className={style.placeholder}>
    67                  <span className={style.errorEmoji}>😖</span>
    68                  <h1>Keyspace not found</h1>
    69                  <p>
    70                      <Link to="/keyspaces">← All keyspaces</Link>
    71                  </p>
    72              </div>
    73          );
    74      }
    75  
    76      return (
    77          <div>
    78              <WorkspaceHeader>
    79                  <NavCrumbs>
    80                      <Link to="/keyspaces">Keyspaces</Link>
    81                  </NavCrumbs>
    82  
    83                  <WorkspaceTitle className="font-mono">{name}</WorkspaceTitle>
    84  
    85                  <div className={style.headingMeta}>
    86                      <span>
    87                          Cluster: <code>{clusterID}</code>
    88                      </span>
    89                  </div>
    90              </WorkspaceHeader>
    91  
    92              <ContentContainer>
    93                  <TabContainer>
    94                      <Tab text="Shards" to={`${url}/shards`} />
    95                      <Tab text="VSchema" to={`${url}/vschema`} />
    96                      <Tab text="JSON" to={`${url}/json`} />
    97  
    98                      <ReadOnlyGate>
    99                          <Tab text="Advanced" to={`${url}/advanced`} />
   100                      </ReadOnlyGate>
   101                  </TabContainer>
   102  
   103                  <Switch>
   104                      <Route path={`${path}/shards`}>
   105                          <KeyspaceShards keyspace={keyspace} />
   106                      </Route>
   107  
   108                      <Route path={`${path}/vschema`}>
   109                          <KeyspaceVSchema clusterID={clusterID} name={name} />
   110                      </Route>
   111  
   112                      <Route path={`${path}/json`}>
   113                          <QueryLoadingPlaceholder query={kq} />
   114                          <Code code={JSON.stringify(keyspace, null, 2)} />
   115                      </Route>
   116  
   117                      {!isReadOnlyMode() && (
   118                          <Route path={`${path}/advanced`}>
   119                              <Advanced clusterID={clusterID} name={name} />
   120                          </Route>
   121                      )}
   122  
   123                      <Redirect exact from={path} to={{ pathname: `${path}/shards`, search }} />
   124                  </Switch>
   125              </ContentContainer>
   126          </div>
   127      );
   128  };