Files
egovframe-msa-edu/frontend/admin/src/pages/menu/role/index.tsx
2021-10-21 09:03:17 +09:00

216 lines
5.8 KiB
TypeScript

import { DetailButtons } from '@components/Buttons/DetailButtons'
import CustomTreeView, { CustomTreeViewType } from '@components/CustomTreeView'
import TreeSubButtons from '@components/DraggableTreeMenu/TreeSubButtons'
import { HorizontalTabs } from '@components/Tabs'
import Box from '@material-ui/core/Box'
import Button from '@material-ui/core/Button'
import ButtonGroup from '@material-ui/core/ButtonGroup'
import MenuItem from '@material-ui/core/MenuItem'
import Paper from '@material-ui/core/Paper'
import Select from '@material-ui/core/Select'
import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'
import Tab from '@material-ui/core/Tab'
import CheckBoxIcon from '@material-ui/icons/CheckBox'
import CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank'
import { IRole, ISite, menuService, roleService } from '@service'
import { detailButtonsSnackAtom, errorStateSelector } from '@stores'
import { GetServerSideProps } from 'next'
import React, { createRef, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useSetRecoilState } from 'recoil'
import { menuRoleService } from 'src/service/MenuRole'
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
flexGrow: 1,
'& .MuiButtonGroup-contained': {
boxShadow: theme.shadows[0],
},
},
paper: {
display: 'flex',
flexDirection: 'column',
padding: theme.spacing(2),
background: theme.palette.background.paper,
},
select: {
minWidth: 150,
maxWidth: 300,
},
buttons: {
padding: theme.spacing(1, 0.5),
},
buttonGroup: {
'& .MuiButton-containedSizeSmall': {
padding: '4px 6px',
fontSize: '0.8rem',
},
whiteSpace: 'nowrap',
marginRight: theme.spacing(1),
},
}),
)
export interface MenuRoleProps {
sites: ISite[]
roles: IRole[]
}
const MenuRole = (props: MenuRoleProps) => {
const { sites, roles } = props
const classes = useStyles()
const { t } = useTranslation()
const treeViewRef = createRef<CustomTreeViewType>() //treeview Ref
const setErrorState = useSetRecoilState(errorStateSelector)
const setSuccessSnackBar = useSetRecoilState(detailButtonsSnackAtom)
const [tabs, setTabs] = useState<React.ReactNode>(undefined)
const [siteState, setSiteState] = useState<number>(sites ? sites[0].id : null)
const [roleState, setRoleState] = useState<string>(
roles ? roles[0].roleId : '',
)
const [expanded, setExpanded] = useState<boolean>(null)
const { data, mutate, error } = menuRoleService.search(roleState, siteState)
useEffect(() => {
if (roles) {
const createTabs = roles.map(role => {
return (
<Tab
label={role.roleName}
value={role.roleId}
key={`tab-${role.roleId}`}
/>
)
})
setTabs(createTabs)
}
}, [roles])
const handleTab = (roleId: string) => {
setRoleState(roleId)
mutate(data, false)
}
const handleSiteChange = (event: React.ChangeEvent<{ value: unknown }>) => {
setSiteState(event.target.value as number)
}
const handleExpand = () => {
setExpanded(true)
}
const handleCollapse = () => {
setExpanded(false)
}
const handleAllChecked = () => {
treeViewRef.current?.handleAllChecked(true)
}
const handleAllUnchecked = () => {
treeViewRef.current?.handleAllChecked(false)
}
const handleSave = async () => {
setSuccessSnackBar('loading')
if (treeViewRef.current) {
const tree = treeViewRef.current.getTreeData()
try {
const result = await menuRoleService.save(tree)
setSuccessSnackBar('success')
if (result) {
mutate()
}
} catch (error) {
setErrorState({ error })
setSuccessSnackBar('none')
}
}
}
return (
<div className={classes.root}>
{tabs && (
<HorizontalTabs tabs={tabs} init={roleState} handleTab={handleTab} />
)}
<Paper className={classes.paper}>
<Select
className={classes.select}
value={siteState}
onChange={handleSiteChange}
>
{sites?.map(item => (
<MenuItem key={item.id} value={item.id}>
{item.name}
</MenuItem>
))}
</Select>
<Box className={classes.buttons}>
<ButtonGroup
className={classes.buttonGroup}
size="small"
aria-label="menu tree buttons"
variant="contained"
>
<Button onClick={handleAllChecked}>
<CheckBoxIcon fontSize="small" />
{t('label.button.all_checked')}
</Button>
<Button onClick={handleAllUnchecked}>
<CheckBoxOutlineBlankIcon fontSize="small" />
{t('label.button.all_unchecked')}
</Button>
</ButtonGroup>
<TreeSubButtons
handleExpand={handleExpand}
handleCollapse={handleCollapse}
/>
</Box>
{data && (
<CustomTreeView
ref={treeViewRef}
data={data}
isChecked={true}
isAllExpanded={expanded}
/>
)}
<DetailButtons handleSave={handleSave} />
</Paper>
</div>
)
}
export const getServerSideProps: GetServerSideProps = async context => {
let sites: ISite[] = []
let roles: IRole[] = []
try {
const siteResult = await menuService.getSites()
if (siteResult) {
sites = siteResult
}
const roleResult = await roleService.searchAll()
if (roleResult) {
roles = roleResult.data
}
} catch (error) {
console.error(`menu role getServerSideProps error ${error.message}`)
}
return {
props: {
sites,
roles,
},
}
}
export default MenuRole