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