vitess.io/vitess@v0.16.2/web/vtadmin/src/components/routes/clusters/ClusterRow.tsx (about) 1 import React, { useState } from 'react'; 2 import { DataCell } from '../../dataTable/DataCell'; 3 import { vtadmin as pb } from '../../../proto/vtadmin'; 4 import Dialog from '../../dialog/Dialog'; 5 import { Icon, Icons } from '../../Icon'; 6 import { useValidate } from '../../../hooks/api'; 7 import { Label } from '../../inputs/Label'; 8 import Toggle from '../../toggle/Toggle'; 9 import ValidationResults from '../../ValidationResults'; 10 11 interface Props { 12 cluster: pb.Cluster; 13 } 14 15 const ClusterRow: React.FC<Props> = ({ cluster }) => { 16 const [isOpen, setIsOpen] = useState(false); 17 const [pingTablets, setPingTablets] = useState(false); 18 19 const { mutate, error, data, isIdle, reset } = useValidate({ clusterID: cluster.id, pingTablets }); 20 const closeDialog = () => { 21 setIsOpen(false); 22 reset(); 23 }; 24 return ( 25 <tr> 26 <Dialog 27 isOpen={isOpen} 28 confirmText={!isIdle ? 'Close' : 'Validate'} 29 cancelText="Cancel" 30 onConfirm={data ? closeDialog : () => mutate({ pingTablets, clusterID: cluster.id })} 31 loadingText="Validating" 32 onCancel={closeDialog} 33 onClose={closeDialog} 34 hideCancel={!isIdle} 35 title={!isIdle ? undefined : 'Validate'} 36 className="min-w-[400px]" 37 > 38 <div className="w-full"> 39 {isIdle && ( 40 <div> 41 <div className="my-4"> 42 Validate that all nodes in the cluster are reachable from the global replication graph, 43 as well as all tablets in discoverable cells, are consistent. 44 </div> 45 <div className="flex items-center"> 46 <Toggle enabled={pingTablets} onChange={() => setPingTablets(!pingTablets)} /> 47 <Label className="ml-2" label="Ping Tablets" /> 48 </div> 49 When set, all tablets will be pinged during the validation process. 50 </div> 51 )} 52 {!isIdle && !error && ( 53 <div className="w-full"> 54 <div className="flex items-center whitespace-nowrap"> 55 <Icon className="fill-current text-green-500" icon={Icons.checkSuccess} /> 56 <div className="ml-2 text-lg font-bold"> 57 Successfully validated cluster {cluster.name} 58 </div> 59 </div> 60 {data?.results_by_keyspace && ( 61 <ValidationResults resultsByKeyspace={data.results_by_keyspace} /> 62 )} 63 </div> 64 )} 65 {!isIdle && error && ( 66 <div className="w-full flex flex-col justify-center items-center"> 67 <span className="flex h-12 w-12 relative items-center justify-center"> 68 <Icon className="fill-current text-red-500" icon={Icons.alertFail} /> 69 </span> 70 <div className="text-lg mt-3 font-bold text-center"> 71 There was an issue validating nodes in cluster {cluster.name} 72 </div> 73 </div> 74 )} 75 </div> 76 </Dialog> 77 <DataCell>{cluster.name}</DataCell> 78 <DataCell>{cluster.id}</DataCell> 79 <DataCell> 80 <button 81 className="btn btn-secondary btn-sm" 82 onClick={() => { 83 setIsOpen(true); 84 }} 85 > 86 Validate 87 </button> 88 </DataCell> 89 </tr> 90 ); 91 }; 92 93 export default ClusterRow;