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