@material-ui/core#Popover JavaScript Examples
The following examples show how to use
@material-ui/core#Popover.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: MenuPopover.js From course-manager with MIT License | 6 votes |
export default function MenuPopover({ children, sx, ...other }) {
return (
<Popover
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
PaperProps={{
sx: {
mt: 1.5,
ml: 0.5,
overflow: 'inherit',
boxShadow: (theme) => theme.customShadows.z20,
border: (theme) => `solid 1px ${theme.palette.grey[500_8]}`,
width: 200,
...sx
}
}}
{...other}
>
<ArrowStyle className="arrow" />
{children}
</Popover>
);
}
Example #2
Source File: ShareButton.js From qasong with ISC License | 5 votes |
function ShareButton({ disabled }) {
const classes = useStyles();
const [anchorEl, setAnchorEl] = React.useState(null);
const handleClick = (event) => {
copyCurrentURL(event);
setAnchorEl(event.currentTarget);
setTimeout(handleClose, 2500);
};
const handleClose = () => {
setAnchorEl(null);
};
const open = Boolean(anchorEl);
const id = open ? "simple-popover" : undefined;
return (
<>
<Tooltip title={disabled ? "Search for songs and add them to your queue" : ""}>
<Box mt={1}>
<IconButton
edge="end"
title="Copy Link to Current Queue"
disabled={disabled}
onClick={handleClick}
target="_blank"
color={disabled ? "inherit" : "secondary"}
aria-describedby={id}
>
<ReplyIcon />
</IconButton>
</Box>
</Tooltip>
<Popover
id={id}
open={open}
anchorEl={anchorEl}
onClose={handleClose}
anchorOrigin={{
vertical: "bottom",
horizontal: "center",
}}
transformOrigin={{
vertical: "top",
horizontal: "center",
}}
>
<Typography className={classes.typography}>Link to playlist copied!</Typography>
</Popover>
</>
);
}
Example #3
Source File: Volume.jsx From archeage-tools with The Unlicense | 5 votes |
render() {
const { volume: _volume, setVolume } = this.props;
const { menu, volume } = this.state;
return (
<>
<Tooltip title={`Volume: ${_volume}%`}>
<IconButton
size="small"
onClick={this.handleOpenMenu}
color="inherit"
ref={this.menuRef}
>
<div>
{_volume > 49 && <VolumeUpIcon />}
{_volume < 50 && _volume > 0 && <VolumeDownIcon />}
{_volume === 0 && <VolumeMuteIcon />}
</div>
</IconButton>
</Tooltip>
<Popover
anchorEl={menu}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'center',
}}
getContentAnchorEl={null}
open={Boolean(menu)}
onClose={this.handleCloseMenu}
>
<div className="volume-column">
<VolumeUpIcon />
<Slider
defaultValue={volume}
onChange={setVolume}
min={0}
max={100}
step={1}
orientation="vertical"
className="vol-slider"
/>
<VolumeDownIcon />
<Typography variant="subtitle2">{_volume}%</Typography>
</div>
</Popover>
</>
);
}
Example #4
Source File: ImageLayout.js From Edlib with GNU General Public License v3.0 | 5 votes |
function ImageLayout(props) {
const {
onDrop,
previewImage,
enlargeImage = false,
onClick,
anchorElement,
onRemoveImage,
uploadProgress,
readOnly = false,
uploading,
} = props;
let icon = null;
if ( previewImage === null) {
icon = <ImageIcon />;
if ( readOnly === false ) {
icon = (
<DropZone
onDropAccepted={onDrop}
multiple={false}
className="imageDropzone"
disabled={readOnly}
>
{icon}
</DropZone>);
}
}
return (
<div
className={'imageContainer ' + (previewImage !== null ? 'withImage' : null)}
>
{icon}
{previewImage !== null && (
<div>
{uploading === true && uploadProgress < 100 && (
<LinearProgress
variant="determinate"
value={uploadProgress}
className="uploadProgress"
/>
)}
<img src={previewImage} onClick={onClick} alt="assigment_image" />
<Popover
open={enlargeImage}
onClose={onClick}
anchorEl={anchorElement}
anchorOrigin={{
vertical: 'center',
horizontal: 'center',
}}
transformOrigin={{
vertical: 'center',
horizontal: 'center',
}}
>
<div className="popoverContainer">
<img src={previewImage} />
{readOnly === false && (
<div onClick={onRemoveImage}>
<DeleteIcon />
</div>
)}
</div>
</Popover>
</div>
)}
</div>
);
}
Example #5
Source File: SwapButton.js From spl-token-wallet with Apache License 2.0 | 5 votes |
function SwapButtonPopover({ size }) {
const [sendTransaction] = useSendTransaction();
const connection = useConnection();
const wallet = useWallet();
const tokenInfos = useTokenInfos();
const tokenList = tokenInfos && new TokenListContainer(tokenInfos);
const provider = new NotifyingProvider(connection, wallet, sendTransaction);
return (
tokenList && (
<PopupState variant="popover">
{(popupState) => (
<div style={{ display: 'flex' }}>
<Tooltip title="Swap Tokens">
<IconButton {...bindTrigger(popupState)} size={size}>
<SwapHoriz />
</IconButton>
</Tooltip>
<Popover
{...bindPopover(popupState)}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}
PaperProps={{ style: { borderRadius: '10px' } }}
disableRestoreFocus
keepMounted
>
<Swap
provider={provider}
tokenList={tokenList}
containerStyle={{ width: '432px' }}
/>
</Popover>
</div>
)}
</PopupState>
)
);
}
Example #6
Source File: PersonCell.jsx From frontend with MIT License | 5 votes |
PersonCell = ({ person }) => {
const classes = useStyles();
const [anchorEl, setAnchorEl] = React.useState(null);
const handlePopoverOpen = (event) => {
setAnchorEl(event.currentTarget);
};
const handlePopoverClose = () => {
setAnchorEl(null);
};
const open = Boolean(anchorEl);
return (
<div>
<Grid
container
wrap="nowrap"
alignItems="center"
spacing={2}
aria-owns={open ? 'mouse-over-popover' : undefined}
aria-haspopup="true"
onMouseEnter={handlePopoverOpen}
onMouseLeave={handlePopoverClose}
>
<Grid item>
<PersonAvatar src={person.avatarUrl} name={person.name} />
</Grid>
<Grid item xs>
{person.name}
</Grid>
</Grid>
<Popover
id="mouse-over-popover"
open={open}
classes={{
paper: classes.popoverContent,
}}
className={classes.popover}
anchorEl={anchorEl}
anchorOrigin={{
vertical: 'top',
horizontal: 'left',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left',
}}
onClose={handlePopoverClose}
disableRestoreFocus
PaperProps={{
onMouseEnter: handlePopoverOpen,
onMouseLeave: handlePopoverClose,
}}
>
<PersonCard person={person} />
</Popover>
</div>
);
}
Example #7
Source File: MapPopup.jsx From frontend with MIT License | 5 votes |
MapPopup = memo(({ anchorEl, regionName, handleClose, elevation, ...popupProps }) => {
const classes = useMapPopupStyles();
const { region, needs } = mockData;
const calculateProgressBarWidth = (mainParameter, ...other) => `${mainParameter} * (100% - 12px) / (${mainParameter} + ${other[0]} + ${other[1]})`
return (
<Popover
className={classes.root}
anchorEl={anchorEl}
open={!!anchorEl}
getContentAnchorEl={null}
onClose={handleClose}
elevation={0}
anchorOrigin={{
vertical: 'center',
horizontal: 'center',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}
{...popupProps}
>
<Box display='flex' flexDirection='column' p={2}>
<Box display='flex' justifyContent='space-between' minWidth='200px' >
<Typography className={classes.heading}>{regionName || '-'}</Typography>
<Box ml={2}>
<Typography className={classes.heading}>{region?.cases || '-'}</Typography>
</Box>
</Box>
<Box display='flex' height='34px' width='100%' py={1.75}>
<Box height='6px' width={`calc(${calculateProgressBarWidth(region?.cases, region?.recovered, region?.deaths)})`} mr={0.75} borderRadius={18} bgcolor='#FEAA53' />
<Box height='6px' width={`calc(${calculateProgressBarWidth(region?.recovered, region?.cases, region?.deaths)})`} mr={0.75} borderRadius={18} bgcolor='#2ED47A' />
<Box height='6px' width={`calc(${calculateProgressBarWidth(region?.deaths, region?.cases, region?.recovered)})`} borderRadius={18} bgcolor='#707683' />
</Box>
<Box>
<List disablePadding>
<ListItem disableGutters className={classes.casesListItem}>
<Box height='8px' width='8px' mr={1} borderRadius='50%' bgcolor='#FEAA53' />
<ListItemText disableTypography className={classes.casesListItemText}>{mapPopup.cases}</ListItemText>
<ListItemText disableTypography className={classes.casesListItemTextCount}>{region?.cases || '-'}</ListItemText>
</ListItem>
<ListItem disableGutters className={classes.casesListItem}>
<Box height='8px' width='8px' mr={1} borderRadius='50%' bgcolor='#2ED47A' />
<ListItemText disableTypography className={classes.casesListItemText}>{mapPopup.recovered}</ListItemText>
<ListItemText disableTypography className={classes.casesListItemTextCount}>{region?.recovered || '-'}</ListItemText>
</ListItem>
<ListItem disableGutters className={classes.casesListItem}>
<Box height='8px' width='8px' mr={1} borderRadius='50%' bgcolor='#707683' />
<ListItemText disableTypography className={classes.casesListItemText}>{mapPopup.deaths}</ListItemText>
<ListItemText disableTypography className={classes.casesListItemTextCount}>{region?.deaths || '-'}</ListItemText>
</ListItem>
</List>
</Box>
<Divider className={classes.divider} />
<Box>
<List className={classes.medicineList} disablePadding>
{needs?.map(item => (
<ListItem key={item?.id || item?.type + item?.count} disableGutters>
<SvgIcon viewBox='0 0 36 36' className={classes.listItemIcon}>
<path d={medicineIcons[item?.type.toLowerCase()] || medicineIcons.other} fill="white" />
</SvgIcon>
<ListItemText
primary={medicine[item?.type.toLowerCase()] || item?.type}
secondary={item?.count}
primaryTypographyProps={{ style: primaryTypographyStyle }}
secondaryTypographyProps={{ style: secondaryTypographyStyle }} />
</ListItem>
))}
</List>
</Box>
</Box>
</Popover >
);
})
Example #8
Source File: SideComp.js From eSim-Cloud with GNU General Public License v3.0 | 4 votes |
export default function SideComp ({ isFavourite = false, favourite, setFavourite, component }) {
const classes = useStyles()
const imageRef = React.createRef()
const [openSnackbar, setOpenSnackbar] = React.useState(false)
const [anchorEl, setAnchorEl] = React.useState(null)
const [snackbarMessage, setSnackbarMessage] = React.useState(null)
const handleClick = (event) => {
setAnchorEl(event.currentTarget)
}
const handleClose = () => {
setAnchorEl(null)
}
const handleSnackbarClose = (event, reason) => {
if (reason === 'clickaway') {
return
}
setOpenSnackbar(false)
}
const open = Boolean(anchorEl)
const id = open ? 'simple-popover' : undefined
useEffect(() => {
// Function call to make components draggable
AddComponent(component, imageRef.current)
// eslint-disable-next-line
}, [])
useEffect(() => {
if (snackbarMessage !== null) { setOpenSnackbar(true) }
}, [snackbarMessage])
useEffect(() => {
if (openSnackbar === false) { setSnackbarMessage(null) }
}, [openSnackbar])
const addFavourite = (id) => {
const token = localStorage.getItem('esim_token')
const body = {
component: [id]
}
const config = {
headers: {
'Content-Type': 'application/json'
}
}
if (token) {
config.headers.Authorization = `Token ${token}`
}
api.post('favouritecomponents', body, config).then(resp => {
setFavourite(resp.data.component)
setSnackbarMessage('Component is added to favourites successfully')
}).catch(err => {
console.log(err)
})
setAnchorEl(null)
}
const handleFavourite = (id) => {
if (favourite) {
var flag = 0
for (var i = 0; i < favourite.length; i++) {
if (favourite[i].id === id) {
flag = 1
break
}
}
if (!flag) {
addFavourite(id)
} else {
setSnackbarMessage('This component is already added to favourites')
setAnchorEl(null)
}
} else {
addFavourite(id)
}
}
const handleRemove = (id) => {
const token = localStorage.getItem('esim_token')
const config = {
headers: {
'Content-Type': 'application/json'
}
}
if (token) {
config.headers.Authorization = `Token ${token}`
}
api.delete(`favouritecomponents/${id}`, config).then(resp => {
setFavourite(resp.data.component)
}).catch(err => {
console.log(err)
})
setAnchorEl(null)
}
return (
<div>
<Tooltip title={component.full_name + ' : ' + component.description} arrow>
{/* Display Image thumbnail in left side pane */}
<img ref={imageRef} className='compImage' src={'../' + component.svg_path} alt="Logo" aria-describedby={id} onClick={handleClick} />
</Tooltip>
{/* Popover to display component information on single click */}
<Popover
id={id}
open={open}
className={classes.popup}
anchorEl={anchorEl}
onClose={handleClose}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center'
}}
transformOrigin={{
vertical: 'top',
horizontal: 'center'
}}
>
<List component="div" className={classes.popupInfo} disablePadding dense >
<ListItemText>
<b>Component Name:</b> {component.name}
</ListItemText>
{component.description !== '' &&
<ListItemText>
<b>Description:</b> {component.description}
</ListItemText>
}
{
component.keyword !== '' &&
<ListItemText>
<b>Keywords:</b> {component.keyword}
</ListItemText>
}
{
component.data_link !== '' &&
<ListItemText>
<b>Datasheet:</b> <a href={component.data_link} rel="noopener noreferrer" target='_blank' >{component.data_link}</a>
</ListItemText>
}
{!isFavourite && localStorage.getItem('esim_token') &&
<ListItemText>
<Button onClick={() => handleFavourite(component.id)}>Add to Favourites</Button>
</ListItemText>
}
{isFavourite && localStorage.getItem('esim_token') &&
<ListItemText>
<Button onClick={() => handleRemove(component.id)}>Remove from Favourites</Button>
</ListItemText>
}
</List>
</Popover>
<Snackbar
style={{ zIndex: 100 }}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left'
}}
open={openSnackbar}
autoHideDuration={2000}
onClose={handleSnackbarClose}
message={snackbarMessage}
action={
<>
<IconButton size="small" aria-label="close" color="inherit" onClick={handleSnackbarClose}>
<CloseIcon fontSize="small" />
</IconButton>
</>
}
/>
</div>
)
}
Example #9
Source File: User.js From virtualdojo-rooms with GNU General Public License v3.0 | 4 votes |
function User({
user,
currentUser,
avatarSize,
inRoom,
avatarColor,
changeRoom,
dragDisabled,
}) {
const { setIsDragging } = useContext(store);
const classes = useStyles();
const [anchorEl, setAnchorEl] = useState(null);
const handlePopoverOpen = (event) => {
setAnchorEl(event.currentTarget);
};
const handlePopoverClose = () => {
setAnchorEl(null);
};
const canDrag = currentUser.isMentor && !dragDisabled;
const [{ isDragging }, drag] = useDrag({
item: { name: user.userName, type: ItemTypes.USER },
begin: () => setIsDragging(true),
canDrag,
end: (item, monitor) => {
const dropResult = monitor.getDropResult();
setIsDragging(false);
if (item && dropResult) {
changeRoom(user.userId, dropResult.room.roomId);
}
},
collect: (monitor) => ({
isDragging: monitor.isDragging(),
}),
});
const avatarWidthHeight = avatarSize === "sm" ? 24 : 36;
const popoverOpen = !isDragging && Boolean(anchorEl);
const initials = user.userName
.trim()
.split(" ")
.slice(0, 2)
.map((s) => (s && [...s].length > 0 ? [...s][0].toUpperCase() : ""));
console.log(initials);
return (
<Grid
item
style={{
opacity: isDragging ? "0.4" : "1",
}}
onMouseEnter={handlePopoverOpen}
onMouseLeave={handlePopoverClose}
>
<Avatar
style={{
...avatarColor,
width: avatarWidthHeight,
height: avatarWidthHeight,
cursor: canDrag ? "grab" : "default",
borderRadius: user.isMentor ? 0 : "50%",
}}
ref={drag}
>
{initials}
</Avatar>
<Popover
id="mouse-over-popover"
className={classes.popover}
classes={{
paper: classes.paper,
}}
open={popoverOpen}
anchorEl={anchorEl}
anchorOrigin={{
vertical: "bottom",
horizontal: "left",
}}
transformOrigin={{
vertical: "top",
horizontal: "left",
}}
onClose={handlePopoverClose}
disableRestoreFocus
>
<Typography>
{user.userName}
{user.isMentor && <b> (Mentor)</b>}
</Typography>
</Popover>
</Grid>
);
}
Example #10
Source File: feedComponent.js From Kurakoo with MIT License | 4 votes |
function Feed({ username, question, img, profession, answer }) {
const [likeDislike, setLikeDislike] = useState([false, false]);
const [mark,setMark] = useState([false, false]);
const [openPopup, setOpenPopup] = useState(false);
const classes = useStyles();
const [anchorEl, setAnchorEl] = React.useState(null);
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
const open = Boolean(anchorEl);
const id = open ? 'simple-popover' : undefined;
const handleOpen = () => {
setOpenPopup(true);
};
const handleCloseModal = () => {
setOpenPopup(false);
}
return (
<div>
<section className="feed-component">
<div className="bio-div">
<img src={img} id="profile-pic" alt="img" />
<div id="bio-details">
<h4 id="username">{username}</h4>
<small>{profession} </small>
<span
onClick={() =>
mark[0]
? setMark([false, false])
: setMark([true, false])
}
>
{mark[0] ? (
<BookmarkIcon className={classes.bookMarkIcon} />
) : (
<BookmarkBorderIcon className={classes.bookMarkIcon} />
)}
</span>
</div>
</div>
<hr />
<div id="feed-content">
<h4 id="question">{question}</h4>
<p id="answer">{answer}</p>
</div>
<hr />
<div id="response-bar">
<button
class="button"
onClick={() =>
likeDislike[0]
? setLikeDislike([false, false])
: setLikeDislike([false, true])
}
>
{likeDislike[0] ? (
<ThumbUpIcon />
) : (
<ThumbUpOutlinedIcon />
)}
</button>
<button
class="button"
onClick={() =>
likeDislike[1]
? setLikeDislike([false, false])
: setLikeDislike([false, true])
}
>
{likeDislike[1] ? (
<ThumbDownIcon />
) : (
<ThumbDownOutlinedIcon />
)}
</button>
<button class="button" onClick={handleClick}>
<InsertCommentOutlinedIcon />
</button>
<button class="ans_button" onClick={handleOpen}>Answer</button>
</div>
</section>
<Modal
open ={openPopup}
onClose={handleCloseModal}>
<div className={classes.paper}>
<AnswerQuestion/>
</div>
</Modal>
<Popover
className={classes.pop}
id={id}
open={open}
anchorEl={anchorEl}
onClose={handleClose}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left',
}}
>
{/* <Box className={classes.divArea}>
<Typography className={classes.typography}>
<TextareaAutosize className={classes.commentArea} aria-label="empty textarea" placeholder="Empty" />
<Button variant="contained" color="secondary">
Submit
</Button>
</Typography>
</Box> */}
<div>
<Card className={classes.card}>
<CardContent>
<TextField
id="outlined-multiline-static"
label=""
multiline
rows={2}
fullWidth
variant="outlined"
/>
</CardContent>
<CardActions>
<Button size="small" variant="contained" color="secondary" className={classes.button}>Submit</Button>
</CardActions>
</Card>
</div>
</Popover>
</div>
);
}
Example #11
Source File: Projects.js From eSim-Cloud with GNU General Public License v3.0 | 4 votes |
function PublicProjects (props) {
const classes = useStyles()
const dispatch = useDispatch()
const projects = useSelector(state => state.dashboardReducer.publicProjects)
const [sort, setSort] = React.useState('')
const [order, setOrder] = React.useState('ascending')
const [filteredProjects, setFilteredProjects] = React.useState(projects)
const [anchorEl, setAnchorEl] = React.useState(null)
const open = Boolean(anchorEl)
useEffect(() => {
dispatch(fetchPublicProjects())
}, [dispatch])
useEffect(() => {
setFilteredProjects(projects)
}, [projects])
const handleFilterOpen = (e) => {
if (anchorEl) {
setAnchorEl(null)
} else {
setAnchorEl(e.currentTarget)
}
}
const sortSaves = (sorting, order) => {
if (order === 'ascending') {
if (sorting === 'name') {
setFilteredProjects(filteredProjects.sort((a, b) => a.title > b.title))
} else if (sorting === 'author') {
setFilteredProjects(filteredProjects.sort((a, b) => a.author > b.author))
} else if (sorting === 'status') {
setFilteredProjects(filteredProjects.sort((a, b) => a.status_name > b.status_name))
}
} else {
if (sorting === 'name') {
setFilteredProjects(filteredProjects.sort((a, b) => a.title < b.title))
} else if (sorting === 'author') {
setFilteredProjects(filteredProjects.sort((a, b) => a.author < b.author))
} else if (sorting === 'status') {
setFilteredProjects(filteredProjects.sort((a, b) => a.status_name < b.status_name))
}
}
}
const handleSort = (e) => {
sortSaves(e.target.value, order)
setSort(e.target.value)
}
const handleOrder = (e) => {
setOrder(e.target.value)
if (sort !== '') {
sortSaves(sort, e.target.value)
}
}
const onSearch = (e) => {
setFilteredProjects(projects.filter((o) =>
// eslint-disable-next-line
Object.keys(o).some((k) => {
if ((k === 'title' || k === 'description' || k === 'author' || k === 'status_name') && String(o[k]).toLowerCase().includes(e.target.value.toLowerCase())) {
return String(o[k]).toLowerCase().includes(e.target.value.toLowerCase())
}
}
)
))
}
return (
<div className={classes.root}>
<CssBaseline />
<Container maxWidth="lg" className={classes.header}>
<Grid
container
direction="row"
justify="flex-start"
alignItems="flex-start"
alignContent="center"
spacing={3}
>
{/* eSim Gallery Header */}
<Grid item xs={12}>
<MainCard />
</Grid>
<Grid item xs={12}>
{filteredProjects && <IconButton onClick={handleFilterOpen} style={{ float: 'right' }} ><FilterListIcon /></IconButton>}
{filteredProjects && <Input style={{ float: 'right' }} onChange={(e) => onSearch(e)} placeholder='Search' />}
<Popover
open={open}
onClose={handleFilterOpen}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center'
}}
transformOrigin={{
vertical: 'top',
horizontal: 'center'
}}
anchorEl={anchorEl}
>
<FormControl style={{ width: ' 200px', padding: '2%' }}>
<InputLabel>Select Sort</InputLabel>
<Select className={classes.popover} value={sort} onChange={handleSort} >
<MenuItem key='name' value='name'>Name</MenuItem>
<MenuItem key='author' value='author'>Author</MenuItem>
<MenuItem key='status' value='status'>Status</MenuItem>
</Select>
</FormControl>
<FormControl style={{ width: ' 200px', padding: '2%' }}>
<InputLabel>Select Order</InputLabel>
<Select className={classes.popover} value={order} onChange={handleOrder} >
<MenuItem key='ascending' value='ascending'>Ascending</MenuItem>
<MenuItem key='descending' value='descending'>Descending</MenuItem>
</Select>
</FormControl>
</Popover>
</Grid>
{/* Listing Gallery Schematics */}
{filteredProjects.map(
(pub) => {
console.log(pub)
return (
<Grid item xs={12} sm={6} lg={4} key={pub.save_id}>
<ProjectCard pub={pub} is_review={true} />
</Grid>
)
})}
</Grid>
</Container>
</div>
)
}
Example #12
Source File: SimulationProperties.js From eSim-Cloud with GNU General Public License v3.0 | 4 votes |
export default function SimulationProperties (props) {
const netfile = useSelector(state => state.netlistReducer)
const isSimRes = useSelector(state => state.simulationReducer.isSimRes)
const [taskId, setTaskId] = useState(null)
const dispatch = useDispatch()
const classes = useStyles()
const [nodeList, setNodeList] = useState([])
const [componentsList, setComponentsList] = useState([])
const [errMsg, setErrMsg] = useState('')
const [err, setErr] = useState(false)
const [error, setError] = useState(false)
const [warning, setWarning] = useState(false)
const [needParameters, setNeedParameters] = useState(false)
const [status, setStatus] = useState('')
const stats = { loading: 'loading', error: 'error', success: 'success' }
const [dcSweepcontrolLine, setDcSweepControlLine] = useState(props.dcSweepcontrolLine ? props.dcSweepcontrolLine : {
parameter: '',
sweepType: 'Linear',
start: '',
stop: '',
step: '',
parameter2: '',
start2: '',
stop2: '',
step2: ''
})
const [transientAnalysisControlLine, setTransientAnalysisControlLine] = useState(props.transientAnalysisControlLine ? props.transientAnalysisControlLine : {
start: '0',
stop: '',
step: '',
skipInitial: false
})
const [acAnalysisControlLine, setAcAnalysisControlLine] = useState(props.acAnalysisControlLine ? props.acAnalysisControlLine : {
input: 'dec',
start: '',
stop: '',
pointsBydecade: ''
})
const [tfAnalysisControlLine, setTfAnalysisControlLine] = useState(props.tfAnalysisControlLine ? props.tfAnalysisControlLine : {
outputNodes: false,
outputVoltageSource: '',
inputVoltageSource: ''
})
const [NoiseAnalysisControlLine, setNoiseAnalysisControlLine] = useState(props.NoiseAnalysisControlLine ? props.NoiseAnalysisControlLine : {
inputVoltageSource: '',
input: 'dec',
start: '',
stop: '',
pointsBydecade: '',
outputSpectrum: false
})
const [controlBlockParam, setControlBlockParam] = useState('')
const [simType, setSimType] = React.useState('')
let typeSimulation = ''
const handleControlBlockParam = (evt) => {
setControlBlockParam(evt.target.value)
}
const analysisNodeArray = []
const analysisCompArray = []
const nodeArray = []
const nodeNoiseArray = []
// const pushZero = (nodeArray) => {
// nodeArray.push({ key: 0 })
// }
const onTabExpand = () => {
try {
setComponentsList(['', ...GenerateCompList()])
setNodeList(['', ...GenerateNodeList()])
} catch (err) {
setComponentsList([])
setNodeList([])
setWarning(true)
}
}
const handleDcSweepControlLine = (evt) => {
const value = evt.target.value
setDcSweepControlLine({
...dcSweepcontrolLine,
[evt.target.id]: value
})
}
const handleTransientAnalysisControlLine = (evt) => {
const value = evt.target.value
setTransientAnalysisControlLine({
...transientAnalysisControlLine,
[evt.target.id]: value
})
}
const handleTransientAnalysisControlLineUIC = (evt) => {
const value = evt.target.checked
setTransientAnalysisControlLine({
...transientAnalysisControlLine,
[evt.target.id]: value
})
}
const handleAcAnalysisControlLine = (evt) => {
const value = evt.target.value
setAcAnalysisControlLine({
...acAnalysisControlLine,
[evt.target.id]: value
})
}
const handleTfAnalysisControlLine = (evt) => {
const value = evt.target.value
setTfAnalysisControlLine({
...tfAnalysisControlLine,
[evt.target.id]: value
})
}
const handleTfAnalysisControlLineNodes = (evt) => {
const value = evt.target.checked
setTfAnalysisControlLine({
...tfAnalysisControlLine,
[evt.target.id]: value
})
}
const handleNoiseAnalysisControlLine = (evt) => {
const value = evt.target.value
setNoiseAnalysisControlLine({
...NoiseAnalysisControlLine,
[evt.target.id]: value
})
}
const [simulateOpen, setSimulateOpen] = React.useState(false)
const handlesimulateOpen = () => {
setSimulateOpen(true)
}
const handleSimulateClose = () => {
setSimulateOpen(false)
}
const [simResult, setSimResult] = React.useState({})
const handleSimulationResult = (simResults) => {
setSimResult(simResults)
}
const acTypeOptionList = {
Linear: 'lin',
Decade: 'dec',
Octave: 'oct'
}
const [selectedValue, setSelectedValue] = React.useState([])
const [selectedValueDCSweep, setSelectedValueDCSweep] = React.useState([])
const [selectedValueTransientAnal, setSelectedValueTransientAnal] = React.useState([])
const [selectedValueTFAnal, setSelectedValueTFAnal] = React.useState([])
const [selectedValueNoiseAnal, setSelectedValueNoiseAnal] = React.useState([])
const [selectedValueComp, setSelectedValueComp] = React.useState([])
const [selectedValueDCSweepComp, setSelectedValueDCSweepComp] = React.useState([])
const [selectedValueTransientAnalComp, setSelectedValueTransientAnalComp] = React.useState([])
const [selectedgraphNoiseComp, setSelectedgraphNoiseComp] = React.useState([])
const handleAddSelectedValueDCSweep = (data) => {
let f = 0
selectedValueDCSweep.forEach((value, i) => {
if (value[i] !== undefined) {
if (value[i].key === data) f = 1
}
})
if (f === 0) {
const tmp = [...selectedValueDCSweep, data]
setSelectedValueDCSweep(tmp)
}
// console.log(selectedValue)
}
const handleRemSelectedValueDCSweep = (data) => {
const tmp = []
selectedValueDCSweep.forEach((value, i) => {
if (value[i] !== undefined) {
if (value[i].key !== data) tmp.push(data)
}
})
setSelectedValueDCSweep(tmp)
// console.log(selectedValue)
}
const handleAddSelectedValueTransientAnal = (data) => {
let f = 0
selectedValueTransientAnal.forEach((value, i) => {
if (value[i] !== undefined) {
if (value[i].key === data) f = 1
}
})
if (f === 0) {
const tmp = [...selectedValueTransientAnal, data]
setSelectedValueTransientAnal(tmp)
}
// console.log(selectedValue)
}
const handleRemSelectedValueTransientAnal = (data) => {
const tmp = []
selectedValueTransientAnal.forEach((value, i) => {
if (value[i] !== undefined) {
if (value[i].key !== data) tmp.push(data)
}
})
setSelectedValueTransientAnal(tmp)
// console.log(selectedValue)
}
const handleAddSelectedValueTFAnal = (data) => {
let f = 0
selectedValueTFAnal.forEach((value, i) => {
if (value[i] !== undefined) {
if (value[i].key === data) f = 1
}
})
if (f === 0) {
const tmp = [...selectedValueTFAnal, data]
setSelectedValueTFAnal(tmp)
}
// console.log(selectedValue)
}
const handleRemSelectedValueTFAnal = (data) => {
const tmp = []
selectedValueTFAnal.forEach((value, i) => {
if (value[i] !== undefined) {
if (value[i].key !== data) tmp.push(data)
}
})
setSelectedValueTFAnal(tmp)
// console.log(selectedValue)
}
const handleAddSelectedValueNoiseAnal = (data) => {
let f = 0
selectedValueNoiseAnal.forEach((value, i) => {
if (value[i] !== undefined) {
if (value[i].key === data) f = 1
}
})
if (f === 0) {
const tmp = data
setSelectedValueNoiseAnal(tmp)
}
}
const handleRemSelectedValueNoiseAnal = (data) => {
setSelectedValueNoiseAnal(data)
}
const handleAddSelectedValueDCSweepComp = (data) => {
let f = 0
selectedValueDCSweepComp.forEach((value, i) => {
if (value[i] !== undefined) {
if (value[i].key === data) f = 1
}
})
if (f === 0) {
const tmp = [...selectedValueDCSweepComp, data]
setSelectedValueDCSweepComp(tmp)
}
// console.log(selectedValue)
}
const handleRemSelectedValueDCSweepComp = (data) => {
const tmp = []
selectedValueDCSweepComp.forEach((value, i) => {
if (value[i] !== undefined) {
if (value[i].key !== data) tmp.push(data)
}
})
setSelectedValueDCSweepComp(tmp)
// console.log(selectedValue)
}
const handleAddSelectedValueTransientAnalComp = (data) => {
let f = 0
selectedValueTransientAnalComp.forEach((value, i) => {
if (value[i] !== undefined) {
if (value[i].key === data) f = 1
}
})
if (f === 0) {
const tmp = [...selectedValueTransientAnalComp, data]
setSelectedValueTransientAnalComp(tmp)
}
// console.log(selectedValue)
}
const handleRemSelectedValueTransientAnalComp = (data) => {
const tmp = []
selectedValueTransientAnalComp.forEach((value, i) => {
if (value[i] !== undefined) {
if (value[i].key !== data) tmp.push(data)
}
})
setSelectedValueTransientAnalComp(tmp)
// console.log(selectedValue)
}
const handleNoiseOutputMode = (evt) => {
const value = evt.target.checked
setNoiseAnalysisControlLine({
...NoiseAnalysisControlLine,
[evt.target.id]: value
})
}
const handleErrOpen = () => {
setErr(true)
}
const handleErrClose = () => {
setErr(false)
}
const handleErrMsg = (msg) => {
setErrMsg(msg)
}
const handleStatus = (status) => {
setStatus(status)
}
// Prepare Netlist to file
const prepareNetlist = (netlist) => {
const titleA = netfile.title.split(' ')[1]
const myblob = new Blob([netlist], {
type: 'text/plain'
})
const file = new File([myblob], `${titleA}.cir`, { type: 'text/plain', lastModified: Date.now() })
// console.log(file)
sendNetlist(file)
}
function sendNetlist (file) {
setIsResult(false)
netlistConfig(file)
.then((response) => {
const res = response.data
const getUrl = 'simulation/status/'.concat(res.details.task_id)
setTaskId(res.details.task_id)
simulationResult(getUrl)
})
.catch(function (error) {
console.log(error)
})
}
// Upload the nelist
function netlistConfig (file) {
const token = localStorage.getItem('esim_token')
const url = queryString.parse(window.location.href.split('editor?')[1])
const formData = new FormData()
formData.append('simulationType', typeSimulation)
formData.append('file', file)
if (url.id) {
formData.append('save_id', url.id)
formData.append('version', url.version)
formData.append('branch', url.branch)
}
if (url.lti_nonce) {
formData.append('lti_id', url.lti_id)
}
const config = {
headers: {
'content-type': 'multipart/form-data'
}
}
if (token) {
config.headers.Authorization = `Token ${token}`
}
setSimType(typeSimulation)
return api.post('simulation/upload', formData, config)
}
const [isResult, setIsResult] = useState(false)
// Get the simulation result with task_Id
function simulationResult (url) {
let isError = false
let msg
let resPending = true // to stop immature opening of simulation screen
api
.get(url)
.then((res) => {
if (res.data.state === 'PROGRESS' || res.data.state === 'PENDING') {
handleStatus(stats.loading)
setTimeout(simulationResult(url), 1000)
} else if (Object.prototype.hasOwnProperty.call(res.data.details, 'fail')) {
resPending = false
setIsResult(false)
console.log('failed notif')
console.log(res.data.details)
msg = res.data.details.fail.replace("b'", '')
isError = true
console.log(err)
} else {
const result = res.data.details
resPending = false
if (result === null) {
setIsResult(false)
} else {
const temp = res.data.details.data
const data = result.data
// console.log('DATA SIm', data)
if (res.data.details.graph === 'true') {
const simResultGraph = { labels: [], x_points: [], y_points: [] }
// populate the labels
for (let i = 0; i < data.length; i++) {
simResultGraph.labels[0] = data[i].labels[0]
const lab = data[i].labels
// lab is an array containeing labels names ['time','abc','def']
simResultGraph.x_points = data[0].x
// labels
for (let x = 1; x < lab.length; x++) {
// if (lab[x].includes('#branch')) {
// lab[x] = `I (${lab[x].replace('#branch', '')})`
// }
// uncomment below if you want label like V(r1.1) but it will break the graph showing time as well
// else {
// lab[x] = `V (${lab[x]})`
// }
simResultGraph.labels.push(lab[x])
}
// populate y_points
for (let z = 0; z < data[i].y.length; z++) {
simResultGraph.y_points.push(data[i].y[z])
}
}
simResultGraph.x_points = simResultGraph.x_points.map(d => parseFloat(d))
for (let i1 = 0; i1 < simResultGraph.y_points.length; i1++) {
simResultGraph.y_points[i1] = simResultGraph.y_points[i1].map(d => parseFloat(d))
}
dispatch(setResultGraph(simResultGraph))
} else {
const simResultText = []
for (let i = 0; i < temp.length; i++) {
let postfixUnit = ''
if (temp[i][0].includes('#branch')) {
postfixUnit = 'A'
} else if (temp[i][0].includes('transfer_function')) {
postfixUnit = ''
} else if (temp[i][0].includes('impedance')) {
postfixUnit = 'Ohm'
} else {
temp[i][0] = `V(${temp[i][0]})`
postfixUnit = 'V'
}
simResultText.push(temp[i][0] + ' ' + temp[i][1] + ' ' + parseFloat(temp[i][2]) + ' ' + postfixUnit + '\n')
}
handleSimulationResult(res.data.details)
dispatch(setResultText(simResultText))
}
setIsResult(true)
props.setLtiSimResult(true)
}
}
})
.then((res) => {
if (isError === false && resPending === false) {
console.log('no error')
handleStatus(stats.success)
handlesimulateOpen()
} else if (resPending === false) {
handleStatus(stats.error)
handleErrMsg(msg)
}
handleErrOpen()
})
.catch(function (error) {
console.log(error)
})
}
const startSimulate = (type) => {
if (ErcCheckNets() && componentsList !== [] && nodeList !== []) {
let compNetlist
try {
compNetlist = GenerateNetList()
} catch {
setError(true)
return
}
let controlLine = ''
let controlBlock = ''
let skipMultiNodeChk = 0
let nodes = ''
let uic = ''
let noiseMode = ''
switch (type) {
case 'DcSolver':
// console.log('To be implemented')
typeSimulation = 'DcSolver'
controlLine = '.op'
dispatch(setResultTitle('DC Solver Output'))
break
case 'DcSweep':
// console.log(dcSweepcontrolLine)
if (dcSweepcontrolLine.parameter !== '' && dcSweepcontrolLine.start !== '' && dcSweepcontrolLine.stop !== '' && dcSweepcontrolLine.step !== '') {
typeSimulation = 'DcSweep'
controlLine = `.dc ${dcSweepcontrolLine.parameter} ${dcSweepcontrolLine.start} ${dcSweepcontrolLine.stop} ${dcSweepcontrolLine.step} ${dcSweepcontrolLine.parameter2} ${dcSweepcontrolLine.start2} ${dcSweepcontrolLine.stop2} ${dcSweepcontrolLine.step2}`
dispatch(setResultTitle('DC Sweep Output'))
setSelectedValue(selectedValueDCSweep)
setSelectedValueComp(selectedValueDCSweepComp)
} else {
setNeedParameters(true)
return
}
break
case 'Transient':
// console.log(transientAnalysisControlLine)
if (transientAnalysisControlLine.step !== '' && transientAnalysisControlLine.start !== '' && transientAnalysisControlLine.start !== '') {
typeSimulation = 'Transient'
if (transientAnalysisControlLine.skipInitial === true) uic = 'UIC'
controlLine = `.tran ${transientAnalysisControlLine.step} ${transientAnalysisControlLine.stop} ${transientAnalysisControlLine.start} ${uic}`
dispatch(setResultTitle('Transient Analysis Output'))
setSelectedValue(selectedValueTransientAnal)
setSelectedValueComp(selectedValueTransientAnalComp)
} else {
setNeedParameters(true)
return
}
break
case 'Ac':
// console.log(acAnalysisControlLine)
if (acAnalysisControlLine.input !== '' && acAnalysisControlLine.pointsBydecade !== '' && acAnalysisControlLine.start !== '' && acAnalysisControlLine.stop !== '') {
typeSimulation = 'Ac'
controlLine = `.ac ${acAnalysisControlLine.input} ${acAnalysisControlLine.pointsBydecade} ${acAnalysisControlLine.start} ${acAnalysisControlLine.stop}`
dispatch(setResultTitle('AC Analysis Output'))
} else {
setNeedParameters(true)
return
}
break
case 'tfAnalysis':
if (tfAnalysisControlLine.inputVoltageSource !== '') {
typeSimulation = 'tfAnalysis'
setSelectedValue(selectedValueTFAnal)
if (tfAnalysisControlLine.outputNodes === true) {
selectedValue.forEach((value, i) => {
if (value[i] !== undefined) {
nodes = nodes + ' ' + String(value[i].key)
}
})
nodes = 'V(' + nodes + ')'
} else {
nodes = `I(${tfAnalysisControlLine.outputVoltageSource})`
}
console.log(tfAnalysisControlLine.outputNodes)
controlLine = `.tf ${nodes} ${tfAnalysisControlLine.inputVoltageSource}`
dispatch(setResultTitle('Transfer Function Analysis Output'))
skipMultiNodeChk = 1
} else {
setNeedParameters(true)
return
}
break
case 'noiseAnalysis':
// console.log('Start noise analysis simulation', selectedValueNoiseAnal, NoiseAnalysisControlLine)
typeSimulation = 'noiseAnalysis'
var node1 = selectedValueNoiseAnal[0].key
var node2 = '0'
if (selectedValueNoiseAnal.length > 1) {
node2 = selectedValueNoiseAnal[1].key
}
if (NoiseAnalysisControlLine.inputVoltageSource && NoiseAnalysisControlLine.pointsBydecade && NoiseAnalysisControlLine.input && NoiseAnalysisControlLine.start && NoiseAnalysisControlLine.stop) {
controlLine = `.noise v(${node1}, ${node2}) ${NoiseAnalysisControlLine.inputVoltageSource} ${NoiseAnalysisControlLine.input} ${NoiseAnalysisControlLine.pointsBydecade} ${NoiseAnalysisControlLine.start} ${NoiseAnalysisControlLine.stop}`
noiseMode = NoiseAnalysisControlLine.outputSpectrum ? 'setplot noise1' : 'setplot noise2'
dispatch(setResultTitle('Noise Analysis Output'))
} else {
setNeedParameters(true)
return
}
break
default:
break
}
// console.log(selectedValue)
let atleastOne = 0
let cblockline = ''
// if either the extra expression field or the nodes multi select
// drop down list in enabled then atleast one value is made non zero
// to add add all instead to the print statement.
if (selectedValue.length > 0 && selectedValue !== null && skipMultiNodeChk === 0) {
selectedValue.forEach((value, i) => {
if (value[i] !== undefined && value[i].key !== 0) {
atleastOne = 1
cblockline = cblockline + ' ' + String(value[i].key)
}
})
}
if (selectedValueComp.length > 0 && selectedValueComp !== null) {
selectedValueComp.forEach((value, i) => {
if (value[i] !== undefined && value[i].key !== 0) {
atleastOne = 1
if (value[i].key.charAt(0) === 'V' || value[i].key.charAt(0) === 'v') {
cblockline = cblockline + ' I(' + String(value[i].key) + ') '
}
}
})
}
if (controlBlockParam.length > 0) {
cblockline = cblockline + ' ' + controlBlockParam
atleastOne = 1
}
if (atleastOne === 0) cblockline = 'all'
if (typeSimulation !== 'noiseAnalysis') {
controlBlock = `\n.control \nrun \nprint ${cblockline} > data.txt \n.endc \n.end`
} else {
controlBlock = `\n.control \nrun \n${noiseMode} \nprint ${cblockline} > data.txt \n.endc \n.end`
}
// console.log(controlLine)
dispatch(setControlLine(controlLine))
dispatch(setControlBlock(controlBlock))
// setTimeout(function () { }, 2000)
const netlist = netfile.title + '\n\n' +
compNetlist.models + '\n' +
compNetlist.main + '\n' +
controlLine + '\n' +
controlBlock + '\n'
dispatch(setNetlist(netlist))
prepareNetlist(netlist)
}
// handlesimulateOpen()
}
// simulation properties add expression input box
const [anchorEl, setAnchorEl] = React.useState(null)
const handleAddExpressionClick = (event) => {
setAnchorEl(event.currentTarget)
}
const handleAddExpressionClose = () => {
setAnchorEl(null)
}
const open = Boolean(anchorEl)
const id = open ? 'simple-popover' : undefined
return (
<>
<div className={classes.SimulationOptions}>
<Snackbar
open={needParameters}
autoHideDuration={6000}
onClose={() => setNeedParameters(false)}
>
<Alert onClose={() => setNeedParameters(false)} severity="error">
Please enter the necessary parameters!
</Alert>
</Snackbar>
<Snackbar
open={warning}
autoHideDuration={6000}
onClose={() => setWarning(false)}
>
<Alert onClose={() => setWarning(false)} severity="warning">
Circuit is not complete to be simulated!
</Alert>
</Snackbar>
<Snackbar
open={error}
autoHideDuration={6000}
onClose={() => setError(false)}
>
<Alert onClose={() => setError(false)} severity="error">
Cannot simulate an incomplete circuit!
</Alert>
</Snackbar>
<SimulationScreen open={simulateOpen} isResult={isResult} close={handleSimulateClose} taskId={taskId} simType={simType} />
<Notice status={status} open={err} msg={errMsg} close={handleErrClose} />
{/* Simulation modes list */}
<List>
{/* DC Solver */}
<ListItem className={classes.simulationOptions} divider>
<div className={classes.propertiesBox}>
<ExpansionPanel onClick={onTabExpand}>
<ExpansionPanelSummary
expandIcon={<ExpandMoreIcon />}
aria-controls="panel1a-content"
id="panel1a-header"
style={{ width: '100% ' }}
>
<Typography className={classes.heading}>DC Solver</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<form>
<List>
<ListItem>
<Button aria-describedby={id} variant="outlined" color="primary" size="small" onClick={handleAddExpressionClick}>
Add Expression
</Button>
<Tooltip title={'Add expression seperated by spaces.\n Include #branch at end of expression to indicate current e.g v1#branch. To add multiple expression seperate them by spaces eg. v1 v2 v3#branch'}>
<IconButton aria-label="info">
<InfoOutlinedIcon style={{ fontSize: 'large' }} />
</IconButton>
</Tooltip>
<Popover
id={id}
open={open}
anchorEl={anchorEl}
onClose={handleAddExpressionClose}
anchorOrigin={{
vertical: 'center',
horizontal: 'left'
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left'
}}
>
<TextField id="controlBlockParam" placeHolder="enter expression" size='large' variant="outlined"
value={controlBlockParam}
onChange={handleControlBlockParam}
/>
</Popover>
</ListItem>
<ListItem>
<Button size='small' variant="contained" color="primary"
onClick={(e) => { startSimulate('DcSolver') }}>
Run dc solver
</Button>
</ListItem>
</List>
</form>
</ExpansionPanelDetails>
</ExpansionPanel>
</div>
</ListItem>
{/* DC Sweep */}
<ListItem className={classes.simulationOptions} divider>
<ExpansionPanel onClick={onTabExpand}>
<ExpansionPanelSummary
expandIcon={<ExpandMoreIcon />}
aria-controls="panel1a-content"
id="panel1a-header"
style={{ width: '97%' }}
>
<Typography className={classes.heading}>DC Sweep</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<form className={classes.propertiesBox} noValidate autoComplete="off">
<List>
<ListItem>
<TextField
style={{ width: '100%' }}
id="parameter"
size='small'
variant="outlined"
select
label="Select Component"
value={dcSweepcontrolLine.parameter}
error={!dcSweepcontrolLine.parameter}
onChange={handleDcSweepControlLine}
SelectProps={{
native: true
}}
>
{
componentsList.map((value, i) => {
if (value.charAt(0) === 'V' || value.charAt(0) === 'v' || value.charAt(0) === 'I' || value.charAt(0) === 'i' || value === '') {
return (<option key={i} value={value}>
{value}
</option>)
} else {
return null
}
})
}
</TextField>
</ListItem>
<ListItem>
<TextField id="start" label="Start Voltage" size='small' variant="outlined"
value={dcSweepcontrolLine.start}
error={!dcSweepcontrolLine.start}
onChange={handleDcSweepControlLine}
/>
<span style={{ marginLeft: '10px' }}>V</span>
</ListItem>
<ListItem>
<TextField id="stop" label="Stop Voltage" size='small' variant="outlined"
value={dcSweepcontrolLine.stop}
error={!dcSweepcontrolLine.stop}
onChange={handleDcSweepControlLine}
/>
<span style={{ marginLeft: '10px' }}>V</span>
</ListItem>
<ListItem>
<TextField id="step" label="Step" size='small' variant="outlined"
value={dcSweepcontrolLine.step}
error={!dcSweepcontrolLine.step}
onChange={handleDcSweepControlLine}
/>
<span style={{ marginLeft: '10px' }}>V</span>
</ListItem>
{/* SECONDARY PARAMETER FOR SWEEP */}
<Divider />
<ListItem>
<h4 style={{ marginLeft: '10px' }}>Secondary Parameters</h4>
</ListItem>
<ListItem>
<TextField
style={{ width: '100%' }}
id="parameter2"
size='small'
variant="outlined"
select
label="Select Component"
value={dcSweepcontrolLine.parameter2}
onChange={handleDcSweepControlLine}
SelectProps={{
native: true
}}
>
{
componentsList.map((value, i) => {
return <option key={i} value={value}>
{value}
</option>
})
}
</TextField>
</ListItem>
<ListItem>
<TextField id="start2" label="Start Value" size='small' variant="outlined"
value={dcSweepcontrolLine.start2}
onChange={handleDcSweepControlLine}
/>
</ListItem>
<ListItem>
<TextField id="stop2" label="Stop Value" size='small' variant="outlined"
value={dcSweepcontrolLine.stop2}
onChange={handleDcSweepControlLine}
/>
</ListItem>
<ListItem>
<TextField id="step2" label="Step Value" size='small' variant="outlined"
value={dcSweepcontrolLine.step2}
onChange={handleDcSweepControlLine}
/>
</ListItem>
<ListItem>
<Multiselect
style={{ width: '100%' }}
id="Nodes"
closeOnSelect="false"
placeholder="Select Node"
onSelect={handleAddSelectedValueDCSweep}
onRemove={handleRemSelectedValueDCSweep}
options={analysisNodeArray} displayValue="key"
avoidHighlightFirstOption="true"
/>
</ListItem>
<ListItem>
<Multiselect
style={{ width: '100%' }}
id="Branch"
closeOnSelect="false"
placeholder="Select VSRC"
onSelect={handleAddSelectedValueDCSweepComp}
onRemove={handleRemSelectedValueDCSweepComp}
options={analysisCompArray} displayValue="key"
avoidHighlightFirstOption="true"
/>
</ListItem>
<ListItem>
<Button aria-describedby={id} variant="outlined" color="primary" size="small" onClick={handleAddExpressionClick}>
Add Expression
</Button>
<Tooltip title={'Add expression seperated by spaces.\n Include #branch at end of expression to indicate current e.g v1#branch. To add multiple expression seperate them by spaces eg. v1 v2 v3#branch'}>
<IconButton aria-label="info">
<InfoOutlinedIcon style={{ fontSize: 'large' }} />
</IconButton>
</Tooltip>
<Popover
id={id}
open={open}
anchorEl={anchorEl}
onClose={handleAddExpressionClose}
anchorOrigin={{
vertical: 'center',
horizontal: 'left'
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left'
}}
>
<TextField id="controlBlockParam" placeHolder="enter expression" size='large' variant="outlined"
value={controlBlockParam}
onChange={handleControlBlockParam}
/>
</Popover>
</ListItem>
<ListItem>
<Button id="dcSweepSimulate" size='small' variant="contained" color="primary" onClick={(e) => { startSimulate('DcSweep') }}>
Simulate
</Button>
</ListItem>
</List>
</form>
</ExpansionPanelDetails>
</ExpansionPanel>
</ListItem>
{/* Transient Analysis */}
<ListItem className={classes.simulationOptions} divider>
<ExpansionPanel onClick={onTabExpand}>
<ExpansionPanelSummary
expandIcon={<ExpandMoreIcon />}
aria-controls="panel1a-content"
id="panel1a-header"
style={{ width: '97%' }}
>
<Typography className={classes.heading}>Transient Analysis</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<form className={classes.propertiesBox} noValidate autoComplete="off">
<List>
<ListItem>
<TextField id="start" label="Start Time" size='small' variant="outlined"
value={transientAnalysisControlLine.start}
error={!transientAnalysisControlLine.start}
onChange={handleTransientAnalysisControlLine}
/>
<span style={{ marginLeft: '10px' }}>S</span>
</ListItem>
<ListItem>
<TextField id="stop" label="Stop Time" size='small' variant="outlined"
value={transientAnalysisControlLine.stop}
error={!transientAnalysisControlLine.stop}
onChange={handleTransientAnalysisControlLine}
/>
<span style={{ marginLeft: '10px' }}>S</span>
</ListItem>
<ListItem>
<TextField id="step" label="Time Step" size='small' variant="outlined"
value={transientAnalysisControlLine.step}
error={!transientAnalysisControlLine.step}
onChange={handleTransientAnalysisControlLine}
/>
<span style={{ marginLeft: '10px' }}>S</span>
</ListItem>
<ListItem>
<Checkbox id="skipInitial" label="Use Initial Conditions" size='small' variant="outlined"
value={transientAnalysisControlLine.skipInitial}
checked={transientAnalysisControlLine.skipInitial}
onChange={handleTransientAnalysisControlLineUIC}
/>
<span style={{ marginLeft: '10px' }}>Use Initial Conditions</span>
</ListItem>
<ListItem>
{nodeList.forEach((value) => {
if (value !== null && value !== '') {
analysisNodeArray.push({ key: value })
}
})
}
<Multiselect
style={{ width: '100%' }}
id="Nodes"
closeOnSelect="false"
placeholder="Select Node"
onSelect={handleAddSelectedValueTransientAnal}
onRemove={handleRemSelectedValueTransientAnal}
options={analysisNodeArray} displayValue="key"
avoidHighlightFirstOption="true"
/>
</ListItem>
<ListItem>
{
componentsList.forEach((value) => {
if (value !== null && value !== '') {
if (value.charAt(0) === 'V' || value.charAt(0) === 'v') {
analysisCompArray.push({ key: value })
}
}
})
}
<Multiselect
style={{ width: '100%' }}
id="Branch"
closeOnSelect="false"
placeholder="Select VSRC"
onSelect={handleAddSelectedValueTransientAnalComp}
onRemove={handleRemSelectedValueTransientAnalComp}
options={analysisCompArray} displayValue="key"
avoidHighlightFirstOption="true"
/>
</ListItem>
<ListItem>
<Button aria-describedby={id} variant="outlined" color="primary" size="small" onClick={handleAddExpressionClick}>
Add Expression
</Button>
<Tooltip title={'Add expression seperated by spaces.\n Include #branch at end of expression to indicate current e.g v1#branch. To add multiple expression seperate them by spaces eg. v1 v2 v3#branch'}>
<IconButton aria-label="info">
<InfoOutlinedIcon style={{ fontSize: 'large' }} />
</IconButton>
</Tooltip>
<Popover
id={id}
open={open}
anchorEl={anchorEl}
onClose={handleAddExpressionClose}
anchorOrigin={{
vertical: 'center',
horizontal: 'left'
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left'
}}
>
<TextField id="controlBlockParam" placeHolder="enter expression" size='large' variant="outlined"
value={controlBlockParam}
onChange={handleControlBlockParam}
/>
</Popover>
</ListItem>
<ListItem>
<Button id="transientAnalysisSimulate" size='small' variant="contained" color="primary" onClick={(e) => { startSimulate('Transient') }}>
Simulate
</Button>
</ListItem>
</List>
</form>
</ExpansionPanelDetails>
</ExpansionPanel>
</ListItem>
{/* AC Analysis */}
<ListItem className={classes.simulationOptions} divider>
<ExpansionPanel onClick={onTabExpand}>
<ExpansionPanelSummary
expandIcon={<ExpandMoreIcon />}
aria-controls="panel1a-content"
id="panel1a-header"
style={{ width: '100%' }}
>
<Typography className={classes.heading}>AC Analysis</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<form className={classes.propertiesBox} noValidate autoComplete="off">
<List>
<ListItem>
<TextField
style={{ width: '100%' }}
id="input"
size='small'
variant="outlined"
select
label="Type"
value={acAnalysisControlLine.input}
onChange={handleAcAnalysisControlLine}
SelectProps={{
native: true
}}
>
<option key="linear" value="lin">
Linear
</option>
<option key="decade" value="dec">
Decade
</option>
<option key="octave" value="oct">
Octave
</option>
</TextField>
</ListItem>
<ListItem>
<TextField id="pointsBydecade" label="Points/scale" size='small' variant="outlined"
value={acAnalysisControlLine.pointsBydecade}
error={!acAnalysisControlLine.pointsBydecade}
onChange={handleAcAnalysisControlLine}
/>
</ListItem>
<ListItem>
<TextField id="start" label="Start Frequency" size='small' variant="outlined"
value={acAnalysisControlLine.start}
error={!acAnalysisControlLine.start}
onChange={handleAcAnalysisControlLine}
/>
<span style={{ marginLeft: '10px' }}>Hz</span>
</ListItem>
<ListItem>
<TextField id="stop" label="Stop Frequency" size='small' variant="outlined"
value={acAnalysisControlLine.stop}
error={!acAnalysisControlLine.stop}
onChange={handleAcAnalysisControlLine}
/>
<span style={{ marginLeft: '10px' }}>Hz</span>
</ListItem>
<ListItem>
<Button aria-describedby={id} variant="outlined" color="primary" size="small" onClick={handleAddExpressionClick}>
Add Expression
</Button>
<Tooltip title={'Add expression seperated by spaces. Include #branch at end of expression to indicate current e.g v1#branch. To add multiple expression seperate them by spaces eg. v1 v2 v3#branch'}>
<IconButton aria-label="info">
<InfoOutlinedIcon style={{ fontSize: 'large' }} />
</IconButton>
</Tooltip>
<Popover
id={id}
open={open}
anchorEl={anchorEl}
onClose={handleAddExpressionClose}
anchorOrigin={{
vertical: 'center',
horizontal: 'left'
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left'
}}
>
<TextField id="controlBlockParam" placeHolder="enter expression" size='large' variant="outlined"
value={controlBlockParam}
onChange={handleControlBlockParam}
/>
</Popover>
</ListItem>
<ListItem>
<Button size='small' variant="contained" color="primary" onClick={(e) => { startSimulate('Ac') }}>
Simulate
</Button>
</ListItem>
</List>
</form>
</ExpansionPanelDetails>
</ExpansionPanel>
</ListItem>
{/* Transfer Function Analysis */}
<ListItem className={classes.simulationOptions} divider>
<ExpansionPanel onClick={onTabExpand}>
<ExpansionPanelSummary
expandIcon={<ExpandMoreIcon />}
aria-controls="panel1a-content"
id="panel1a-header"
style={{ width: '97%' }}
>
<Typography className={classes.heading}>Transfer Function Analysis</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<form className={classes.propertiesBox} noValidate autoComplete="off">
<List>
<ListItem>
<input
type="checkbox"
name="Between Nodes"
value={tfAnalysisControlLine.outputNodes}
checked={tfAnalysisControlLine.outputNodes}
onChange={handleTfAnalysisControlLineNodes}
id="outputNodes"
/>
<span style={{ marginLeft: '10px' }}>Output By Nodes</span>
</ListItem>
{nodeList.forEach((value) => {
if (value !== null && value !== '') {
nodeArray.push({ key: value })
}
})
}
{/* {pushZero(nodeArray)} */}
<ListItem>
<Multiselect
style={{ width: '100%' }}
id="Nodes"
closeOnSelect="false"
placeholder="Voltage between Nodes"
onSelect={handleAddSelectedValueTFAnal}
onRemove={handleRemSelectedValueTFAnal}
selectionLimit="2"
options={nodeArray} displayValue="key"
disable={!tfAnalysisControlLine.outputNodes}
avoidHighlightFirstOption="true"
/>
</ListItem>
<ListItem>
<TextField
style={{ width: '100%' }}
id="outputVoltageSource"
size='small'
variant="outlined"
select
label="Output Voltage SRC"
value={tfAnalysisControlLine.outputVoltageSource}
onChange={handleTfAnalysisControlLine}
SelectProps={{
native: true
}}
disabled={tfAnalysisControlLine.outputNodes}
>
{
componentsList.map((value, i) => {
if (value.charAt(0) === 'V' || value.charAt(0) === 'v' || value.charAt(0) === 'I' || value.charAt(0) === 'i' || value === '') {
return (<option key={i} value={value}>
{value}
</option>)
} else {
return null
}
})
}
</TextField>
</ListItem>
<ListItem>
<TextField
style={{ width: '100%' }}
id="inputVoltageSource"
size='small'
variant="outlined"
select
label="Input Voltage SRC"
value={tfAnalysisControlLine.inputVoltageSource}
error={!tfAnalysisControlLine.inputVoltageSource}
onChange={handleTfAnalysisControlLine}
SelectProps={{
native: true
}}
>
{
componentsList.map((value, i) => {
if (value.charAt(0) === 'V' || value.charAt(0) === 'v' || value.charAt(0) === 'I' || value.charAt(0) === 'i' || value === '') {
return (<option key={i} value={value}>
{value}
</option>)
} else {
return null
}
})
}
</TextField>
</ListItem>
<ListItem>
<Button aria-describedby={id} variant="outlined" color="primary" size="small" onClick={handleAddExpressionClick}>
Add Expression
</Button>
<Tooltip title={'Add expression seperated by spaces.\n Include #branch at end of expression to indicate current e.g v1#branch. To add multiple expression seperate them by spaces eg. v1 v2 v3#branch'}>
<IconButton aria-label="info">
<InfoOutlinedIcon style={{ fontSize: 'large' }} />
</IconButton>
</Tooltip>
<Popover
id={id}
open={open}
anchorEl={anchorEl}
onClose={handleAddExpressionClose}
anchorOrigin={{
vertical: 'center',
horizontal: 'left'
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left'
}}
>
<TextField id="controlBlockParam" placeHolder="enter expression" size='large' variant="outlined"
value={controlBlockParam}
onChange={handleControlBlockParam}
/>
</Popover>
</ListItem>
<ListItem>
<Button id="tfAnalysisSimulate" size='small' variant="contained" color="primary" onClick={(e) => { startSimulate('tfAnalysis') }}>
Simulate
</Button>
</ListItem>
</List>
</form>
</ExpansionPanelDetails>
</ExpansionPanel>
</ListItem>
{/* Noise Analysis */}
<ListItem className={classes.simulationOptions} divider>
<ExpansionPanel onClick={onTabExpand}>
<ExpansionPanelSummary
expandIcon={<ExpandMoreIcon />}
aria-controls="panel1a-content"
id="panel1a-header"
style={{ width: '97%' }}
>
<Typography className={classes.heading}>Noise Analysis</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<form className={classes.propertiesBox} noValidate autoComplete="off">
<List>
{nodeList.forEach((value) => {
if (value !== null && value !== '') {
nodeNoiseArray.push({ key: value })
}
})
}
{/* {pushZero(nodeArray)} */}
<ListItem>
<Multiselect
style={{ width: '100%' }}
id="Nodes"
closeOnSelect="false"
placeholder="Voltage between Nodes"
onSelect={handleAddSelectedValueNoiseAnal}
onRemove={handleRemSelectedValueNoiseAnal}
selectionLimit="2"
options={nodeNoiseArray} displayValue="key"
avoidHighlightFirstOption="true"
/>
</ListItem>
<ListItem>
<TextField
style={{ width: '100%' }}
id="inputVoltageSource"
size='small'
variant="outlined"
select
label="Input Voltage SRC"
value={handleNoiseAnalysisControlLine.inputVoltageSource}
error={!handleNoiseAnalysisControlLine.inputVoltageSource}
onChange={handleNoiseAnalysisControlLine}
SelectProps={{
native: true
}}
>
{
componentsList.map((value, i) => {
if (value.charAt(0) === 'V' || value.charAt(0) === 'v' || value.charAt(0) === 'I' || value.charAt(0) === 'i' || value === '') {
return (<option key={i} value={value}>
{value}
</option>)
} else {
return null
}
})
}
</TextField>
</ListItem>
<ListItem>
<TextField
style={{ width: '100%' }}
id="input"
size='small'
variant="outlined"
select
label="Type"
value={handleNoiseAnalysisControlLine.input}
onChange={handleNoiseAnalysisControlLine}
SelectProps={{
native: true
}}
>
<option key="linear" value="lin">
Linear
</option>
<option key="decade" value="dec">
Decade
</option>
<option key="octave" value="oct">
Octave
</option>
</TextField>
</ListItem>
<ListItem>
<TextField id="pointsBydecade" label="Points/scale" size='small' variant="outlined"
value={NoiseAnalysisControlLine.pointsBydecade}
error={!NoiseAnalysisControlLine.pointsBydecade}
onChange={handleNoiseAnalysisControlLine}
/>
</ListItem>
<ListItem>
<TextField id="start" label="Start Frequency" size='small' variant="outlined"
value={NoiseAnalysisControlLine.start}
error={!NoiseAnalysisControlLine.start}
onChange={handleNoiseAnalysisControlLine}
/>
<span style={{ marginLeft: '10px' }}>Hz</span>
</ListItem>
<ListItem>
<TextField id="stop" label="Stop Frequency" size='small' variant="outlined"
value={NoiseAnalysisControlLine.stop}
error={!NoiseAnalysisControlLine.stop}
onChange={handleNoiseAnalysisControlLine}
/>
<span style={{ marginLeft: '10px' }}>Hz</span>
</ListItem>
<ListItem>
<input
type="checkbox"
name="Between Nodes"
value={NoiseAnalysisControlLine.outputSpectrum}
checked={NoiseAnalysisControlLine.outputSpectrum}
onChange={handleNoiseOutputMode}
id="outputSpectrum"
/>
<span style={{ marginLeft: '10px' }}>Show Noise Spectrum</span>
</ListItem>
<ListItem>
<Button aria-describedby={id} variant="outlined" color="primary" size="small" onClick={handleAddExpressionClick}>
Add Expression
</Button>
<Tooltip title={'Add expression seperated by spaces.\n Include #branch at end of expression to indicate current e.g v1#branch. To add multiple expression seperate them by spaces eg. v1 v2 v3#branch'}>
<IconButton aria-label="info">
<InfoOutlinedIcon style={{ fontSize: 'large' }} />
</IconButton>
</Tooltip>
<Popover
id={id}
open={open}
anchorEl={anchorEl}
onClose={handleAddExpressionClose}
anchorOrigin={{
vertical: 'center',
horizontal: 'left'
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left'
}}
>
<TextField id="controlBlockParam" placeHolder="enter expression" size='large' variant="outlined"
value={controlBlockParam}
onChange={handleControlBlockParam}
/>
</Popover>
</ListItem>
<ListItem>
<Button id="noiseAnalysisSimulate" size='small' variant="contained" color="primary" onClick={(e) => { startSimulate('noiseAnalysis') }}>
Simulate
</Button>
</ListItem>
</List>
</form>
</ExpansionPanelDetails>
</ExpansionPanel>
</ListItem>
<ListItem style={isSimRes ? {} : { display: 'none' }} onClick={handlesimulateOpen} >
<Button size='small' variant="contained" color="primary" style={{ margin: '10px auto' }} onClick={handlesimulateOpen}>
Simulation Result
</Button>
</ListItem>
</List>
</div>
</>
)
}
Example #13
Source File: SelectRole.js From AdaptivApps-fe with MIT License | 4 votes |
export default function SimplePopover({ activity, activityData }) {
const { user } = useAuth0();
const classes = useStyles();
const [anchorEl, setAnchorEl] = useState(null);
const [registerAsAthlete] = useMutation(REGISTER_AS_ATHLETE);
const [registerAsCoach] = useMutation(REGISTER_AS_COACH);
const [registerAsVolunteer] = useMutation(REGISTER_AS_VOLUNTEER);
const [registerAsSpectator] = useMutation(REGISTER_AS_SPECTATOR);
const handleClick = event => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
const participant = activity.participants.map(participant => {
return participant?.id;
});
const participantIdValue = JSON.stringify(participant).replace(
/[\[\]"]+/g,
""
);
const athleteRegister = async () => {
console.log("participantIdValue", participantIdValue);
console.log("participant", participant);
await registerAsAthlete({
variables: {
participantId: participantIdValue,
activityId: activity.id,
email: user.email,
},
});
alert("Successfully registered to compete in this event!");
handleClose();
};
const coachRegister = async () => {
console.log("participantIdValue", participantIdValue);
console.log("participant", participant);
await registerAsCoach({
variables: {
participantId: participantIdValue,
activityId: activity.id,
email: user.email,
},
});
alert("Successfully registered as a Coach!");
handleClose();
};
const volunteerRegister = async () => {
console.log("participantIdValue", participantIdValue);
console.log("participant", participant);
await registerAsVolunteer({
variables: {
participantId: participantIdValue,
activityId: activity.id,
email: user.email,
},
});
alert("Successfully registered as a Volunteer");
handleClose();
};
const spectatorRegister = async () => {
console.log("participantIdValue", participantIdValue);
console.log("participant", participant);
await registerAsSpectator({
variables: {
participantId: participantIdValue,
activityId: activity.id,
email: user.email,
},
});
alert("Successfully registered as a Spectator");
handleClose();
};
const open = Boolean(anchorEl);
const id = open ? "simple-popover" : undefined;
return (
<IconContext.Provider
onBlur={handleClick}
value={
anchorEl
? {
style: {
background: "white",
color: "#FFC629",
fontSize: "3rem",
},
}
: {
style: {
background: "white",
color: "#2962FF",
fontSize: "3rem",
},
}
}
>
{activityData && activityData?.event?.type === "Webinar" ? (
<LightTooltip title="Register for Activity" placement="right">
<Button
className={classes.btn}
aria-describedby={id}
variant="contained"
onClick={spectatorRegister}
>
<IoIosAddCircle />
</Button>
</LightTooltip>
) : (
<>
<LightTooltip title="Register for Activity" placement="right">
<Button
className={classes.btn}
aria-describedby={id}
variant="contained"
onClick={handleClick}
>
<IoIosAddCircle />
</Button>
</LightTooltip>
<Popover
className={classes.popover}
id={id}
open={open}
anchorEl={anchorEl}
onClose={handleClose}
anchorOrigin={{
vertical: "center",
horizontal: "right",
}}
transformOrigin={{
vertical: "center",
horizontal: "left",
}}
classes={{ paper: classes.dialogPaper }}
>
<Box className={classes.box}>
<Button className={classes.role} onClick={athleteRegister}>
I'm Competing
</Button>
<Button className={classes.role} onClick={coachRegister}>
I'm Coaching
</Button>
<Button className={classes.role} onClick={volunteerRegister}>
I'm Volunteering
</Button>
<Button className={classes.role} onClick={spectatorRegister}>
I'm Spectating
</Button>
</Box>
</Popover>
</>
)}
</IconContext.Provider>
);
}
Example #14
Source File: SchematicsList.js From eSim-Cloud with GNU General Public License v3.0 | 4 votes |
export default function SchematicsList ({ ltiDetails = null }) {
const classes = useStyles()
const auth = useSelector(state => state.authReducer)
const schematics = useSelector(state => state.dashboardReducer.schematics)
const [saves, setSaves] = React.useState(schematics)
const dispatch = useDispatch()
const [anchorEl, setAnchorEl] = React.useState(null)
const open = Boolean(anchorEl)
const [value, setValue] = React.useState(0)
const [sort, setSort] = React.useState('')
const [order, setOrder] = React.useState('ascending')
// For Fetching Saved Schematics
useEffect(() => {
dispatch(fetchSchematics())
}, [dispatch])
useEffect(() => {
setSaves(schematics)
}, [schematics])
const onSearch = (e) => {
setSaves(schematics.filter((o) =>
// eslint-disable-next-line
Object.keys(o).some((k) => {
if ((k === 'name' || k === 'description' || k === 'owner' || k === 'save_time' || k === 'create_time') && String(o[k]).toLowerCase().includes(e.target.value.toLowerCase())) {
return String(o[k]).toLowerCase().includes(e.target.value.toLowerCase())
}
}
)
))
}
const handleFilterOpen = (e) => {
if (anchorEl) {
setAnchorEl(null)
} else {
setAnchorEl(e.currentTarget)
}
}
const sortSaves = (sorting, order) => {
if (order === 'ascending') {
if (sorting === 'name') {
setSaves(saves.sort((a, b) => (a.name > b.name) ? 1 : -1))
} else if (sorting === 'created_at') {
setSaves(saves.sort((a, b) => (a.create_time > b.create_time) ? 1 : -1))
} else if (sorting === 'updated_at') {
setSaves(saves.sort((a, b) => (a.save_time < b.save_time) ? 1 : -1))
}
} else {
if (sorting === 'name') {
setSaves(saves.sort((a, b) => (a.name < b.name) ? 1 : -1))
} else if (sorting === 'created_at') {
setSaves(saves.sort((a, b) => (a.create_time < b.create_time) ? 1 : -1))
} else if (sorting === 'updated_at') {
setSaves(saves.sort((a, b) => (a.save_time > b.save_time) ? 1 : -1))
}
}
}
const handleSort = (e) => {
sortSaves(e.target.value, order)
setSort(e.target.value)
}
const handleOrder = (e) => {
setOrder(e.target.value)
if (sort !== '') {
sortSaves(sort, e.target.value)
}
}
const handleChange = (event, newValue) => {
setValue(newValue)
}
return (
<>
<Grid
container
direction="row"
justify="flex-start"
alignItems="flex-start"
alignContent="center"
spacing={3}
>
{/* User Dashboard My Schematic Header */}
<Grid item xs={12}>
<MainCard />
</Grid>
<Grid item xs={12}>
{schematics && <IconButton onClick={handleFilterOpen} style={{ float: 'right' }} ><FilterListIcon /></IconButton>}
{schematics && <Input style={{ float: 'right' }} onChange={(e) => onSearch(e)} placeholder='Search' />}
<Popover
open={open}
onClose={handleFilterOpen}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center'
}}
transformOrigin={{
vertical: 'top',
horizontal: 'center'
}}
anchorEl={anchorEl}
>
<FormControl style={{ width: ' 200px', padding: '2%' }}>
<InputLabel>Select Sort</InputLabel>
<Select className={classes.popover} value={sort} onChange={handleSort} >
<MenuItem key='name' value='name'>Name</MenuItem>
<MenuItem key='created_at' value='created_at'>Created</MenuItem>
<MenuItem key='updated_at' value='updated_at'>Updated</MenuItem>
</Select>
</FormControl>
<FormControl style={{ width: ' 200px', padding: '2%' }}>
<InputLabel>Select Order</InputLabel>
<Select className={classes.popover} value={order} onChange={handleOrder} >
<MenuItem key='ascending' value='ascending'>Ascending</MenuItem>
<MenuItem key='descending' value='descending'>Descending</MenuItem>
</Select>
</FormControl>
</Popover>
</Grid>
<AppBar position='static'>
<Tabs value={value} onChange={handleChange}>
<Tab label='Schematics' />
<Tab label='Projects' />
<Tab label='LTI Apps' />
</Tabs>
</AppBar>
<TabPanel style={{ width: '100%' }} value={value} index={0}>
{saves.filter(x => { return (x.project_id == null && x.lti_id == null) }).length !== 0
? <>
{saves.filter(x => { return (x.project_id == null && x.lti_id == null) }).map(
(sch) => {
return (
<Grid item xs={12} sm={6} lg={3} key={sch.save_id}>
<SchematicCard sch={sch} />
</Grid>
)
}
)}
</>
: <Grid item xs={12}>
<Card style={{ padding: '7px 15px' }} className={classes.mainHead}>
<Typography variant="subtitle1" gutterBottom>
Hey {auth.user.username} , You dont have any saved schematics...
</Typography>
</Card>
</Grid>
}
</TabPanel>
<TabPanel style={{ width: '100%' }} value={value} index={1}>
{saves.filter(x => { return x.project_id }).length !== 0
? <>
{saves.filter(x => { return x.project_id }).map(
(sch) => {
return (
<Grid item xs={12} sm={6} lg={3} key={sch.save_id}>
<SchematicCard sch={sch} />
</Grid>
)
}
)}
</>
: <Grid item xs={12}>
<Card style={{ padding: '7px 15px' }} className={classes.mainHead}>
<Typography variant="subtitle1" gutterBottom>
Hey {auth.user.username} , You dont have any saved projects...
</Typography>
</Card>
</Grid>
}
</TabPanel>
<TabPanel style={{ width: '100%' }} value={value} index={2}>
{saves.filter(x => { return x.lti_id }).length !== 0
? <>
{saves.filter(x => { return x.lti_id }).map(
(sch) => {
return (
<Grid item xs={12} sm={6} lg={3} key={sch.save_id}>
<SchematicCard sch={sch} />
</Grid>
)
}
)}
</>
: <Grid item xs={12}>
<Card style={{ padding: '7px 15px' }} className={classes.mainHead}>
<Typography variant="subtitle1" gutterBottom>
Hey {auth.user.username} , You dont have any saved projects...
</Typography>
</Card>
</Grid>
}
</TabPanel>
{/* List all schematics saved by user */}
</Grid>
</>
)
}
Example #15
Source File: DashboardOtherProjects.js From eSim-Cloud with GNU General Public License v3.0 | 4 votes |
function DashboardOtherProjects () {
const projects = useSelector(state => state.dashboardReducer.otherProjects)
const classes = useStyles()
const auth = useSelector(state => state.authReducer)
const dispatch = useDispatch()
const [value, setValue] = React.useState(0)
const [sort, setSort] = React.useState('')
const [order, setOrder] = React.useState('ascending')
const [filteredProjects, setFilteredProjects] = React.useState(projects)
const [anchorEl, setAnchorEl] = React.useState(null)
const open = Boolean(anchorEl)
useEffect(() => {
setFilteredProjects(projects)
}, [projects])
useEffect(() => {
dispatch(fetchOtherProjects())
}, [dispatch])
const handleFilterOpen = (e) => {
if (anchorEl) {
setAnchorEl(null)
} else {
setAnchorEl(e.currentTarget)
}
}
const handleChange = (event, newValue) => {
setValue(newValue)
}
const sortSaves = (sorting, order) => {
if (order === 'ascending') {
if (sorting === 'name') {
setFilteredProjects(filteredProjects.sort((a, b) => a.title > b.title))
} else if (sorting === 'author') {
setFilteredProjects(filteredProjects.sort((a, b) => a.author > b.author))
} else if (sorting === 'status') {
setFilteredProjects(filteredProjects.sort((a, b) => a.status_name > b.status_name))
}
} else {
if (sorting === 'name') {
setFilteredProjects(filteredProjects.sort((a, b) => a.title < b.title))
} else if (sorting === 'author') {
setFilteredProjects(filteredProjects.sort((a, b) => a.author < b.author))
} else if (sorting === 'status') {
setFilteredProjects(filteredProjects.sort((a, b) => a.status_name < b.status_name))
}
}
}
const handleSort = (e) => {
sortSaves(e.target.value, order)
setSort(e.target.value)
}
const handleOrder = (e) => {
setOrder(e.target.value)
if (sort !== '') {
sortSaves(sort, e.target.value)
}
}
const onSearch = (e) => {
setFilteredProjects(projects.filter((o) =>
// eslint-disable-next-line
Object.keys(o).some((k) => {
if ((k === 'title' || k === 'description' || k === 'author' || k === 'status_name') && String(o[k]).toLowerCase().includes(e.target.value.toLowerCase())) {
return String(o[k]).toLowerCase().includes(e.target.value.toLowerCase())
}
}
)
))
}
return (
<>
<Grid
container
direction="row"
justify="flex-start"
alignItems="space-between"
alignContent="center"
spacing={3}>
<Grid item xs={12}>
<Card className={classes.mainHead}>
<CardContent>
<Typography className={classes.title} gutterBottom>
All the projects which are pending for a review are Listed Below
</Typography>
<Typography variant="h5" component="h2">
Review Projects
</Typography>
</CardContent>
</Card>
</Grid>
<Grid item xs={12}>
{filteredProjects && <IconButton onClick={handleFilterOpen} style={{ float: 'right' }} ><FilterListIcon /></IconButton>}
{filteredProjects && <Input style={{ float: 'right' }} onChange={(e) => onSearch(e)} placeholder='Search' />}
<Popover
open={open}
onClose={handleFilterOpen}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center'
}}
transformOrigin={{
vertical: 'top',
horizontal: 'center'
}}
anchorEl={anchorEl}
>
<FormControl style={{ width: ' 200px', padding: '2%' }}>
<InputLabel>Select Sort</InputLabel>
<Select className={classes.popover} value={sort} onChange={handleSort} >
<MenuItem key='name' value='name'>Name</MenuItem>
<MenuItem key='author' value='author'>Author</MenuItem>
<MenuItem key='status' value='status'>Status</MenuItem>
</Select>
</FormControl>
<FormControl style={{ width: ' 200px', padding: '2%' }}>
<InputLabel>Select Order</InputLabel>
<Select className={classes.popover} value={order} onChange={handleOrder} >
<MenuItem key='ascending' value='ascending'>Ascending</MenuItem>
<MenuItem key='descending' value='descending'>Descending</MenuItem>
</Select>
</FormControl>
</Popover>
</Grid>
<AppBar position='static'>
<Tabs value={value} onChange={handleChange}>
<Tab label='Projects to be reviewed' />
<Tab label='Reported Projects' />
</Tabs>
</AppBar>
<TabPanel style={{ width: '100%' }} value={value} index={0}>
{filteredProjects.filter(x => { return !x.is_reported }).length !== 0
? <>
{filteredProjects.filter(x => { return !x.is_reported }).map(
(project) => {
return (
<Grid item xs={12} sm={6} lg={3} key={project.project_id}>
<ProjectCard pub={project} is_review={true} />
</Grid>
)
}
)}
</>
: <Grid item xs={12}>
<Card style={{ padding: '7px 15px' }} className={classes.mainHead}>
<Typography variant="subtitle1" gutterBottom>
Hey {auth.user.username} , You don't have any projects to review...
</Typography>
</Card>
</Grid>
}
</TabPanel>
<TabPanel style={{ width: '100%' }} value={value} index={1}>
{filteredProjects.filter(x => { return x.is_reported }).length !== 0
? <>
{filteredProjects.filter(x => { return x.is_reported }).map(
(project) => {
return (
<Grid item xs={12} sm={6} lg={3} key={project.project_id}>
<ProjectCard pub={project} is_review={true} />
</Grid>
)
}
)}
</>
: <Grid item xs={12}>
<Card style={{ padding: '7px 15px' }} className={classes.mainHead}>
<Typography variant="subtitle1" gutterBottom>
Hey {auth.user.username} , You dont have any reported projects to review...
</Typography>
</Card>
</Grid>
}
</TabPanel>
</Grid>
</>
)
}
Example #16
Source File: Volume.js From budgie-stream with MIT License | 4 votes |
VolumeSlider = () => {
const classes = useStyles();
const { playback } = useContext(ClientContext);
const [state, setState] = playback;
const devices = state.devices.filter((device) => device.selected === true);
// Only control the volume if any devices are selected
const disabled = !state.playing;
const [masterValue, setMasterValue] = useState(30);
const prevMasterValue = usePreviousValue(masterValue);
const [anchorEl, setAnchorEl] = useState(null);
const ref = createRef();
const open = Boolean(anchorEl);
const handleClose = () => {
setAnchorEl(null);
};
const handleMasterVol = (newMasterValue) => {
// Toggle multiple devices control
if (devices.length > 1) {
setAnchorEl(ref.current);
}
setMasterValue(newMasterValue);
if (devices.length === 1) {
handleVolChange(devices[0].name, newMasterValue, null);
} else {
const masterChange = newMasterValue - prevMasterValue;
handleVolChange(null, null, masterChange);
}
};
const handleVolChange = (deviceName, newValue, master = false) => {
let newState = [...state.devices];
if (!master) {
const deviceIndex = state.devices.findIndex(
(device) => device.name === deviceName
);
newState[deviceIndex] = { ...newState[deviceIndex], vol: newValue };
const avgVol =
devices.reduce(
(totalCalories, device) => totalCalories + device.vol,
0
) / devices.length;
setMasterValue(avgVol);
} else {
newState.map((x) => (x.selected ? (x.vol = x.vol + master) : x));
}
setState((prevState) => ({
...prevState,
devices: newState,
}));
setVolume(devices);
};
return (
<>
<div className={classes.root}>
<Grid container className={classes.container} spacing={1}>
<Grid item id="volume-icon">
<VolumeUp />
</Grid>
<Grid item ref={ref} xs>
<Slider
className={classes.slider}
value={masterValue}
disabled={disabled}
onChange={(event, value) => handleMasterVol(value)}
aria-labelledby="volume-slider"
/>
</Grid>
</Grid>
</div>
<Popover
className={classes.popover}
open={open}
anchorEl={anchorEl}
onClose={handleClose}
anchorOrigin={{
vertical: "top",
horizontal: "center",
}}
transformOrigin={{
vertical: "bottom",
horizontal: "center",
}}
>
<DevicesVolume devices={devices} handleChange={handleVolChange} />
</Popover>
</>
);
}
Example #17
Source File: EditEvent.jsx From archeage-tools with The Unlicense | 4 votes |
render() {
const { id, open, onClose, mobile, eventTypes } = this.props;
const { formData: { name, icon, eventType, description, link, times, disabled }, avatarSelect, editTime, timeData, error, loading } = this.state;
return (
<Dialog
open={open}
onClose={onClose}
fullScreen={mobile}
>
<AppBar position="static">
<Toolbar variant="dense">
<Typography className="title-text">{id ? 'Edit' : 'New'} Event</Typography>
<IconButton color="inherit" aria-label="Close" onClick={onClose}>
<CloseIcon />
</IconButton>
</Toolbar>
</AppBar>
<DialogContent>
<form autoComplete="off" onSubmit={this.handleSubmit} ref={this.form}>
<div className="event-form">
<div className="avatar-opt">
<Avatar src={icon ? `/images/event/${icon}.png` : null} onClick={this.toggleAvatar} />
<Typography>{icon || 'Select an icon.'}</Typography>
</div>
<TextField
required
id="event-name"
label="Event Name"
value={name || ''}
onChange={(e) => this.handleChange('name', e.target.value)}
/>
<FormControl required>
<InputLabel id="event-type-select">Type</InputLabel>
<Select
labelId="event-type-select"
id="event-type"
value={eventType || ''}
onChange={(e) => this.handleChange('eventType', e.target.value)}
>
{Object.values(eventTypes).map(type => (
<MenuItem
value={type.id}
key={`etype-${type.id}`}
>
{type.name}
</MenuItem>
))}
</Select>
</FormControl>
<TextField
id="event-desc"
label="Description"
value={description || ''}
onChange={(e) => this.handleChange('description', e.target.value)}
multiline
/>
<TextField
id="event-link"
label="Link"
value={link || ''}
onChange={(e) => this.handleChange('link', e.target.value)}
/>
<div>
<FormControlLabel
control={
<Checkbox
checked={disabled || false}
onChange={(_, disabled) => this.handleChange('disabled', disabled)}
name="disabled"
/>}
label="Disabled"
/>
</div>
<div className="times">
<Typography>Times</Typography>
<div className="chips">
{(times || []).map((time, timeId) => (
<Chip
key={`time-${timeId}`}
icon={<Avatar>{time.region || 'GT'}</Avatar>}
label={`${time.time} ${time.days.length > 0 && time.days.length < 7
? time.days.map(day => DAY_ABBR[day]).join('') : ''}`}
onClick={this.editTime(timeId)}
onDelete={this.deleteTime(timeId)}
variant="outlined"
color={editTime === timeId ? 'primary' : 'secondary'}
/>
))}
{editTime === false &&
<IconButton onClick={this.editTime()}>
<AddIcon />
</IconButton>}
</div>
</div>
</div>
</form>
{editTime !== false &&
<Paper elevation={3}>
<form autoComplete="off" onSubmit={this.saveTime} className="time-form">
<Typography>{editTime === true ? 'Add Time' : 'Edit Time'}</Typography>
<FormControl
style={{ width: 75 }}
disabled={Boolean(timeData.gameTime)}
>
<InputLabel id="region-label" shrink>Region</InputLabel>
<Select
labelId="region-label"
id="region"
value={timeData.region || ''}
onChange={(e) => this.handleChangeTime('region', e.target.value)}
>
{[null, ...Object.values(REGIONS)].map(region => (
<MenuItem
value={region}
key={`region-${region}`}
>
{region || 'None'}
</MenuItem>
))}
</Select>
</FormControl>
<TextField
id="start-time"
label="Start Time"
margin="dense"
type="time"
required
value={timeData.time || ''}
onChange={(e) => this.handleChangeTime('time', this.handleTime(e))}
InputLabelProps={{
shrink: true,
}}
inputProps={{
step: 900,
}}
/>
<TextField
id="duration"
label="Duration"
margin="dense"
type="time"
value={timeData.duration || ''}
onChange={(e) => this.handleChangeTime('duration', this.handleTime(e))}
InputLabelProps={{
shrink: true,
}}
inputProps={{
step: 900,
}}
/>
<TextField
id="in-game-time"
label="Game Time?"
margin="dense"
type="time"
value={timeData.gameTime || ''}
onChange={(e) => {
const gameTime = this.handleTime(e);
this.handleChangeTime('gameTime', gameTime, () => {
if (gameTime) {
this.handleChangeTime('region', null);
}
});
}}
InputLabelProps={{
shrink: true,
}}
inputProps={{
step: 900,
}}
/>
<TextField
id="time-name"
label="Name"
margin="dense"
value={timeData.name || ''}
onChange={(e) => this.handleChangeTime('name', e.target.value)}
InputLabelProps={{
shrink: true,
}}
placeholder={`${name || 'Event Name'}: ...`}
/>
<TextField
className="start-message"
id="time-message"
label="Start Message"
margin="dense"
value={timeData.startMessage || ''}
onChange={(e) => this.handleChangeTime('startMessage', e.target.value)}
InputLabelProps={{
shrink: true,
}}
placeholder="Alternate message for when this event starts."
/>
<TextField
id="reminder-time"
label="Reminder Time"
margin="dense"
type="time"
value={timeData.reminderTime || ''}
onChange={(e) => this.handleChangeTime('reminderTime', this.handleTime(e))}
InputLabelProps={{
shrink: true,
}}
inputProps={{
step: 900,
}}
/>
<TextField
className="start-message"
id="time-reminder-message"
label="Reminder Message"
margin="dense"
value={timeData.reminderMessage || ''}
onChange={(e) => this.handleChangeTime('reminderMessage', e.target.value)}
InputLabelProps={{
shrink: true,
}}
placeholder="Alternate message for when this event is starting soon."
/>
<FormControl className="day-select">
<InputLabel id="time-days-label">Days</InputLabel>
<Select
labelId="time-days-label"
id="time-days"
multiple
value={timeData.days || []}
onChange={(e) => this.handleChangeTime('days', e.target.value)}
input={<Input id="select-multiple-chip" />}
renderValue={(selected) => (
<div className="day-chips">
{selected.map((value) => (
<Chip key={value} label={DAY[value]} className="day-chip" />
))}
</div>
)}
>
{Object.entries(DAY).map(([key, name]) => (
<MenuItem key={key} value={key} className="day-item">
{name}
</MenuItem>
))}
</Select>
</FormControl>
<IconButton type="submit"><CheckIcon /></IconButton>
<IconButton onClick={this.editTime(false)}><CloseIcon /></IconButton>
</form>
</Paper>}
<Popover
anchorOrigin={{
vertical: 'top',
horizontal: 'left',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left',
}}
anchorEl={avatarSelect}
open={Boolean(avatarSelect)}
elevation={2}
onClose={() => this.toggleAvatar()}
>
<div className="avatar-select">
{Object.entries(EventIcon).sort(sortBy(0)).map(([key, url]) => (
<Tooltip title={getIconName(url)} key={key}>
<Avatar
src={url}
onClick={() => {
this.handleChange('icon', getIconName(url));
this.toggleAvatar();
}}
/>
</Tooltip>
))}
</div>
</Popover>
{error &&
<Box color="error.main">
<Typography>{error}</Typography>
</Box>}
<DialogActions>
<Button onClick={onClose}>
Cancel
</Button>
<Button
color="primary"
onClick={() => this.form.current.dispatchEvent(new Event('submit'))}
disabled={loading}
>
Save
</Button>
</DialogActions>
</DialogContent>
</Dialog>
);
}
Example #18
Source File: EditQuiz.js From Quizzie with MIT License | 4 votes |
function EditQuiz(props) {
const quizId = props.match.params.id;
const [loading, setLoading] = useState(true);
const [redirect, setRedirect] = useState(false);
const [quizDetails, setQuizDetails] = useState({});
const [quizQuestions, setQuizQuestions] = useState([]);
const [fileError, setFileError] = useState(false);
const [serverError, setServerError] = useState(false);
const [popoverAnchor, setPopoverAnchor] = useState(null);
const popoverOpen = Boolean(popoverAnchor);
const [questionModal, setQuestionModal] = useState(false);
const [newQuestion, setNewQuestion] = useState("");
const [newQuestionError, setNewQuestionError] = useState(false);
const [option1, setOption1] = useState("");
const [option1Error, setOption1Error] = useState(false);
const [option2, setOption2] = useState("");
const [option2Error, setOption2Error] = useState(false);
const [option3, setOption3] = useState("");
const [option3Error, setOption3Error] = useState(false);
const [option4, setOption4] = useState("");
const [option4Error, setOption4Error] = useState(false);
const [correctOption, setCorrectOption] = useState(-1);
const [correctOptionError, setCorrectOptionError] = useState(false);
const [update, setUpdate] = useState(false);
const [updateId, setUpdateId] = useState(null);
const [deleteModal, setDeleteModal] = useState(false);
const [deleteQuestionModal, setDeleteQuestionModal] = useState(false);
const [quizRestartModal, setQuizRestartModal] = useState(false);
const [closeQuizModal, setCloseQuizModal] = useState(false);
const [responses, setResponses] = useState([]);
const [searchData, setSearchData] = useState(responses);
const [searchText, setSearchText] = useState("");
const [sortBy, setSortBy] = useState(-1);
const { executeRecaptcha } = useGoogleReCaptcha();
const onCloseHandle = () => {
setQuestionModal(false);
if (update) {
setUpdate(false);
setUpdateId(null);
clearModal();
}
};
const handlePopover = (event) => {
setPopoverAnchor(event.currentTarget);
};
const handlePopoverClose = () => {
setPopoverAnchor(null);
};
const onQuestionChange = (event) => {
setNewQuestion(event.target.value);
};
const handleOptionChange1 = (event) => {
setOption1(event.target.value);
};
const handleOptionChange2 = (event) => {
setOption2(event.target.value);
};
const handleOptionChange3 = (event) => {
setOption3(event.target.value);
};
const handleOptionChange4 = (event) => {
setOption4(event.target.value);
};
const handleCorrectOption = (event) => {
setCorrectOption(event.target.value);
};
const clearModal = () => {
setNewQuestion("");
setNewQuestionError(false);
setOption1("");
setOption1Error(false);
setOption2("");
setOption2Error(false);
setOption3("");
setOption3Error(false);
setOption4("");
setOption4Error(false);
setCorrectOption(-1);
setCorrectOptionError(false);
};
const handleFileDrop = (files) => {
const reader = new FileReader();
let questions = [];
reader.onabort = () => {
setFileError(true);
return;
};
reader.onerror = () => {
setFileError(true);
return;
};
reader.onload = () => {
csv.parse(reader.result, (err, data) => {
if (data === undefined) {
setFileError(true);
return;
}
data.map((question) => {
if (question[0].trim() === "") {
return null;
}
let obj = {
quizId: quizId,
description: question[0],
options: [
{ text: question[1] },
{ text: question[2] },
{ text: question[3] },
{ text: question[4] },
],
correctAnswer: question[5],
};
questions.push(obj);
});
submitCSV(questions);
});
};
reader.readAsBinaryString(files[0]);
};
const submitCSV = async (questions) => {
setLoading(true);
let token = localStorage.getItem("authToken");
let url = "https://quizzie-api.herokuapp.com/question/csv";
let captcha = await executeRecaptcha("submit_csv");
let data = {
questions: questions,
captcha: captcha,
};
try {
await axios
.post(url, data, {
headers: {
"auth-token": token,
},
})
.then((res) => {
console.log(res);
setLoading(false);
clearModal();
onCloseHandle();
getQuizDetails();
});
} catch (error) {
setServerError(true);
console.log(error);
}
};
const handleSearchChange = (event) => {
setSearchText(event.target.value);
let newRes = responses.filter(
(response) =>
response.userId.name
.toLowerCase()
.search(event.target.value.trim().toLowerCase()) !== -1 ||
String(response.marks) ===
event.target.value.trim().toLowerCase()
);
let sorted = sortByFunc(sortBy, newRes);
setSearchData(sorted);
};
const handleSortChange = (event) => {
setSortBy(event.target.value);
let newRes = sortByFunc(event.target.value, searchData);
setSearchData(newRes);
};
const sortByFunc = (by, array) => {
if (by === "score") {
return array.sort(function (a, b) {
return b.marks - a.marks;
});
} else if (by === "name") {
return array.sort(function (a, b) {
return a.userId.name - b.userId.name;
});
} else if (by === "recent") {
return array.sort(function (a, b) {
return b.timeEnded - a.timeEnded;
});
} else {
return array;
}
};
const handleRestart = async () => {
let token = localStorage.getItem("authToken");
let url = `https://quizzie-api.herokuapp.com/quiz/restart`;
let captcha = await executeRecaptcha("restart_quiz");
let data = {
quizId: quizId,
captcha: captcha,
};
try {
await axios
.patch(url, data, {
headers: {
"auth-token": token,
},
})
.then((res) => {
setQuizRestartModal(false);
getQuizDetails();
});
} catch (error) {
console.log(error);
}
};
const handleQuizClose = async () => {
let token = localStorage.getItem("authToken");
let url = `https://quizzie-api.herokuapp.com/quiz/close`;
let captcha = await executeRecaptcha("quiz_close");
let data = {
quizId: quizId,
captcha: captcha,
};
try {
await axios
.patch(url, data, {
headers: {
"auth-token": token,
},
})
.then((res) => {
setCloseQuizModal(false);
getQuizDetails();
});
} catch (error) {
console.log(error);
}
};
const handleQuestionEditBtn = (question) => {
setUpdate(true);
setUpdateId(question._id);
setNewQuestion(question.description);
setOption1(question.options[0].text);
setOption2(question.options[1].text);
setOption3(question.options[2].text);
setOption4(question.options[3].text);
setCorrectOption(question.correctAnswer);
setQuestionModal(true);
};
const handleQuestionDeleteBtn = (question) => {
setUpdateId(question._id);
setDeleteQuestionModal(true);
};
const handleQuestionModalClose = () => {
setUpdateId(null);
setDeleteQuestionModal(false);
};
const handleDeleteBtn = () => {
setDeleteModal(true);
};
const handleDeleteQuestion = async () => {
let token = localStorage.getItem("authToken");
let url = `https://quizzie-api.herokuapp.com/question/${updateId}`;
// let captcha = executeRecaptcha("delete_quiz");
try {
await axios
.delete(url, {
headers: {
"auth-token": token,
},
})
.then((res) => {
setUpdateId(null);
setDeleteQuestionModal(false);
getQuizDetails();
});
} catch (error) {
console.log(error);
}
};
const handleDelete = async () => {
let token = localStorage.getItem("authToken");
let url = `https://quizzie-api.herokuapp.com/quiz/delete`;
let data = {
quizId: quizId,
};
try {
await axios
.delete(url, {
headers: {
"auth-token": token,
},
data: data,
})
.then((res) => {
setRedirect(true);
});
} catch (error) {
console.log(error);
}
};
const handleQuestionUpdate = async () => {
if (!validate()) return;
let token = localStorage.getItem("authToken");
let url = `https://quizzie-api.herokuapp.com/question/update/${updateId}`;
let captcha = await executeRecaptcha("question_update");
let updateOps = [
{ propName: "description", value: newQuestion },
{
propName: "options",
value: [
{
text: option1,
},
{
text: option2,
},
{
text: option3,
},
{
text: option4,
},
],
},
{ propName: "correctAnswer", value: correctOption },
];
let data = {
updateOps: updateOps,
captcha: captcha,
};
try {
await axios
.patch(url, data, {
headers: {
"auth-token": token,
},
})
.then((res) => {
onCloseHandle();
getQuizDetails();
});
} catch (error) {
console.log(error);
}
};
const validate = () => {
if (newQuestion.trim().length === 0) {
setNewQuestionError(true);
return false;
}
if (option1.trim().length === 0) {
setOption1Error(true);
return false;
}
if (option2.trim().length === 0) {
setOption2Error(true);
return false;
}
if (option3.trim().length === 0) {
setOption3Error(true);
return false;
}
if (option4.trim().length === 0) {
setOption4Error(true);
return false;
}
if (correctOption === -1) {
setCorrectOptionError(true);
return false;
}
return true;
};
const handleQuestionSubmit = async () => {
//TODO: Handle Validation
if (!validate()) return;
let token = localStorage.getItem("authToken");
let url = `https://quizzie-api.herokuapp.com/question/add`;
let captcha = await executeRecaptcha("submit_question");
let options = [
{ text: option1 },
{ text: option2 },
{ text: option3 },
{ text: option4 },
];
let data = {
quizId: quizId,
description: newQuestion,
options: options,
correctAnswer: correctOption,
captcha: captcha,
};
try {
await axios
.post(url, data, {
headers: {
"auth-token": token,
},
})
.then((res) => {
clearModal();
getQuizDetails();
setQuestionModal(false);
});
} catch (error) {
console.log(error);
}
};
const isOwnerOfQuiz = async () => {
let token = localStorage.getItem("authToken");
let url = `https://quizzie-api.herokuapp.com/quiz/checkAdmin/${quizId}`;
try {
await axios
.get(url, {
headers: {
"auth-token": token,
},
})
.then((res) => {
return true;
});
} catch (error) {
setRedirect(true);
return;
}
};
const getQuizDetails = async () => {
setLoading(true);
let token = localStorage.getItem("authToken");
let url = `https://quizzie-api.herokuapp.com/quiz/${quizId}`;
try {
await axios
.get(url, {
headers: {
"auth-token": token,
},
})
.then((res) => {
setQuizDetails(res.data.result);
});
} catch (error) {
console.log(error);
}
url = `https://quizzie-api.herokuapp.com/question/all/${quizId}`;
try {
await axios
.get(url, {
headers: {
"auth-token": token,
},
})
.then((res) => {
setQuizQuestions(res.data.result);
});
} catch (error) {
console.log(error);
}
url = `https://quizzie-api.herokuapp.com/admin/allStudentsQuizResult/${quizId}`;
try {
await axios
.get(url, {
headers: {
"auth-token": token,
},
})
.then((res) => {
setResponses(res.data.userResults);
setSearchData(res.data.userResults);
setLoading(false);
});
} catch (error) {
console.log(error);
}
};
useEffect(() => {
let token = localStorage.getItem("authToken");
if (token === null) {
setLoading(false);
setRedirect(true);
return;
}
isOwnerOfQuiz();
getQuizDetails();
}, []);
if (loading) {
return <Loading />;
} else if (redirect) {
return <Redirect to="/dashboard" />;
} else {
return (
<Container className="edit-quiz-page">
<Typography
variant="h3"
className="dash-head p-top edit-quiz-head"
>
Edit Quiz
</Typography>
<div className="edit-btn-bar">
<Button
className="edit-details-btn"
component={Link}
to={`/updateQuizDetails/${quizId}`}
>
<Create className="edit-icon" />
Edit Details
</Button>
<Button
className="edit-details-btn delete-btn"
onClick={handleDeleteBtn}
>
<Delete className="edit-icon" />
Delete Quiz
</Button>
{quizDetails.quizStatus === 1 ? (
<Button
className="edit-details-btn"
style={{ marginLeft: "3%" }}
onClick={() => setCloseQuizModal(true)}
>
<Replay className="edit-quiz" />
Close Quiz
</Button>
) : quizDetails.quizStatus === 2 ? (
<Button
className="edit-details-btn"
style={{ marginLeft: "3%" }}
onClick={() => setQuizRestartModal(true)}
>
<Replay className="edit-quiz" />
Restart Quiz
</Button>
) : null}
</div>
<div className="quiz-details-sec">
<Typography variant="h6" className="quiz-detail-param">
Name:{" "}
<span className="quiz-detail-text">
{quizDetails.quizName}
</span>
</Typography>
<Typography variant="h6" className="quiz-detail-param">
Date:{" "}
<span className="quiz-detail-text">
{new Date(
Number(quizDetails.scheduledFor)
).toDateString()}
</span>
</Typography>
<Typography variant="h6" className="quiz-detail-param">
Time:{" "}
<span className="quiz-detail-text">
{new Date(
Number(quizDetails.scheduledFor)
).toLocaleTimeString()}
</span>
</Typography>
<Typography variant="h6" className="quiz-detail-param">
Duration:{" "}
<span className="quiz-detail-text">
{quizDetails.quizDuration} minutes
</span>
</Typography>
<Typography variant="h6" className="quiz-detail-param">
Type:{" "}
<span className="quiz-detail-text">
{quizDetails.quizType}
</span>
</Typography>
{quizDetails.quizType === "private" ? (
<Typography variant="h6" className="quiz-detail-param">
Quiz Code:{" "}
<span className="quiz-detail-text">
{quizDetails.quizCode}
</span>
</Typography>
) : null}
</div>
<div className="quiz-questions-sec">
<Typography variant="h4" className="quiz-questions-head">
Questions
</Typography>
<div className="quiz-questions-display">
<div className="add-question-bar">
<Button
className="add-question-btn"
onClick={() => setQuestionModal(true)}
>
Add a question
</Button>
</div>
{quizQuestions.length === 0 ? (
<p style={{ textAlign: "center" }}>
No questions added yet!
</p>
) : (
<div className="questions-list-display">
{quizQuestions.map((question) => (
<ExpansionPanel
elevation={3}
className="expansion"
key={question._id}
>
<ExpansionPanelSummary
className="question-summary"
expandIcon={<ExpandMore />}
aria-controls="question-content"
aria-label="Expand"
>
<FormControlLabel
style={{ marginRight: "0" }}
aria-label="Edit"
control={
<IconButton>
<Create />
</IconButton>
}
// label={question.description}
onClick={() =>
handleQuestionEditBtn(
question
)
}
/>
<FormControlLabel
aria-label="Edit"
control={
<IconButton>
<Delete />
</IconButton>
}
// label={question.description}
onClick={() =>
handleQuestionDeleteBtn(
question
)
}
/>
<Typography className="question-label">
{question.description}
</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<List
component="nav"
className="options-display"
>
{question.options.map(
(option) => (
<ListItem
button
key={option._id}
>
<ListItemIcon>
<Adjust
style={{
color:
question.correctAnswer ===
option.text
? "green"
: "black",
}}
/>
</ListItemIcon>
<ListItemText
style={{
color:
question.correctAnswer ===
option.text
? "green"
: "black",
}}
primary={
option.text
}
/>
</ListItem>
)
)}
</List>
</ExpansionPanelDetails>
</ExpansionPanel>
))}
</div>
)}
</div>
<Typography
variant="h4"
className="quiz-questions-head m-top"
>
Submissions
</Typography>
<div className="quiz-students-list">
<div className="add-question-bar">
<Button
className="add-question-btn stats-btn"
component={
responses.length !== 0 ? Link : Button
}
to={{
pathname: "/quizStats",
state: { responses: responses },
}}
>
<BarChart />
View Stats
</Button>
</div>
{responses.length === 0 ? (
<p
style={{
textAlign: "center",
margin: "0",
paddingTop: "3%",
paddingBottom: "3%",
}}
>
No responses yet!
</p>
) : (
<>
<div className="search-bar">
<TextField
placeholder="Search by name or score"
type="text"
onChange={handleSearchChange}
className="search-input"
value={searchText}
/>
<div style={{ marginLeft: "3%" }}>
<InputLabel id="sort-by">
Sort by
</InputLabel>
<Select
labelId="sort-by"
id="sort-select"
value={sortBy}
onChange={handleSortChange}
>
<MenuItem value={-1}>
<em>None</em>
</MenuItem>
<MenuItem value="recent">
Recent
</MenuItem>
<MenuItem value="score">
Score
</MenuItem>
<MenuItem value="name">
Name
</MenuItem>
</Select>
</div>
</div>
<List aria-label="responses list">
{searchData.map((response) => (
<ListItem
button
key={response._id}
component={Link}
to={{
pathname: `/studentResponse`,
state: { response: response },
}}
>
<ListItemText
primary={response.userId.name}
secondary={`Scored: ${response.marks}`}
/>
</ListItem>
))}
</List>
</>
)}
</div>
</div>
<Dialog
open={questionModal}
onClose={onCloseHandle}
aria-labelledby="add-question-modal"
PaperProps={{
style: {
backgroundColor: "white",
color: "#333",
minWidth: "50%",
},
}}
style={{ width: "100%" }}
>
<div className="add-ques-heading">
<Typography
variant="h6"
style={{ textAlign: "center", margin: "2% 5%" }}
>
New Question{" "}
</Typography>
{!update ? (
<IconButton onClick={handlePopover}>
<Info className="add-info-icon" />
</IconButton>
) : null}
<Popover
id="file-upload-popover"
open={popoverOpen}
anchorEl={popoverAnchor}
onClose={handlePopoverClose}
anchorOrigin={{
vertical: "bottom",
horizontal: "left",
}}
disableRestoreFocus
useLayerForClickAway={false}
PaperProps={{ style: { maxWidth: "400px" } }}
>
<p className="popover-text">
You can upload a <strong>.csv</strong> file with
questions. The format should be: the{" "}
<strong>
first column should contain the question
text.
</strong>{" "}
The next 4 columns must contain the{" "}
<strong>four options.</strong> And the sixth
column should contain{" "}
<strong>
the correct answer (it should match one of
the four options)
</strong>
. <br />
<br />
<strong>
NOTE: THE FILE SHOULD EXACTLY MATCH THE
GIVEN FORMAT.
</strong>{" "}
You will be able to see and edit all the
question though.
</p>
</Popover>
</div>
{!update ? (
<>
<div className="dropzone">
<Dropzone
onDrop={(acceptedFiles) =>
handleFileDrop(acceptedFiles)
}
>
{({ getRootProps, getInputProps }) => (
<section>
<div {...getRootProps()}>
<input {...getInputProps()} />
<AddCircle className="drop-icon" />
<p
style={{
color:
"rgb(110, 110, 110)",
}}
>
Drag 'n' drop or click to
select files
</p>
</div>
</section>
)}
</Dropzone>
</div>
<p className="manual-head">
<span>Or manually add the question</span>
</p>
</>
) : null}
<div className="new-question-form">
<TextInput
error={newQuestionError}
helperText={
newQuestionError ? "This cannot be empty" : null
}
className="new-ques-input"
variant="outlined"
label="Question Text"
value={newQuestion}
onChange={onQuestionChange}
/>
<hr style={{ width: "100%", marginBottom: "3%" }} />
<Grid container spacing={1}>
<Grid item xs={12} sm={6}>
<TextInput
error={option1Error}
helperText={
option1Error
? "This cannot be empty"
: null
}
className="new-ques-input"
variant="outlined"
label="Option 1"
value={option1}
onChange={handleOptionChange1}
/>
</Grid>
<Grid item xs={12} sm={6}>
<TextInput
error={option2Error}
helperText={
option2Error
? "This cannot be empty"
: null
}
className="new-ques-input"
variant="outlined"
label="Option 2"
value={option2}
onChange={handleOptionChange2}
/>
</Grid>
</Grid>
<Grid container spacing={1}>
<Grid item xs={12} sm={6}>
<TextInput
error={option3Error}
helperText={
option3Error
? "This cannot be empty"
: null
}
className="new-ques-input"
variant="outlined"
label="Option 3"
value={option3}
onChange={handleOptionChange3}
/>
</Grid>
<Grid item xs={12} sm={6}>
<TextInput
error={option4Error}
helperText={
option4Error
? "This cannot be empty"
: null
}
className="new-ques-input"
variant="outlined"
label="Option 4"
value={option4}
onChange={handleOptionChange4}
/>
</Grid>
</Grid>
<hr style={{ width: "100%", marginBottom: "3%" }} />
<InputLabel id="correct-option">
Correct Option
</InputLabel>
<Select
error={correctOptionError}
className="correct-answer-select"
style={{ width: "50%" }}
labelId="correct-option"
value={correctOption}
onChange={handleCorrectOption}
>
<MenuItem value={-1}>None</MenuItem>
{option1.trim().length !== 0 ? (
<MenuItem value={option1}>{option1}</MenuItem>
) : null}
{option2.trim().length !== 0 ? (
<MenuItem value={option2}>{option2}</MenuItem>
) : null}
{option3.trim().length !== 0 ? (
<MenuItem value={option3}>{option3}</MenuItem>
) : null}
{option4.trim().length !== 0 ? (
<MenuItem value={option4}>{option4}</MenuItem>
) : null}
</Select>
{!update ? (
<Button
className="add-question-submit"
onClick={handleQuestionSubmit}
>
Add Question
</Button>
) : (
<Button
className="add-question-submit"
onClick={handleQuestionUpdate}
>
Update Question
</Button>
)}
</div>
</Dialog>
<Dialog
open={deleteModal}
onClose={() => setDeleteModal(false)}
aria-labelledby="delete-quiz-modal"
PaperProps={{
style: {
backgroundColor: "white",
color: "black",
minWidth: "10%",
},
}}
>
<DialogTitle>
Are you sure you want to delete this quiz?
</DialogTitle>
<div className="btn-div">
<Button
className="logout-btn m-right bg-red-btn"
onClick={handleDelete}
>
Yes
</Button>
<Button
className="cancel-btn m-left"
onClick={() => setDeleteModal(false)}
>
No
</Button>
</div>
</Dialog>
<Dialog
open={deleteQuestionModal}
onClose={handleQuestionModalClose}
aria-labelledby="delete-quiz-modal"
PaperProps={{
style: {
backgroundColor: "white",
color: "black",
minWidth: "10%",
},
}}
>
<DialogTitle>
Are you sure you want to delete this question?
</DialogTitle>
<div className="btn-div">
<Button
className="logout-btn m-right bg-red-btn"
onClick={handleDeleteQuestion}
>
Yes
</Button>
<Button
className="cancel-btn m-left"
onClick={handleQuestionModalClose}
>
No
</Button>
</div>
</Dialog>
<Dialog
open={quizRestartModal}
onClose={() => setQuizRestartModal(false)}
aria-labelledby="restart-quiz-modal"
PaperProps={{
style: {
backgroundColor: "white",
color: "black",
minWidth: "10%",
},
}}
>
<DialogTitle>
Are you sure you want to restart this quiz?
</DialogTitle>
<div className="btn-div">
<Button
className="logout-btn m-right bg-green-btn"
onClick={handleRestart}
>
Yes
</Button>
<Button
className="cancel-btn m-left bg-red-btn"
onClick={() => setQuizRestartModal(false)}
>
No
</Button>
</div>
</Dialog>
<Dialog
open={closeQuizModal}
onClose={() => setCloseQuizModal(false)}
aria-labelledby="restart-quiz-modal"
PaperProps={{
style: {
backgroundColor: "white",
color: "black",
minWidth: "10%",
},
}}
>
<DialogTitle>
Are you sure you want to close this quiz?
</DialogTitle>
<div className="btn-div">
<Button
className="logout-btn m-right bg-green-btn"
onClick={handleQuizClose}
>
Yes
</Button>
<Button
className="cancel-btn m-left bg-red-btn"
onClick={() => setCloseQuizModal(false)}
>
No
</Button>
</div>
</Dialog>
<Snackbar
open={fileError}
autoHideDuration={3000}
onClose={() => setFileError(false)}
anchorOrigin={{ vertical: "bottom", horizontal: "left" }}
>
<Alert
variant="filled"
severity="error"
onClose={() => setFileError(false)}
>
There was some problem with the file. Try again...
</Alert>
</Snackbar>
<Snackbar
open={serverError}
autoHideDuration={3000}
onClose={() => setServerError(false)}
anchorOrigin={{ vertical: "bottom", horizontal: "left" }}
>
<Alert
variant="filled"
severity="error"
onClose={() => setServerError(false)}
>
There was some problem with the server. Try again...
</Alert>
</Snackbar>
</Container>
);
}
}