github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/webapp/javascript/components/Settings/Apps/index.tsx (about)

     1  import React, { useEffect, useState } from 'react';
     2  import cl from 'classnames';
     3  import { useAppDispatch, useAppSelector } from '@webapp/redux/hooks';
     4  import {
     5    selectApps,
     6    reloadApps,
     7    deleteApp,
     8    selectIsLoadingApps,
     9  } from '@webapp/redux/reducers/settings';
    10  import { addNotification } from '@webapp/redux/reducers/notifications';
    11  import { type App } from '@webapp/models/app';
    12  import Input from '@webapp/ui/Input';
    13  import TableUI from '@webapp/ui/Table';
    14  import LoadingSpinner from '@webapp/ui/LoadingSpinner';
    15  import { getAppTableRows } from './getAppTableRows';
    16  
    17  import appsStyles from './Apps.module.css';
    18  import tableStyles from '../SettingsTable.module.scss';
    19  
    20  const headRow = [
    21    { name: '', label: 'Name', sortable: 0 },
    22    { name: '', label: '', sortable: 0 },
    23  ];
    24  
    25  function Apps() {
    26    const dispatch = useAppDispatch();
    27    const apps = useAppSelector(selectApps);
    28    const isLoading = useAppSelector(selectIsLoadingApps);
    29    const [search, setSearchField] = useState('');
    30    const [appsInProcessing, setAppsInProcessing] = useState<string[]>([]);
    31    const [deletedApps, setDeletedApps] = useState<string[]>([]);
    32  
    33    useEffect(() => {
    34      dispatch(reloadApps());
    35    }, []);
    36  
    37    const displayApps =
    38      (apps &&
    39        apps.filter(
    40          (x) =>
    41            x.name.toLowerCase().indexOf(search.toLowerCase()) !== -1 &&
    42            !deletedApps.includes(x.name)
    43        )) ||
    44      [];
    45  
    46    const handleDeleteApp = (app: App) => {
    47      setAppsInProcessing([...appsInProcessing, app.name]);
    48      dispatch(deleteApp(app))
    49        .unwrap()
    50        .then(() => {
    51          setAppsInProcessing(appsInProcessing.filter((x) => x !== app.name));
    52          setDeletedApps([...deletedApps, app.name]);
    53          dispatch(
    54            addNotification({
    55              type: 'success',
    56              title: 'App has been deleted',
    57              message: `App ${app.name} has been successfully deleted`,
    58            })
    59          );
    60        })
    61        .catch(() => {
    62          setDeletedApps(deletedApps.filter((x) => x !== app.name));
    63          setAppsInProcessing(appsInProcessing.filter((x) => x !== app.name));
    64        });
    65    };
    66  
    67    const tableBodyProps =
    68      displayApps.length > 0
    69        ? {
    70            bodyRows: getAppTableRows(
    71              displayApps,
    72              appsInProcessing,
    73              handleDeleteApp
    74            ),
    75            type: 'filled' as const,
    76          }
    77        : {
    78            type: 'not-filled' as const,
    79            value: 'The list is empty',
    80            bodyClassName: appsStyles.appsTableEmptyMessage,
    81          };
    82  
    83    return (
    84      <>
    85        <h2 className={appsStyles.tabNameContrainer}>
    86          Apps
    87          {isLoading && !!apps ? <LoadingSpinner /> : null}
    88        </h2>
    89        <div className={appsStyles.searchContainer}>
    90          <Input
    91            type="text"
    92            placeholder="Search app"
    93            value={search}
    94            onChange={(v) => setSearchField(v.target.value)}
    95            name="Search app input"
    96          />
    97        </div>
    98        <TableUI
    99          className={cl(appsStyles.appsTable, tableStyles.settingsTable)}
   100          table={{ headRow, ...tableBodyProps }}
   101          isLoading={isLoading && !apps}
   102        />
   103      </>
   104    );
   105  }
   106  
   107  export default Apps;