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';
import { useUserPermissions } from 'src/utils/UserPermissions/useUserPermissions';
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 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 { hasPermissions } = useUserPermissions();
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()));
}
};
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]
);
const decoratorHandleClose = hasPermissions(
handleClose,
[],
'sca.mgmt.$provider.$action',
{ provider: '1' },
{
action: ['create'],
}
);
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={decoratorHandleClose}
>
{CLOUD_PROVIDERS.map((el: any) => (
<MenuItem
data-cy={el.name + 'Menu'}
key={el.name}
onClick={() => decoratorHandleClose(el.name.toLowerCase())}
disabled={disableMenuItem(el)}
value={el.value}
>
{' '}
{getProviderUiName(el.value)}
</MenuItem>
))}
</StyledMenu>
</Grid>
</Grid>
);
};
export default PoliciesFilterBar;