Untitled

mail@pastecode.io avatar
unknown
tsx
a year ago
11 kB
4
Indexable
Never
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import styles from '../policies-filter-bar/PoliciesFilterBar.module.scss';
import { Box, Button, InputLabel, MenuItem, MenuProps, Select, Typography, Divider, Grid } from '@mui/material';
import { SelectChangeEvent } from '@mui/material/Select';
import { useDispatch, useSelector } from 'react-redux';
import { AccessPolicyCloudProvider, getProviderDisplayName } from '../../models/access-policies.enums';
import Menu from '@mui/material/Menu';
import arrow from '../../../assets/icons/arrow down-w.svg';
import withStyles from '@mui/styles/withStyles';
import { styled } from '@mui/material/styles';

import { useHistory } from 'react-router-dom';
import { ScaSearchField } from '../../../shared/search/ScaSearchField';
import { ApplicationConfig } from '../../../global-state/reducers/ApplicationConfigReducer';
import { getProviderUiName } from '../../services/PlatformService';
import { useTranslation } from 'react-i18next';
import trans from 'src/utils/i18n';
import { PermissionService } from '../../../shared/PermissionService';
import { CLOUD_PROVIDERS, POLICY_TYPES, STATUS } from './constants';
import {
  setCloudProviderFilterAction,
  setSearchTermAction,
  setStatusFilterAction,
  setTypeFilterAction,
} from 'src/global-state/actions/policies.actions';
import { debounce } from 'lodash';
const StyledMenu = withStyles({
  paper: {
    border: '1px solid #d3d4d5',
    width: 185,
  },
})((props: MenuProps) => (
  <Menu
    elevation={0}
    anchorOrigin={{
      vertical: 'bottom',
      horizontal: 'center',
    }}
    transformOrigin={{
      vertical: 'top',
      horizontal: 'center',
    }}
    {...props}
  />
));

const SelectInputWrapper = styled(Box)(({ theme }) => ({
  display: 'flex',
  flexDirection: 'column',
  width: '200px',
  textAlign: 'left',
}));

const userPermissions = ['sca.mgmt.search']

function checkUserPermission(permission: string): boolean {
  // Get the user's permissions from a database or API
  // const userPermissions: string[] = getUserPermissions();

  // Check if the user has the specified permission
  return userPermissions.includes(permission);
}

// Define a decorator function that takes a permission name as an argument
function hasPermission(permission: string) {
  return function(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    // Save the original method or property
    const original = descriptor.value;

    // Replace the original method or property with a new function that checks permissions first
    descriptor.value = function(...args: any[]) {
      // Check if the user has the required permission
      const hasPermission = checkUserPermission(permission);

      if (!hasPermission) {
        throw new Error(`User does not have permission to perform this action: ${permission}`);
      }

      // Call the original method or property with the arguments passed in
      return original.apply(this, args);
    };

    // Return the modified descriptor
    return descriptor;
  };
}

const permissionService = new PermissionService();
const DEBOUNCE_TIMEOUT = 500;
const PoliciesFilterBar = () => {
  const history = useHistory();
  const { t } = useTranslation();
  const dispatch = useDispatch();
  const appConfig: ApplicationConfig = useSelector<ApplicationConfig>(
    (state: any) => state.appConfig.applicationConfig
  ) as ApplicationConfig;
  const enableTypeFilter = appConfig.policyFilter.typeFilter;
  const searchTerm = useSelector((state: any) => state.policiesReducer.searchTerm);
  const statusFilter = useSelector((state: any) => state.policiesReducer.statusFilter);
  const cloudProviderFilter = useSelector((state: any) => state.policiesReducer.cloudProviderFilter);
  const typeFilter = useSelector((state: any) => state.policiesReducer.typeFilter);
  const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
  const [searchTermValue, setSearchTermValue] = useState(searchTerm);

  const handleDispatchSearchTerm = (value: string) => {
    dispatch(setSearchTermAction(value));
  };
  const debounceSearchTerm = useMemo(() => debounce(handleDispatchSearchTerm, DEBOUNCE_TIMEOUT), []);

  const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
    setAnchorEl(event.currentTarget);
  };

  const handleClose = (provider: any) => {
    setAnchorEl(null);
    if (typeof provider === 'string') {
      history.push(`/create_policy/` + encodeURIComponent(provider.toLowerCase()));
    }
  };
  @hasPermission(['create_aws_button'])
  const handleSearchTermChange = (value: string) => {
    setSearchTermValue(value);
    debounceSearchTerm(value);
  };

  
  
  const handleStatusFilterChange = (event: SelectChangeEvent) => {
    dispatch(setStatusFilterAction(Number(event.target.value)));
  };
  const handleCloudProviderFilterChange = (event: SelectChangeEvent) => {
    dispatch(setCloudProviderFilterAction(Number(event.target.value)));
  };

  const handleTypeFilterChange = (event: SelectChangeEvent) => {
    dispatch(setTypeFilterAction(Number(event.target.value)));
  };

  const isDisabled = useCallback(
    (el: any) => {
      if (el.value === AccessPolicyCloudProvider.AWS_SSO) {
        return !appConfig?.wizardConfig?.enableAwsSSO;
      }
      if (el.value === AccessPolicyCloudProvider.AZURE_RESOURCE) {
        return !appConfig?.wizardConfig?.enableAzureResource;
      }
      if (el.value === AccessPolicyCloudProvider.AZURE_AD) {
        return !appConfig?.wizardConfig?.enableAzureAD;
      }
      return false;
    },
    [appConfig.wizardConfig]
  );

  const disableMenuItem = useCallback(
    (el: any) => {
      if (el.name === getProviderDisplayName(AccessPolicyCloudProvider.GCP)) {
        return !appConfig.wizardConfig.enableGcp;
      }
      if (el.name === getProviderDisplayName(AccessPolicyCloudProvider.AWS_SSO)) {
        return !appConfig.wizardConfig.enableAwsSSO;
      }
      if (el.name === getProviderDisplayName(AccessPolicyCloudProvider.AZURE_RESOURCE)) {
        return !appConfig.wizardConfig.enableAzureResource;
      }
      if (el.name === getProviderDisplayName(AccessPolicyCloudProvider.AZURE_AD)) {
        return !appConfig.wizardConfig.enableAzureAD;
      }
      return false;
    },
    [appConfig.wizardConfig]
  );

  return (
    <Grid
      container={true}
      direction="row"
      justifyContent="space-between"
      alignItems="center"
      data-testid="PoliciesFilterBar"
      columns={24}
      mb={5}
    >
      <Grid item={true} container={true} xs={10} md={10} lg={10}>
        <SelectInputWrapper key="status">
          <InputLabel id="status" shrink={true}>
            {trans('status', t)}
          </InputLabel>
          <Select
            id="demo-simple-select"
            data-testid="select-status-filter"
            name="select-status-filter"
            labelId="status"
            value={statusFilter}
            onChange={handleStatusFilterChange}
          >
            {STATUS.map((el: any) => (
              <MenuItem key={el.value} value={el.value}>
                {el.name}
              </MenuItem>
            ))}
          </Select>
        </SelectInputWrapper>
        <SelectInputWrapper key="provider" ml={3}>
          <InputLabel id="cloud" shrink={true}>
            {trans('cloudProviderT', t)}
          </InputLabel>
          <Select
            labelId="cloud"
            id="demo-simple-select2"
            data-testid="select-cloud-provider-filter"
            name="select-cloud-provider-filter"
            value={cloudProviderFilter}
            onChange={handleCloudProviderFilterChange}
          >
            {CLOUD_PROVIDERS.map((el: any) => (
              <MenuItem key={el.value} value={el.value} disabled={isDisabled(el)}>
                {el.value !== AccessPolicyCloudProvider.ALL ? getProviderUiName(el.value) : el.name}
              </MenuItem>
            ))}
          </Select>
        </SelectInputWrapper>
        {enableTypeFilter && (
          <SelectInputWrapper key="type" ml={3}>
            <InputLabel id="type" shrink={true}>
              {trans('policyType', t)}
            </InputLabel>
            <Select
              labelId="type"
              id="demo-simple-select3"
              data-testid="select-type-filter"
              name="select-type-filter"
              value={typeFilter}
              onChange={handleTypeFilterChange}
            >
              {POLICY_TYPES.map((el: any) => (
                <MenuItem key={el.value} value={el.value}>
                  {el.name}
                </MenuItem>
              ))}
            </Select>
          </SelectInputWrapper>
        )}
        <div className={styles.border} />
        <Box
          sx={{
            width: '250px',
            display: 'flex',
            marginTop: '24px',
          }}
          ml={1.5}
          key="search"
        >
          <ScaSearchField
            placeholder="Search"
            value={searchTermValue}
            action={handleSearchTermChange}
            style={{ fontSize: '14px', fontWeight: '400' }}
          />
        </Box>
      </Grid>
      <Grid item={true} container={true} justifyContent="flex-end" alignItems="center" xs={2} md={2} lg={2}>
        <Button
          id="add-new-policy"
          variant="contained"
          color="primary"
          data-cy="createNewPolicy"
          aria-controls="simple-menu"
          aria-haspopup="true"
          disabled={permissionService.isReadOnly(appConfig.wizardConfig.scope)}
          onClick={handleClick}
          sx={{
            padding: '2px 14px 2px 20px',
            height: '34px',
            justifyContent: 'center',
            alignItems: 'center',
          }}
        >
          <Typography
            sx={{
              fontWeight: '600',
              fontSize: '14px',
              lineHeight: '19px',
            }}
          >
            {trans('createNewPolicy', t)}
          </Typography>
          <img src={arrow} className={styles.arrowImg} alt="arrow" />
        </Button>
        <StyledMenu
          id="customized-menu"
          anchorEl={anchorEl}
          keepMounted={true}
          open={Boolean(anchorEl)}
          onClose={handleClose}
        >
          {CLOUD_PROVIDERS.map((el: any) => (
            <MenuItem
              data-cy={el.name + 'Menu'}
              key={el.name}
              onClick={() => handleClose(el.name)}
              disabled={disableMenuItem(el)}
              value={el.value}
            >
              {' '}
              {getProviderUiName(el.value)}
            </MenuItem>
          ))}
        </StyledMenu>
      </Grid>
    </Grid>
  );
};

export default PoliciesFilterBar;