vitess.io/vitess@v0.16.2/web/vtadmin/src/components/routes/Vtctlds.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 { orderBy } from 'lodash'; 17 import { useMemo } from 'react'; 18 import { useVtctlds } from '../../hooks/api'; 19 import { useSyncedURLParam } from '../../hooks/useSyncedURLParam'; 20 import { filterNouns } from '../../util/filterNouns'; 21 import { DataCell } from '../dataTable/DataCell'; 22 import { DataFilter } from '../dataTable/DataFilter'; 23 import { DataTable } from '../dataTable/DataTable'; 24 import { ContentContainer } from '../layout/ContentContainer'; 25 import { WorkspaceHeader } from '../layout/WorkspaceHeader'; 26 import { WorkspaceTitle } from '../layout/WorkspaceTitle'; 27 import { QueryLoadingPlaceholder } from '../placeholders/QueryLoadingPlaceholder'; 28 29 export const Vtctlds = () => { 30 const vtctldsQuery = useVtctlds(); 31 const { data: vtctlds = [] } = vtctldsQuery; 32 33 const { value: filter, updateValue: updateFilter } = useSyncedURLParam('filter'); 34 35 const data = useMemo(() => { 36 const mapped = vtctlds.map((v) => ({ 37 cluster: v.cluster?.name, 38 clusterID: v.cluster?.id, 39 hostname: v.hostname, 40 fqdn: v.FQDN, 41 })); 42 43 const filtered = filterNouns(filter, mapped); 44 45 return orderBy(filtered, ['cluster', 'hostname']); 46 }, [filter, vtctlds]); 47 48 const renderRows = (rows: typeof data) => { 49 return rows.map((row) => { 50 return ( 51 <tr key={row.hostname}> 52 <DataCell> 53 <div className="font-bold"> 54 {row.fqdn ? ( 55 <a href={`//${row.fqdn}`} rel="noopener noreferrer" target="_blank"> 56 {row.hostname} 57 </a> 58 ) : ( 59 row.hostname 60 )} 61 </div> 62 </DataCell> 63 <DataCell> 64 {row.cluster} 65 <div className="text-sm text-secondary">{row.clusterID}</div> 66 </DataCell> 67 </tr> 68 ); 69 }); 70 }; 71 72 return ( 73 <div> 74 <WorkspaceHeader> 75 <WorkspaceTitle>vtctlds</WorkspaceTitle> 76 </WorkspaceHeader> 77 78 <ContentContainer> 79 <DataFilter 80 autoFocus 81 onChange={(e) => updateFilter(e.target.value)} 82 onClear={() => updateFilter('')} 83 placeholder="Filter vtctlds" 84 value={filter || ''} 85 /> 86 <DataTable columns={['Hostname', 'Cluster']} data={data} renderRows={renderRows} /> 87 <QueryLoadingPlaceholder query={vtctldsQuery} /> 88 </ContentContainer> 89 </div> 90 ); 91 };