github.com/argoproj/argo-cd/v3@v3.2.1/ui/src/app/ui-banner/ui-banner.tsx (about) 1 import {Tooltip} from 'argo-ui'; 2 import * as React from 'react'; 3 import {combineLatest} from 'rxjs'; 4 import {map} from 'rxjs/operators'; 5 import {ExternalLink} from '../applications/components/application-urls'; 6 7 import {DataLoader} from '../shared/components'; 8 import {services, ViewPreferences} from '../shared/services'; 9 import './ui-banner.scss'; 10 11 const CustomBanner = (props: { 12 combinedBannerClassName: string; 13 show: boolean; 14 heightOfBanner: string; 15 leftOffset: string; 16 permanent: boolean; 17 url: string; 18 content: string; 19 setVisible: (visible: boolean) => void; 20 prefs: object; 21 }) => { 22 return ( 23 <div className={props.combinedBannerClassName} style={{visibility: props.show ? 'visible' : 'hidden', height: props.heightOfBanner, marginLeft: props.leftOffset}}> 24 <div className='ui-banner-text' style={{maxHeight: props.permanent ? '25px' : '50px'}}> 25 {props.url !== undefined ? ( 26 <a href={props.url} target='_blank' rel='noopener noreferrer'> 27 {props.content} 28 </a> 29 ) : ( 30 <React.Fragment>{props.content}</React.Fragment> 31 )} 32 </div> 33 {!props.permanent ? ( 34 <> 35 <button className='ui-banner-button argo-button argo-button--base' style={{marginRight: '5px'}} onClick={() => props.setVisible(false)}> 36 Dismiss for now 37 </button> 38 <button 39 className='ui-banner-button argo-button argo-button--base' 40 onClick={() => services.viewPreferences.updatePreferences({...props.prefs, hideBannerContent: props.content})}> 41 Don't show again 42 </button> 43 </> 44 ) : null} 45 </div> 46 ); 47 }; 48 49 export const Banner = (props: React.Props<any>) => { 50 const [visible, setVisible] = React.useState(true); 51 return ( 52 <DataLoader 53 load={() => 54 combineLatest([services.authService.settings(), services.viewPreferences.getPreferences()]).pipe( 55 map(items => { 56 return { 57 content: items[0].uiBannerContent, 58 url: items[0].uiBannerURL, 59 prefs: items[1], 60 permanent: items[0].uiBannerPermanent, 61 chatText: items[0].help.chatText, 62 chatUrl: items[0].help.chatUrl, 63 position: items[0].uiBannerPosition 64 }; 65 }) 66 ) 67 }> 68 {({ 69 content, 70 url, 71 prefs, 72 permanent, 73 chatText, 74 chatUrl, 75 position 76 }: { 77 content: string; 78 url: string; 79 prefs: ViewPreferences; 80 permanent: boolean; 81 chatText: string; 82 chatUrl: string; 83 position: string; 84 }) => { 85 const heightOfBanner = permanent ? '28px' : '70px'; 86 const leftOffset = prefs.hideSidebar ? '60px' : '230px'; 87 let show = false; 88 if (!content || content === '' || content === null) { 89 if (prefs.hideBannerContent) { 90 services.viewPreferences.updatePreferences({...prefs, hideBannerContent: null}); 91 } 92 } else { 93 if (prefs.hideBannerContent !== content) { 94 show = true; 95 } 96 } 97 show = permanent || (show && visible); 98 const isTop = position !== 'bottom'; 99 const bannerClassName = isTop ? 'ui-banner-top' : 'ui-banner-bottom'; 100 const wrapperClassname = bannerClassName + '--wrapper ' + (!permanent ? bannerClassName + '--wrapper-multiline' : bannerClassName + '--wrapper-singleline'); 101 let chatBottomPosition = 10; 102 if (show && (!isTop || position === 'both')) { 103 if (permanent) { 104 chatBottomPosition = 40; 105 } else { 106 chatBottomPosition = 85; 107 } 108 } 109 if (chatUrl) { 110 try { 111 const externalLink = new ExternalLink(chatUrl); 112 chatUrl = externalLink.ref; 113 } catch (InvalidExternalLinkError) { 114 chatUrl = 'invalid-url'; 115 } 116 } 117 const shouldRenderTop = position === 'top' || position === 'both' || (!position && content); 118 const shouldRenderBottom = position === 'bottom' || position === 'both'; 119 return ( 120 <React.Fragment> 121 {shouldRenderTop && ( 122 <CustomBanner 123 combinedBannerClassName={'ui-banner ui-banner-top'} 124 show={show} 125 heightOfBanner={heightOfBanner} 126 leftOffset={leftOffset} 127 permanent={permanent} 128 url={url} 129 content={content} 130 setVisible={setVisible} 131 prefs={prefs} 132 /> 133 )} 134 {shouldRenderBottom && ( 135 <CustomBanner 136 combinedBannerClassName={'ui-banner ui-banner-bottom'} 137 show={show} 138 heightOfBanner={heightOfBanner} 139 leftOffset={leftOffset} 140 permanent={permanent} 141 url={url} 142 content={content} 143 setVisible={setVisible} 144 prefs={prefs} 145 /> 146 )} 147 {show ? <div className={wrapperClassname}>{props.children}</div> : props.children} 148 {chatUrl && ( 149 <div style={{position: 'fixed', right: 10, bottom: chatBottomPosition}}> 150 {chatUrl === 'invalid-url' ? ( 151 <Tooltip content='Invalid URL provided'> 152 <a className='argo-button disabled argo-button--special'> 153 <i className='fas fa-comment-alt' /> {chatText} 154 </a> 155 </Tooltip> 156 ) : ( 157 <a href={chatUrl} className='argo-button argo-button--special'> 158 <i className='fas fa-comment-alt' /> {chatText} 159 </a> 160 )} 161 </div> 162 )} 163 </React.Fragment> 164 ); 165 }} 166 </DataLoader> 167 ); 168 };