1
0
mirror of https://github.com/sasjs/server.git synced 2025-12-10 11:24:35 +00:00

feat: created modal for adding permission

This commit is contained in:
2022-05-18 00:05:28 +05:00
parent dfbd155711
commit 1413b18508
4 changed files with 245 additions and 32 deletions

View File

@@ -7,19 +7,19 @@ import CloseIcon from '@mui/icons-material/Close'
export interface DialogTitleProps {
id: string
children?: React.ReactNode
onClose: Dispatch<SetStateAction<boolean>>
handleOpen: Dispatch<SetStateAction<boolean>>
}
export const BootstrapDialogTitle = (props: DialogTitleProps) => {
const { children, onClose, ...other } = props
const { children, handleOpen, ...other } = props
return (
<DialogTitle sx={{ m: 0, p: 2 }} {...other}>
{children}
{onClose ? (
{handleOpen ? (
<IconButton
aria-label="close"
onClick={() => onClose(false)}
onClick={() => handleOpen(false)}
sx={{
position: 'absolute',
right: 8,

View File

@@ -0,0 +1,217 @@
import React, {
useState,
useEffect,
useMemo,
Dispatch,
SetStateAction
} from 'react'
import axios from 'axios'
import {
Button,
Grid,
Dialog,
DialogContent,
DialogActions,
TextField,
CircularProgress
} from '@mui/material'
import { styled } from '@mui/material/styles'
import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete'
import { BootstrapDialogTitle } from '../../components/dialogTitle'
import {
PermissionResponse,
UserResponse,
GroupResponse,
RegisterPermissionPayload
} from '../../utils/types'
const BootstrapDialog = styled(Dialog)(({ theme }) => ({
'& .MuiDialogContent-root': {
padding: theme.spacing(2)
},
'& .MuiDialogActions-root': {
padding: theme.spacing(1)
}
}))
type AddPermissionModalProps = {
open: boolean
handleOpen: Dispatch<SetStateAction<boolean>>
permissions: PermissionResponse[]
addPermission: (addPermissionPayload: RegisterPermissionPayload) => void
}
const filter = createFilterOptions<string>()
const AddPermissionModal = ({
open,
handleOpen,
permissions,
addPermission
}: AddPermissionModalProps) => {
const [uri, setUri] = useState<string>()
const [principalType, setPrincipalType] = useState('user')
const [userPrincipal, setUserPrincipal] = useState<UserResponse>()
const [groupPrincipal, setGroupPrincipal] = useState<GroupResponse>()
const [permissionSetting, setPermissionSetting] = useState('Grant')
const [loadingPrincipals, setLoadingPrincipals] = useState(false)
const [userPrincipals, setUserPrincipals] = useState<UserResponse[]>([])
const [groupPrincipals, setGroupPrincipals] = useState<GroupResponse[]>([])
useEffect(() => {
setLoadingPrincipals(true)
axios
.get(`/SASjsApi/${principalType}`)
.then((res: any) => {
if (res.data) {
if (principalType === 'user') setUserPrincipals(res.data)
else setGroupPrincipals(res.data)
}
})
.catch((err) => {
console.log(err)
})
.finally(() => {
setLoadingPrincipals(false)
})
}, [principalType])
const handleAddPermission = () => {
const addPermissionPayload: any = {
uri,
setting: permissionSetting,
principalType
}
if (principalType === 'user' && userPrincipal) {
addPermissionPayload.principalId = userPrincipal.id
} else if (principalType === 'group' && groupPrincipal) {
addPermissionPayload.principalId = groupPrincipal.groupId
}
addPermission(addPermissionPayload)
}
const URIs = useMemo(() => {
return permissions.map((permission) => permission.uri)
}, [permissions])
const addButtonDisabled =
!uri || (principalType === 'user' ? !userPrincipal : !groupPrincipal)
return (
<BootstrapDialog onClose={() => handleOpen(false)} open={open}>
<BootstrapDialogTitle
id="add-permission-dialog-title"
handleOpen={handleOpen}
>
Add Permission
</BootstrapDialogTitle>
<DialogContent dividers>
<Grid container spacing={2}>
<Grid item xs={12}>
<Autocomplete
disableClearable
value={uri}
onChange={(event, newValue) => setUri(newValue)}
filterOptions={(options, params) => {
const filtered = filter(options, params)
const { inputValue } = params
const isExisting = options.some(
(option) => inputValue === option
)
if (inputValue !== '' && !isExisting) {
filtered.push(inputValue)
}
return filtered
}}
selectOnFocus
clearOnBlur
handleHomeEndKeys
options={URIs}
renderOption={(props, option) => <li {...props}>{option}</li>}
freeSolo
renderInput={(params) => <TextField {...params} label="URI" />}
/>
</Grid>
<Grid item xs={12}>
<Autocomplete
options={['user', 'group']}
disableClearable
value={principalType}
onChange={(event: any, newValue: string) =>
setPrincipalType(newValue)
}
renderInput={(params) => (
<TextField {...params} label="Principal Type" />
)}
/>
</Grid>
<Grid item xs={12}>
{principalType === 'user' ? (
<Autocomplete
options={userPrincipals}
getOptionLabel={(option) => option.displayName}
disableClearable
value={userPrincipal}
onChange={(event: any, newValue: UserResponse) =>
setUserPrincipal(newValue)
}
renderInput={(params) =>
loadingPrincipals ? (
<CircularProgress />
) : (
<TextField {...params} label="Principal" />
)
}
/>
) : (
<Autocomplete
options={groupPrincipals}
getOptionLabel={(option) => option.name}
disableClearable
value={groupPrincipal}
onChange={(event: any, newValue: GroupResponse) =>
setGroupPrincipal(newValue)
}
renderInput={(params) =>
loadingPrincipals ? (
<CircularProgress />
) : (
<TextField {...params} label="Principal" />
)
}
/>
)}
</Grid>
<Grid item xs={12}>
<Autocomplete
options={['Grant', 'Deny']}
disableClearable
value={permissionSetting}
onChange={(event: any, newValue: string) =>
setPermissionSetting(newValue)
}
renderInput={(params) => (
<TextField {...params} label="Settings" />
)}
/>
</Grid>
</Grid>
</DialogContent>
<DialogActions>
<Button
variant="outlined"
onClick={handleAddPermission}
disabled={addButtonDisabled}
>
Add
</Button>
</DialogActions>
</BootstrapDialog>
)
}
export default AddPermissionModal

View File

@@ -23,26 +23,9 @@ import DeleteForeverIcon from '@mui/icons-material/DeleteForever'
import { styled } from '@mui/material/styles'
import PermissionFilterModal from './permissionFilterModal'
import AddPermissionModal from './addPermissionModal'
interface UserResponse {
id: number
username: string
displayName: string
}
interface GroupResponse {
groupId: number
name: string
description: string
}
export interface PermissionResponse {
permissionId: number
uri: string
setting: string
user?: UserResponse
group?: GroupResponse
}
import { PermissionResponse } from '../../utils/types'
const BootstrapTableCell = styled(TableCell)({
textAlign: 'left'
@@ -50,6 +33,7 @@ const BootstrapTableCell = styled(TableCell)({
const Permission = () => {
const [isLoading, setIsLoading] = useState(false)
const [addPermissionModalOpen, setAddPermissionModalOpen] = useState(false)
const [filterModalOpen, setFilterModalOpen] = useState(false)
const [uriFilter, setUriFilter] = useState<string[]>([])
const [principalFilter, setPrincipalFilter] = useState<string[]>([])
@@ -128,6 +112,8 @@ const Permission = () => {
setFilterApplied(false)
}
const addPermission = () => {}
return isLoading ? (
<CircularProgress
style={{ position: 'absolute', left: '50%', top: '50%' }}
@@ -142,8 +128,12 @@ const Permission = () => {
<FilterListIcon onClick={() => setFilterModalOpen(true)} />
</IconButton>
</Tooltip>
<Tooltip title="Add Permission" placement="bottom-end">
<IconButton sx={{ flexGrow: 1, justifyContent: 'flex-end' }}>
<Tooltip
sx={{ marginLeft: 'auto' }}
title="Add Permission"
placement="bottom-end"
>
<IconButton onClick={() => setAddPermissionModalOpen(true)}>
<AddIcon />
</IconButton>
</Tooltip>
@@ -157,7 +147,7 @@ const Permission = () => {
</Grid>
<PermissionFilterModal
open={filterModalOpen}
handleClose={setFilterModalOpen}
handleOpen={setFilterModalOpen}
permissions={permissions}
uriFilter={uriFilter}
setUriFilter={setUriFilter}
@@ -168,6 +158,12 @@ const Permission = () => {
applyFilter={applyFilter}
resetFilter={resetFilter}
/>
<AddPermissionModal
open={addPermissionModalOpen}
handleOpen={setAddPermissionModalOpen}
permissions={permissions}
addPermission={addPermission}
/>
</Box>
)
}
@@ -192,7 +188,7 @@ const PermissionTable = ({ permissions }: PermissionTableProps) => {
</TableHead>
<TableBody>
{permissions.map((permission) => (
<TableRow>
<TableRow key={permission.permissionId}>
<BootstrapTableCell>{permission.uri}</BootstrapTableCell>
<BootstrapTableCell>
{displayPrincipal(permission)}

View File

@@ -10,7 +10,7 @@ import {
import { styled } from '@mui/material/styles'
import Autocomplete from '@mui/material/Autocomplete'
import { PermissionResponse } from './permission'
import { PermissionResponse } from '../../utils/types'
import { BootstrapDialogTitle } from '../../components/dialogTitle'
const BootstrapDialog = styled(Dialog)(({ theme }) => ({
'& .MuiDialogContent-root': {
@@ -23,7 +23,7 @@ const BootstrapDialog = styled(Dialog)(({ theme }) => ({
type FilterModalProps = {
open: boolean
handleClose: Dispatch<SetStateAction<boolean>>
handleOpen: Dispatch<SetStateAction<boolean>>
permissions: PermissionResponse[]
uriFilter: string[]
setUriFilter: Dispatch<SetStateAction<string[]>>
@@ -37,7 +37,7 @@ type FilterModalProps = {
const PermissionFilterModal = ({
open,
handleClose,
handleOpen,
permissions,
uriFilter,
setUriFilter,
@@ -58,10 +58,10 @@ const PermissionFilterModal = ({
.filter((principal) => principal !== '')
return (
<BootstrapDialog onClose={handleClose} open={open}>
<BootstrapDialog onClose={() => handleOpen(false)} open={open}>
<BootstrapDialogTitle
id="permission-filter-dialog-title"
onClose={handleClose}
handleOpen={handleOpen}
>
Permission Filter
</BootstrapDialogTitle>