github.com/argoproj/argo-cd/v2@v2.10.9/ui/src/app/applications/components/application-urls.tsx (about) 1 import {DropDownMenu} from 'argo-ui'; 2 import * as React from 'react'; 3 import {isValidURL} from '../../shared/utils'; 4 5 export class InvalidExternalLinkError extends Error { 6 constructor(message: string) { 7 super(message); 8 Object.setPrototypeOf(this, InvalidExternalLinkError.prototype); 9 this.name = 'InvalidExternalLinkError'; 10 } 11 } 12 13 export class ExternalLink { 14 public title: string; 15 public ref: string; 16 17 constructor(url: string) { 18 const parts = url.split('|'); 19 if (parts.length === 2) { 20 this.title = parts[0]; 21 this.ref = parts[1]; 22 } else { 23 this.title = url; 24 this.ref = url; 25 } 26 if (!isValidURL(this.ref)) { 27 throw new InvalidExternalLinkError('Invalid URL'); 28 } 29 } 30 } 31 32 export const ExternalLinks = (urls?: string[]) => { 33 const externalLinks: ExternalLink[] = []; 34 for (const url of urls || []) { 35 try { 36 const externalLink = new ExternalLink(url); 37 externalLinks.push(externalLink); 38 } catch (InvalidExternalLinkError) { 39 continue; 40 } 41 } 42 43 // sorted alphabetically & links with titles first 44 externalLinks.sort((a, b) => { 45 const hasTitle = (x: ExternalLink): boolean => { 46 return x.title !== x.ref && x.title !== ''; 47 }; 48 49 if (hasTitle(a) && hasTitle(b) && a.title !== b.title) { 50 return a.title > b.title ? 1 : -1; 51 } else if (hasTitle(b) && !hasTitle(a)) { 52 return 1; 53 } else if (hasTitle(a) && !hasTitle(b)) { 54 return -1; 55 } 56 return a.ref > b.ref ? 1 : -1; 57 }); 58 59 return externalLinks; 60 }; 61 62 export const ApplicationURLs = ({urls}: {urls: string[]}) => { 63 const externalLinks: ExternalLink[] = ExternalLinks(urls); 64 65 return ( 66 ((externalLinks || []).length > 0 && ( 67 <div className='applications-list__external-links-icon-container'> 68 <a 69 title={externalLinks[0].title} 70 onClick={e => { 71 e.stopPropagation(); 72 window.open(externalLinks[0].ref); 73 }}> 74 <i className='fa fa-external-link-alt' />{' '} 75 {externalLinks.length > 1 && ( 76 <DropDownMenu 77 anchor={() => <i className='fa fa-caret-down' />} 78 items={externalLinks.map(item => ({ 79 title: item.title, 80 action: () => window.open(item.ref) 81 }))} 82 /> 83 )} 84 </a> 85 </div> 86 )) || 87 null 88 ); 89 };