github.com/argoproj/argo-cd/v2@v2.10.9/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 ) : ( 45 <></> 46 )} 47 </div> 48 ); 49 }; 50 51 export const Banner = (props: React.Props<any>) => { 52 const [visible, setVisible] = React.useState(true); 53 return ( 54 <DataLoader 55 load={() => 56 combineLatest([services.authService.settings(), services.viewPreferences.getPreferences()]).pipe( 57 map(items => { 58 return { 59 content: items[0].uiBannerContent, 60 url: items[0].uiBannerURL, 61 prefs: items[1], 62 permanent: items[0].uiBannerPermanent, 63 chatText: items[0].help.chatText, 64 chatUrl: items[0].help.chatUrl, 65 position: items[0].uiBannerPosition 66 }; 67 }) 68 ) 69 }> 70 {({ 71 content, 72 url, 73 prefs, 74 permanent, 75 chatText, 76 chatUrl, 77 position 78 }: { 79 content: string; 80 url: string; 81 prefs: ViewPreferences; 82 permanent: boolean; 83 chatText: string; 84 chatUrl: string; 85 position: string; 86 }) => { 87 const heightOfBanner = permanent ? '28px' : '70px'; 88 const leftOffset = prefs.hideSidebar ? '60px' : '230px'; 89 let show = false; 90 if (!content || content === '' || content === null) { 91 if (prefs.hideBannerContent) { 92 services.viewPreferences.updatePreferences({...prefs, hideBannerContent: null}); 93 } 94 } else { 95 if (prefs.hideBannerContent !== content) { 96 show = true; 97 } 98 } 99 show = permanent || (show && visible); 100 const isTop = position !== 'bottom'; 101 const bannerClassName = isTop ? 'ui-banner-top' : 'ui-banner-bottom'; 102 const wrapperClassname = bannerClassName + '--wrapper ' + (!permanent ? bannerClassName + '--wrapper-multiline' : bannerClassName + '--wrapper-singleline'); 103 let chatBottomPosition = 10; 104 if (show && (!isTop || position === 'both')) { 105 if (permanent) { 106 chatBottomPosition = 40; 107 } else { 108 chatBottomPosition = 85; 109 } 110 } 111 if (chatUrl) { 112 try { 113 const externalLink = new ExternalLink(chatUrl); 114 chatUrl = externalLink.ref; 115 } catch (InvalidExternalLinkError) { 116 chatUrl = 'invalid-url'; 117 } 118 } 119 const shouldRenderTop = position === 'top' || position === 'both'; 120 const shouldRenderBottom = position === 'bottom' || position === 'both'; 121 return ( 122 <React.Fragment> 123 {shouldRenderTop && ( 124 <CustomBanner 125 combinedBannerClassName={'ui-banner ui-banner-top'} 126 show={show} 127 heightOfBanner={heightOfBanner} 128 leftOffset={leftOffset} 129 permanent={permanent} 130 url={url} 131 content={content} 132 setVisible={setVisible} 133 prefs={prefs} 134 /> 135 )} 136 {shouldRenderBottom && ( 137 <CustomBanner 138 combinedBannerClassName={'ui-banner ui-banner-bottom'} 139 show={show} 140 heightOfBanner={heightOfBanner} 141 leftOffset={leftOffset} 142 permanent={permanent} 143 url={url} 144 content={content} 145 setVisible={setVisible} 146 prefs={prefs} 147 /> 148 )} 149 {show ? <div className={wrapperClassname}>{props.children}</div> : props.children} 150 {chatUrl && ( 151 <div style={{position: 'fixed', right: 10, bottom: chatBottomPosition}}> 152 {chatUrl === 'invalid-url' ? ( 153 <Tooltip content='Invalid URL provided'> 154 <a className='argo-button disabled argo-button--special'> 155 <i className='fas fa-comment-alt' /> {chatText} 156 </a> 157 </Tooltip> 158 ) : ( 159 <a href={chatUrl} className='argo-button argo-button--special'> 160 <i className='fas fa-comment-alt' /> {chatText} 161 </a> 162 )} 163 </div> 164 )} 165 </React.Fragment> 166 ); 167 }} 168 </DataLoader> 169 ); 170 };