github.com/argoproj/argo-cd/v3@v3.2.1/ui/src/app/shared/utils.ts (about)

     1  import React from 'react';
     2  import {Cluster} from './models';
     3  
     4  export function hashCode(str: string) {
     5      let hash = 0;
     6      for (let i = 0; i < str.length; i++) {
     7          // tslint:disable-next-line:no-bitwise
     8          hash = ~~((hash << 5) - hash + str.charCodeAt(i));
     9      }
    10      return hash;
    11  }
    12  
    13  // concatMaps merges two maps. Later args take precedence where there's a key conflict.
    14  export function concatMaps(...maps: (Map<string, string> | null)[]): Map<string, string> {
    15      const newMap = new Map<string, string>();
    16      for (const map of maps) {
    17          if (map) {
    18              for (const entry of Object.entries(map)) {
    19                  newMap.set(entry[0], entry[1]);
    20              }
    21          }
    22      }
    23      return newMap;
    24  }
    25  
    26  export function isValidURL(url: string): boolean {
    27      try {
    28          const parsedUrl = new URL(url);
    29          return parsedUrl.protocol !== 'javascript:' && parsedUrl.protocol !== 'data:' && parsedUrl.protocol !== 'vbscript:';
    30      } catch (TypeError) {
    31          try {
    32              // Try parsing as a relative URL.
    33              const parsedUrl = new URL(url, window.location.origin);
    34              return parsedUrl.protocol !== 'javascript:' && parsedUrl.protocol !== 'data:' && parsedUrl.protocol !== 'vbscript:';
    35          } catch (TypeError) {
    36              return false;
    37          }
    38      }
    39  }
    40  
    41  export const colorSchemes = {
    42      light: '(prefers-color-scheme: light)',
    43      dark: '(prefers-color-scheme: dark)'
    44  };
    45  
    46  /**
    47   * quick method to check system theme
    48   * @param theme auto, light, dark
    49   * @returns dark or light
    50   */
    51  export function getTheme(theme: string) {
    52      if (theme !== 'auto') {
    53          return theme;
    54      }
    55  
    56      const dark = window.matchMedia(colorSchemes.dark);
    57  
    58      return dark.matches ? 'dark' : 'light';
    59  }
    60  
    61  /**
    62   * create a listener for system theme
    63   * @param cb callback for theme change
    64   * @returns destroy listener
    65   */
    66  export const useSystemTheme = (cb: (theme: string) => void) => {
    67      const dark = window.matchMedia(colorSchemes.dark);
    68      const light = window.matchMedia(colorSchemes.light);
    69  
    70      const listener = () => {
    71          cb(dark.matches ? 'dark' : 'light');
    72      };
    73  
    74      dark.addEventListener('change', listener);
    75      light.addEventListener('change', listener);
    76  
    77      return () => {
    78          dark.removeEventListener('change', listener);
    79          light.removeEventListener('change', listener);
    80      };
    81  };
    82  
    83  export const useTheme = (props: {theme: string}) => {
    84      const [theme, setTheme] = React.useState(getTheme(props.theme));
    85  
    86      React.useEffect(() => {
    87          let destroyListener: (() => void) | undefined;
    88  
    89          // change theme by system, only register listener when theme is auto
    90          if (props.theme === 'auto') {
    91              destroyListener = useSystemTheme(systemTheme => {
    92                  setTheme(systemTheme);
    93              });
    94          }
    95  
    96          // change theme manually
    97          if (props.theme !== theme) {
    98              setTheme(getTheme(props.theme));
    99          }
   100  
   101          return () => {
   102              destroyListener?.();
   103          };
   104      }, [props.theme]);
   105  
   106      return [theme];
   107  };
   108  
   109  export const formatClusterQueryParam = (cluster: Cluster) => {
   110      if (cluster.name === cluster.server) {
   111          return cluster.name;
   112      }
   113      return `${cluster.name} (${cluster.server})`;
   114  };