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  };