github.com/argoproj/argo-cd/v2@v2.10.9/ui/src/app/shared/components/version-info/version-info-panel.tsx (about) 1 import {DataLoader, SlidingPanel, Tooltip} from 'argo-ui'; 2 import * as React from 'react'; 3 import {VersionMessage} from '../../models'; 4 import {services} from '../../services'; 5 6 interface VersionPanelProps { 7 isShown: boolean; 8 onClose: () => void; 9 version: Promise<VersionMessage>; 10 } 11 12 type CopyState = 'success' | 'failed' | undefined; 13 14 export class VersionPanel extends React.Component<VersionPanelProps, {copyState: CopyState}> { 15 private readonly header = 'Argo CD Server Version'; 16 17 constructor(props: VersionPanelProps) { 18 super(props); 19 this.state = {copyState: undefined}; 20 } 21 22 public render() { 23 return ( 24 <DataLoader load={() => services.viewPreferences.getPreferences()}> 25 {pref => ( 26 <DataLoader load={() => this.props.version}> 27 {version => { 28 return ( 29 <div className={'theme-' + pref.theme}> 30 <SlidingPanel header={this.header} isShown={this.props.isShown} onClose={() => this.props.onClose()} hasCloseButton={true} isNarrow={true}> 31 <div className='argo-table-list'>{this.buildVersionTable(version)}</div> 32 <div> 33 <Tooltip content='Copy all version info as JSON'>{this.getCopyButton(version)}</Tooltip> 34 </div> 35 </SlidingPanel> 36 </div> 37 ); 38 }} 39 </DataLoader> 40 )} 41 </DataLoader> 42 ); 43 } 44 45 /** 46 * Formats the version data and renders the table rows. 47 */ 48 private buildVersionTable(version: VersionMessage): JSX.Element { 49 const formattedVersion = { 50 'Argo CD': version.Version, 51 'Build Date': version.BuildDate, 52 'Go Version': version.GoVersion, 53 'Go Compiler': version.Compiler, 54 'Platform': version.Platform, 55 'jsonnet': version.JsonnetVersion, 56 'kustomize': version.KustomizeVersion, 57 'Helm': version.HelmVersion, 58 'kubectl': version.KubectlVersion 59 }; 60 61 return ( 62 <React.Fragment> 63 {Object.entries(formattedVersion).map(([key, value]) => { 64 return ( 65 <div className='argo-table-list__row' key={key}> 66 <div className='row'> 67 <div className='columns small-4' title={key}> 68 <strong>{key}</strong> 69 </div> 70 <div className='columns'> 71 {value && ( 72 <Tooltip content={value}> 73 <span>{value}</span> 74 </Tooltip> 75 )} 76 </div> 77 </div> 78 </div> 79 ); 80 })} 81 </React.Fragment> 82 ); 83 } 84 85 private getCopyButton(version: VersionMessage): JSX.Element { 86 let img: string; 87 let text: string; 88 if (this.state.copyState === 'success') { 89 img = 'fa-check'; 90 text = 'Copied'; 91 } else if (this.state.copyState === 'failed') { 92 img = 'fa-times'; 93 text = 'Copy Failed'; 94 } else { 95 img = 'fa-copy'; 96 text = 'Copy JSON'; 97 } 98 99 return ( 100 <button className='argo-button argo-button--base' style={{marginTop: '1em', minWidth: '18ch'}} onClick={() => this.onCopy(version)}> 101 <i className={'fa ' + img} /> 102 {text} 103 </button> 104 ); 105 } 106 107 private async onCopy(version: VersionMessage): Promise<void> { 108 const stringifiedVersion = JSON.stringify(version, undefined, 4) + '\n'; 109 try { 110 await navigator.clipboard.writeText(stringifiedVersion); 111 this.setState({copyState: 'success'}); 112 } catch (err) { 113 this.setState({copyState: 'failed'}); 114 } 115 116 setTimeout(() => { 117 this.setState({copyState: undefined}); 118 }, 750); 119 } 120 }