@material-ui/core#Collapse JavaScript Examples

The following examples show how to use @material-ui/core#Collapse. 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: LanguageSelector.js    From covid-trials-dashboard with MIT License 6 votes vote down vote up
LanguageSelector = ({ languages, onSelect }) => {
  const { t } = useTranslation('languages')
  const [open, setOpen] = useState(false)
  const classes = useStyles()
  console.log({ languages })
  return (
    <>
      <ListItem button onClick={() => setOpen(!open)}>
        <ListItemIcon>
          <LanguageOutlined />
        </ListItemIcon>
        <ListItemText primary={t('selectorTitle')} />
        {open ? <ExpandLess /> : <ExpandMore />}
      </ListItem>
      <Collapse in={open} timeout={300} unmountOnExit>
        <List component='div' disablePadding>
          {languages.map(lan => (
            <ListItem
              key={lan}
              button
              className={classes.nested}
              onClick={() => onSelect(lan)}
            >
              <ListItemText primary={t(lan)} />
            </ListItem>
          ))}
        </List>
      </Collapse>
    </>
  )
}
Example #2
Source File: sidebar-item.js    From horondi_client_fe with MIT License 6 votes vote down vote up
SideBarItem = ({ category, handlerItem, models, translationsKey, mainItemStyles }) => {
  const { sort, page, countPerPage, categoryFilter, modelsFilter, defaultPage } = URL_QUERIES_NAME;
  const { t } = useTranslation();

  const styles = useStyles();
  const [isListOpen, setIsListOpen] = useState(false);

  const handleClick = () => {
    setIsListOpen((prevValue) => setIsListOpen(!prevValue));
  };
  const countPerPageValue = ITEMS_PER_PAGE[0].value;

  return (
    <>
      <li className={mainItemStyles}>
        <ListItemText button='true' onClick={handleClick} primary={t(`${translationsKey}.name`)} />
        {isListOpen ? <RemoveIcon onClick={handleClick} /> : <AddIcon onClick={handleClick} />}
      </li>

      <Collapse in={isListOpen} timeout='auto' unmountOnExit>
        <List className={styles.list}>
          {models.map((model) => (
            <ListItem button className={styles.nested} key={model._id} onClick={handlerItem}>
              <Link
                to={`/catalog/products?${page}=${defaultPage}&${sort}=${POPULARITY}&${countPerPage}=${countPerPageValue}&${categoryFilter}=${category}&${modelsFilter}=${model._id}`}
              >
                <ListItemText primary={t(`${model.translationsKey}.name`)} />
              </Link>
            </ListItem>
          ))}
        </List>
      </Collapse>

      <div className={styles.itemHighlighting} />
    </>
  );
}
Example #3
Source File: ListDropdown.js    From mui-storyblok with MIT License 6 votes vote down vote up
ListDropdown = ({
  rootClass,
  listExpansion,
  content,
  dataBlokC,
  dataBlokUid,
  storyblokClass,
}) => {
  const styles = StoryBlok.arrayToMuiStyles(rootClass);
  const [open, setOpen] = useState(false);
  const handleClick = () => {
    setOpen(!open);
  };

  return (
    <MuiList
      className={`${styles.root} ${storyblokClass}`}
      data-blok-c={dataBlokC}
      data-blok-uid={dataBlokUid}
    >
      <ListExpansion {...listExpansion[0]} handleClick={handleClick} open={open} />
      <Collapse in={open} timeout="auto" unmountOnExit>
        {content.map((component, key) => renderComponents({ List }, component, key))}
      </Collapse>
    </MuiList>
  );
}
Example #4
Source File: CollapsibleMenuItem.js    From generator-webapp-rocket with MIT License 6 votes vote down vote up
CollapsibleMenuItem = ({ menu, ...rest }) => {
  const [open, setOpen] = useState(false)
  const toggleSubMenu = useCallback(() => setOpen(current => !current), [])

  return (
    <>
      <MenuItem menu={menu} subMenuOpen={open} onToggleSubMenu={toggleSubMenu} {...rest} />
      <Collapse in={open} timeout="auto" unmountOnExit>
        <List disablePadding>
          {menu?.children?.map((subMenu, key) => (
            <MenuItem key={key} menu={subMenu} isSubMenuItem={true} {...rest} />
          ))}
        </List>
      </Collapse>
    </>
  )
}
Example #5
Source File: Filter.jsx    From covid-trials-dashboard with MIT License 6 votes vote down vote up
Filter = ({ name, options, selected, onSelect }) => {
  const [open, setOpen] = useState(false)
  const classes = useStyles()
  const handleClick = useCallback(() => setOpen(!open), [open])
  return (
    <>
      <ListItem button onClick={handleClick}>
        <ListItemText primary={name} />
        {open ? <ExpandLess /> : <ExpandMore />}
      </ListItem>
      <Collapse in={open} timeout={300} unmountOnExit>
        <List component='div' disablePadding>
          {options.map(opt => (
            <ListItem
              key={opt}
              button
              className={classes.nested}
              onClick={() => onSelect(opt)}
            >
              <ListItemIcon>
                <Checkbox
                  edge='start'
                  checked={selected.includes(opt)}
                  tabIndex={-1}
                />
              </ListItemIcon>
              <ListItemText primary={opt} />
            </ListItem>
          ))}
        </List>
      </Collapse>
    </>
  )
}
Example #6
Source File: TagList.js    From ra-data-django-rest-framework with MIT License 6 votes vote down vote up
SubTree = ({ level, root, getChildNodes, openChildren, toggleNode }) => {
    const childNodes = getChildNodes(root);
    const hasChildren = childNodes.length > 0;
    const open = openChildren.includes(root.id);
    return (
        <Fragment>
            <ListItem
                button={hasChildren}
                onClick={() => hasChildren && toggleNode(root)}
                style={{ paddingLeft: level * 16 }}
            >
                {hasChildren && open && <ExpandLess />}
                {hasChildren && !open && <ExpandMore />}
                {!hasChildren && <div style={{ width: 24 }}>&nbsp;</div>}
                <ListItemText primary={root.name} />

                <ListItemSecondaryAction>
                    <EditButton record={root} basePath="/tags" />
                </ListItemSecondaryAction>
            </ListItem>
            <Collapse in={open} timeout="auto" unmountOnExit>
                <MuiList component="div" disablePadding>
                    {childNodes.map(node => (
                        <SubTree
                            key={node.id}
                            root={node}
                            getChildNodes={getChildNodes}
                            openChildren={openChildren}
                            toggleNode={toggleNode}
                            level={level + 1}
                        />
                    ))}
                </MuiList>
            </Collapse>
        </Fragment>
    );
}
Example #7
Source File: AlertMessage.js    From medha-STPC with GNU Affero General Public License v3.0 6 votes vote down vote up
AlertMessage = props => {
  let alertTitle = props.alertTitle;
  return (
    <Collapse in={props.openAlert}>
      <Alert
        variant={props.variant}
        severity={alertTitle}
        action={
          <IconButton
            aria-label={props.arialabel}
            color={props.color}
            size={props.size}
            onClick={props.onClick}
          >
            <CloseIcon fontSize="inherit" />
          </IconButton>
        }
      >
        {props.children}
      </Alert>
    </Collapse>
  );
}
Example #8
Source File: Disruption.js    From warsinhk with MIT License 5 votes vote down vote up
Disruption = props => {
  const { node, onCategoryClick } = props
  const { i18n, t } = useTranslation()
  const [expanded, setExpanded] = React.useState(false)

  const handleExpandClick = () => {
    setExpanded(!expanded)
  }

  const sourceUrl = withLanguage(i18n, node, "source_url")
  const hasDescription = props.children && props.children.length > 0
  const ExpandIcon = expanded ? InvertedExpandMoreIcon : ExpandMoreIcon

  return (
    <DisruptionCard>
      <DisruptionCardHeader title={withLanguage(i18n, node, "name")} />
      <DisruptionCardContent>
        <Box alignItems="flex-start">
          <Row>
            <Chip
              label={withLanguage(i18n, node, "category")}
              size="small"
              variant="outlined"
              onClick={() =>
                onCategoryClick(withLanguage(i18n, node, "category"))
              }
            />
          </Row>
          <Row>
            <DisruptionDetail variant="body1">
              {withLanguage(i18n, node, "detail")}
            </DisruptionDetail>
          </Row>
          <Row>
            {t("disruption.status")}:{" "}
            {withLanguage(i18n, node, "status") || "-"}
          </Row>
          <Row>
            {t("disruption.to")}: {withLanguage(i18n, node, "to") || "-"}
          </Row>
        </Box>
      </DisruptionCardContent>
      <>
        <DisruptionCardActions disableSpacing>
          <DisruptionAction>
            {sourceUrl && (
              <Row>
                <Typography variant="caption">
                  <Link component={Link} href={sourceUrl} target="_blank">
                    {t("disruption.source")}
                  </Link>
                </Typography>
              </Row>
            )}
            <Row>
              <Typography variant="caption">
                {t("disruption.last_updated", { date: node.last_update })}
              </Typography>
            </Row>
          </DisruptionAction>
          {hasDescription && (
            <IconButton onClick={handleExpandClick} aria-expanded={expanded}>
              <ExpandIcon />
            </IconButton>
          )}
        </DisruptionCardActions>
        {hasDescription && (
          <Collapse in={expanded} timeout="auto" unmountOnExit>
            <DisruptionCardContent>
              {hasDescription && (
                <Box alignItems="flex-start">{props.children}</Box>
              )}
            </DisruptionCardContent>
          </Collapse>
        )}
      </>
    </DisruptionCard>
  )
}
Example #9
Source File: Comments.jsx    From archeage-tools with The Unlicense 5 votes vote down vote up
render() {
    const { postId } = this.props;
    const { comments, commentCount, newComment, sortAsc } = this.state;

    return (
      <div className="section" id="comments">
        <AppBar position="static">
          <Toolbar variant="dense">
            <Typography variant="h6" className="title-text">
              Comments ({commentCount})
            </Typography>
            <Tooltip title={`Show ${sortAsc ? 'Newest' : 'Oldest'} First`}>
              <IconButton color="inherit" onClick={this.setSortAsc(!sortAsc)}>
                <SortIcon />
              </IconButton>
            </Tooltip>
            <IfPerm permission="comment.create">
              <Tooltip title="Write Comment">
                <IconButton color="inherit" onClick={this.handleNewComment}>
                  <CreateIcon />
                </IconButton>
              </Tooltip>
            </IfPerm>
          </Toolbar>
        </AppBar>
        <Paper className="body-container space-children comments-container">
          <Collapse in={newComment} unmountOnExit>
            <EditComment
              postId={postId}
              depth={2}
              onCancel={this.cancelNewComment}
              onUpdateComments={this.updateComments}
            />
          </Collapse>

          {comments && comments.map(comment => (
            <Comment
              {...comment}
              onUpdateComments={this.updateComments}
              key={`comment-${comment.id}`}
              depth={2}
              sortAsc={sortAsc}
            />))}
          {(!comments || comments.length === 0) &&
          <Typography align="center">
            There are no comments on this topic.
          </Typography>}
        </Paper>
      </div>
    );
  }
Example #10
Source File: SidePanelItem.jsx    From simplQ-frontend with GNU General Public License v3.0 5 votes vote down vote up
SidePanelItem = ({
  title,
  description,
  Icon,
  expandable = false,
  onClick,
  children,
  tourTag = '',
  style = 'side-panel-item',
}) => {
  const [open, setOpen] = useState(false);
  const onClickHandler = () => {
    if (expandable) {
      setOpen(!open);
    }
    if (onClick) {
      onClick();
    }
  };

  return (
    <div className={styles[style]}>
      <div
        reactour-selector={tourTag}
        className={styles['header']}
        tabIndex={0}
        role="button"
        onKeyDown={onClickHandler}
        onClick={onClickHandler}
      >
        <Icon className={styles['icon']} fontSize="large" />
        <div>
          <h2>{title}</h2>
          <p className={styles['description']}>{description}</p>
        </div>
        {expandable && <ExpandButton isOpen={open} />}
      </div>
      {expandable && (
        <Collapse timeout="auto" in={open}>
          {children}
        </Collapse>
      )}
    </div>
  );
}
Example #11
Source File: index.js    From iiitt with MIT License 5 votes vote down vote up
export default function Faq(props) {

  const { question, answer, questionNumber } = props;

  const classes = createStyles(props);

  const [expanded, setExpanded] = React.useState(false);

  const toggleFaq = () => {
    setExpanded(!expanded);
  };

  return (
    <>
      <Card className={classes.root}>
        <CardContent
          onClick={toggleFaq}
          aria-expanded={expanded}
          aria-label="Show answer"
        >
          <IconButton
            onClick={toggleFaq}
            aria-expanded={expanded}
            aria-label="Show answer"
          >
            <KeyboardArrowRightIcon />
          </IconButton>
          {question}
        </CardContent>
        <Collapse
          in={expanded}
          timeout="auto"
          unmountOnExit
          className={classes.answer}
        >
          <CardContent className={classes.text}>
            {answer}
            {questionNumber === 11 ? <Link style={{display: 'inline'}} to='/contactus'>location page for more information.</Link> : null}
          </CardContent>
        </Collapse>
      </Card>
    </>
  );
}
Example #12
Source File: ToolbarExtension.js    From eSim-Cloud with GNU General Public License v3.0 5 votes vote down vote up
function LibraryRow ({ library }) {
  const dispatch = useDispatch()
  const [open, setopen] = React.useState(false)
  const classes = useStyles()
  const components = useSelector(state => state.schematicEditorReducer.components)

  const handleAppply = (lib) => {
    dispatch(fetchLibrary(lib.id))
  }

  const handleUnapply = (lib) => {
    dispatch(removeLibrary(lib.id))
  }

  const handleOpen = () => {
    if (components[library.id].length === 0) { dispatch(fetchComponents(library.id)) }
    setopen(!open)
  }

  return (
    <Paper style={{ marginBottom: '.5rem' }}>
      <ListSubheader>
        <ListItem onClick={handleOpen} >
          {open ? <ExpandLess /> : <ExpandMore />}
          <ListItemText primary={library.library_name.slice(0, -4)} />
          <ListItemSecondaryAction>
            {(!library.default && !library.additional) &&
              <Button variant="contained" size="small"
                style={{ backgroundColor: '#ff1744', color: '#ffffff', margin: '.5rem' }}
                onClick={() => { dispatch(deleteLibrary(library.id)) }} hidden={library.default || library.additional} >
                Delete
              </Button>
            }
            {library.active
              ? <Button variant="contained" size="small" color="secondary"
                onClick={() => { handleUnapply(library) }} style={{ margin: '.5rem' }}>
                Remove
              </Button>
              : <Button variant="contained" size="small" color="primary"
                onClick={() => { handleAppply(library) }} style={{ margin: '.5rem' }}>
                Use
              </Button>
            }
          </ListItemSecondaryAction>
        </ListItem>
      </ListSubheader>

      {(components[library.id]) &&
        <Collapse in={open} timeout="auto" unmountOnExit>
          <List component="div" style={{ paddingLeft: '1rem', paddingRight: '1rem' }}>
            {components[library.id].map(component => {
              return (
                <ListItem alignItems='center' key={component.id} dense className={classes.nested}>
                  <ListItemText primary={component.name} secondary={component.description} />
                </ListItem>
              )
            })}
          </List>
        </Collapse>
      }
    </Paper>
  )
}
Example #13
Source File: SystemStatus.jsx    From Edlib with GNU General Public License v3.0 5 votes vote down vote up
SystemStatus = ({ name, loading, error, data }) => {
    const [isExpanded, setIsExpanded] = React.useState(false);

    if (loading) {
        return (
            <Paper>
                <h2>{name}</h2>
            </Paper>
        );
    }

    if (error) {
        return (
            <Paper>
                <Box display="flex" justifyContent="space-between">
                    <div>{name}</div>
                    <div>
                        <i className="fa fa-caret-down" />
                    </div>
                </Box>
                <Collapse in={isExpanded} timeout="auto">
                    <Typography>
                        Could not get service status. This might be because the
                        service is not set up properly or that you have no
                        internet connection.
                    </Typography>
                </Collapse>
            </Paper>
        );
    }

    return (
        <Paper>
            <Box
                display="flex"
                justifyContent="space-between"
                bgcolor={data.color + '.main'}
                onClick={() => setIsExpanded(!isExpanded)}
            >
                <div>{name}</div>
                <div>
                    <i className="fa fa-caret-down" />
                </div>
            </Box>
            <Collapse in={isExpanded}>
                <Table>
                    <TableHead>
                        <tr>
                            <th width={35} />
                            <th>Subservice name</th>
                            <th>Status</th>
                            <th>Parameters</th>
                        </tr>
                    </TableHead>
                    <TableBody>
                        {data.systems.map((s, index) => (
                            <TableRow key={index}>
                                <TableCell className={'bg-' + s.color} />
                                <TableCell>{s.name}</TableCell>
                                <TableCell>{s.statusMessage}</TableCell>
                                <TableCell>
                                    {s.parameters &&
                                        Object.entries(s.parameters).map(
                                            ([key, value]) => (
                                                <div>
                                                    <strong>{key}: </strong>
                                                    {value}
                                                </div>
                                            )
                                        )}
                                </TableCell>
                            </TableRow>
                        ))}
                    </TableBody>
                </Table>
            </Collapse>
        </Paper>
    );
}
Example #14
Source File: CheckboxFacet.js    From azure-search-react-template with MIT License 5 votes vote down vote up
export default function CheckboxFacet(props) {

    let [isExpanded, setIsExpanded] = useState(false);

    const checkboxes = props.values.map(facetValue => {

        let isSelected = props.selectedFacets.some(facet => facet.value === facetValue.value);
        
        return (
            <FacetValueListItem dense disableGutters id={facetValue.value}>
                <Checkbox 
                    edge="start" 
                    disableRipple 
                    checked={isSelected}
                    onClick= {
                        isSelected ? 
                        () => props.removeFilter({field: props.name, value: facetValue.value}) :
                        () => props.addFilter(props.name, facetValue.value)
                    }
                />
                <ListItemText primary={facetValue.value + " (" + facetValue.count + ")"}/>
            </FacetValueListItem>
        );
    });


    return (
        <div>
            <FacetListItem disableRipple={true} button onClick={() => setIsExpanded(!isExpanded)}>
                <ListItemText 
                    primary={props.mapFacetName(props.name)}
                />
                {isExpanded ? <ExpandLess /> : <ExpandMore />}
            </FacetListItem>
            <Collapse in={isExpanded} component="div">
                <FacetValuesList>
                    {checkboxes}
                </FacetValuesList>
            </Collapse>
        </div>
    );
}
Example #15
Source File: CheckoutItem.jsx    From resilience-app with GNU General Public License v3.0 5 votes vote down vote up
export default function CheckoutItem({ cost, description, name, onChange, quantity }) {
  const classes = useStyles();
  const [open, setOpen] = useState(false);

  const [width, setWidth] = useState(0);
  const ref = useCallback((node) => node && setWidth(node.offsetWidth), []);

  const crop = width / CHAR_WIDTH;
  const formatedDescription =
    description.length > crop ? description.slice(0, crop) + "..." : description;

  return (
    <>
      <Divider />
      <ListItem className={classes.listItem}>
        {onChange ? (
          <Select
            className={classes.select}
            native
            variant="outlined"
            value={quantity}
            onChange={onChange}
            inputProps={{
              name: "quantity",
              id: "quantity",
            }}
          >
            {[...Array(MAX_ORDER + 1)].map((e, i) => (
              <option value={i} key={i}>
                {i}
              </option>
            ))}
          </Select>
        ) : (
          <Typography className={classes.quantity} variant="h4">
            {quantity}
          </Typography>
        )}
        <RootRef rootRef={ref}>
          <Box onClick={() => setOpen(!open)} flex={1} display="flex" flexDirection="column">
            <Typography variant="h4" color="textPrimary">
              {name}
            </Typography>
            {!open && formatedDescription}
            <Collapse in={open} timeout={0}>
              {description}
            </Collapse>
            <Expand open={open} />
          </Box>
        </RootRef>
        <ListItemText className={classes.cost}>
          <Typography variant={onChange ? "h4" : "body1"} color="textPrimary">
            ${parseFloat(cost).toFixed(2)}
          </Typography>
        </ListItemText>
      </ListItem>
    </>
  );
}
Example #16
Source File: ConnectionsList.js    From spl-token-wallet with Apache License 2.0 5 votes vote down vote up
function ConnectionsListItem({ origin, connectedWallet }) {
  const classes = useStyles();
  const [open, setOpen] = useState(false);
  // TODO better way to get high res icon?
  const appleIconUrl = origin + '/apple-touch-icon.png';
  const faviconUrl = origin + '/favicon.ico';
  const [iconUrl, setIconUrl] = useState(appleIconUrl);
  const { accounts } = useWalletSelector();
  // TODO better way to do this
  const account = accounts.find(
    (account) => account.address.toBase58() === connectedWallet.publicKey,
  );

  const setAutoApprove = (autoApprove) => {
    chrome.storage.local.get('connectedWallets', (result) => {
      result.connectedWallets[origin].autoApprove = autoApprove;
      chrome.storage.local.set({ connectedWallets: result.connectedWallets });
    });
  };

  const disconnectWallet = () => {
    chrome.storage.local.get('connectedWallets', (result) => {
      delete result.connectedWallets[origin];
      chrome.storage.local.set({ connectedWallets: result.connectedWallets });
    });
  };

  return (
    <>
      <ListItem button onClick={() => setOpen((open) => !open)}>
        <ListItemIcon>
          <div className={classes.listItemIcon}>
            <img
              src={iconUrl}
              onError={() => setIconUrl(faviconUrl)}
              className={classes.listItemImage}
              alt=""
            />
          </div>
        </ListItemIcon>
        <div style={{ display: 'flex', flex: 1 }}>
          <ListItemText primary={origin} secondary={account.name} />
        </div>
        {open ? <ExpandLess /> : <ExpandMore />}
      </ListItem>
      <Collapse in={open} timeout="auto" unmountOnExit>
        <div class={classes.itemDetails}>
          <div class={classes.buttonContainer}>
            <Button
              variant={connectedWallet.autoApprove ? 'contained' : 'outlined'}
              color="primary"
              size="small"
              startIcon={<DoneAll />}
              onClick={() => setAutoApprove(!connectedWallet.autoApprove)}
            >
              {connectedWallet.autoApprove ? 'Auto-Approved' : 'Auto-Approve'}
            </Button>
            <Button
              variant="outlined"
              color="secondary"
              size="small"
              startIcon={<DeleteIcon />}
              onClick={disconnectWallet}
            >
              Disconnect
            </Button>
          </div>
        </div>
      </Collapse>
    </>
  );
}
Example #17
Source File: SidebarLink.js    From react-code-splitting-2021-04-26 with MIT License 4 votes vote down vote up
export default function SidebarLink({
  link,
  icon,
  label,
  children,
  location,
  isSidebarOpened,
  nested,
  type,
}) {
  var classes = useStyles();

  // local
  var [isOpen, setIsOpen] = useState(false);
  var isLinkActive =
    link &&
    (location.pathname === link || location.pathname.indexOf(link) !== -1);

  if (type === "title")
    return (
      <Typography
        className={classnames(classes.linkText, classes.sectionTitle, {
          [classes.linkTextHidden]: !isSidebarOpened,
        })}
      >
        {label}
      </Typography>
    );

  if (type === "divider") return <Divider className={classes.divider} />;
  if (link && link.includes('http')) {
    return (
      <ListItem
        button
        className={classes.link}
        classes={{
          root: classnames(classes.linkRoot, {
            [classes.linkActive]: isLinkActive && !nested,
            [classes.linkNested]: nested,
          }),
        }}
        disableRipple
      >
        <a className={classes.externalLink} href={link}>
        <ListItemIcon
          className={classnames(classes.linkIcon, {
            [classes.linkIconActive]: isLinkActive,
          })}
        >
          {nested ? <Dot color={isLinkActive && "primary"} /> : icon}
        </ListItemIcon>
        <ListItemText
          classes={{
            primary: classnames(classes.linkText, {
              [classes.linkTextActive]: isLinkActive,
              [classes.linkTextHidden]: !isSidebarOpened,
            }),
          }}
          primary={label}
        />
        </a>
      </ListItem>
    )
  }
  if (!children)
    return (
      <ListItem
        button
        component={link && Link}
        to={link}
        className={classes.link}
        classes={{
          root: classnames(classes.linkRoot, {
            [classes.linkActive]: isLinkActive && !nested,
            [classes.linkNested]: nested,
          }),
        }}
        disableRipple
      >
        <ListItemIcon
          className={classnames(classes.linkIcon, {
            [classes.linkIconActive]: isLinkActive,
          })}
        >
          {nested ? <Dot color={isLinkActive && "primary"} /> : icon}
        </ListItemIcon>
        <ListItemText
          classes={{
            primary: classnames(classes.linkText, {
              [classes.linkTextActive]: isLinkActive,
              [classes.linkTextHidden]: !isSidebarOpened,
            }),
          }}
          primary={label}
        />
      </ListItem>
    );

  return (
    <>
      <ListItem
        button
        component={link && Link}
        onClick={toggleCollapse}
        className={classes.link}
        to={link}
        disableRipple
      >
        <ListItemIcon
          className={classnames(classes.linkIcon, {
            [classes.linkIconActive]: isLinkActive,
          })}
        >
          {icon ? icon : <InboxIcon />}
        </ListItemIcon>
        <ListItemText
          classes={{
            primary: classnames(classes.linkText, {
              [classes.linkTextActive]: isLinkActive,
              [classes.linkTextHidden]: !isSidebarOpened,
            }),
          }}
          primary={label}
        />
      </ListItem>
      {children && (
        <Collapse
          in={isOpen && isSidebarOpened}
          timeout="auto"
          unmountOnExit
          className={classes.nestedList}
        >
          <List component="div" disablePadding>
            {children.map(childrenLink => (
              <SidebarLink
                key={childrenLink && childrenLink.link}
                location={location}
                isSidebarOpened={isSidebarOpened}
                classes={classes}
                nested
                {...childrenLink}
              />
            ))}
          </List>
        </Collapse>
      )}
    </>
  );

  // ###########################################################

  function toggleCollapse(e) {
    if (isSidebarOpened) {
      e.preventDefault();
      setIsOpen(!isOpen);
    }
  }
}
Example #18
Source File: EventFeedback.js    From medha-STPC with GNU Affero General Public License v3.0 4 votes vote down vote up
EventFeedback = props => {
  const [open, setOpen] = React.useState(true);
  const history = useHistory();
  const classes = useStyles();
  const [setSelectedRows] = useState([]);
  const { setLoaderStatus } = useContext(LoaderContext);

  const [formState, setFormState] = useState({
    dataToShow: [],
    tempData: [],
    events: [],
    greenButtonChecker: true,
    /** Filters */
    eventFilterData: [],
    selectedRowFilter: true,
    filterDataParameters: {},
    isClearResetFilter: false,
    isFilterSearch: false,
    startDate: null,
    endDate: null,
    texttvalue: "",
    toggleCleared: false,
    isEventCleared: "",
    /** Pagination and sortinig data */
    resetPagination: false,
    isDataLoading: false,
    pageSize: "",
    totalRows: "",
    page: "",
    pageCount: "",
    sortAscending: true,
    errors: {}
  });

  /** Special feedbackState state variable to set parameters for feedback  */
  const [feedbackState, setFeedbackState] = useState({
    /** Feedback */
    /**  showModalFeedback is used to enable the popup of modal for view/add/edit feedback.*/
    showModalFeedback: false,
    EventTitle: null,
    eventId: null,
    /** feedBackGiven , fromFeedBackModal this two flags are used to set the success and error messages*/
    feedBackGiven: false,
    fromFeedBackModal: false,
    successErrorMessage: "",

    /** showErrorModalFeedback this flag sets the error feedback modal ehich is used to dispaly the popup for error */
    showErrorModalFeedback: false,
    /** errorMessage is used to display what error needs to be shown for popup */
    errorHeading: "",
    errorMessage: "",

    ratings: [],
    /** showAddEditModalFeedback this flags enables the add/edit feedback modal. */
    showAddEditModalFeedback: false,
    /** Below three flags are used to identify whether to give, edit or to view feedback. */
    isGiveFeedback: false,
    isEditFeedback: false,
    isViewFeedback: false,

    /** This has the question set for adding feedback and also for editing feedback with answers also (for editing) */
    entityQuestionSet: [],
    /** questionSetId is while adding/editng */
    questionSetId: null,
    /** feedbackSetId is used while editing to identify where to store data against which feedback. */
    feedbackSetId: null,
    dataFor: "",
    result: {}
  });

  useEffect(() => {
    if (auth.getUserInfo() !== null) {
      getEventData(10, 1);
    } else {
      auth.clearAppStorage();
      history.push({
        pathname: routeConstants.SIGN_IN_URL
      });
    }
  }, []);

  const getEventData = async (pageSize, page, paramsForEvents = null) => {
    if (
      paramsForEvents !== null &&
      !formUtilities.checkEmpty(paramsForEvents)
    ) {
      let defaultParams = {};
      if (paramsForEvents.hasOwnProperty(SORT_FIELD_KEY)) {
        defaultParams = {
          page: page,
          pageSize: pageSize
        };
      } else {
        defaultParams = {
          page: page,
          pageSize: pageSize,
          [SORT_FIELD_KEY]: "title:asc"
        };
      }
      Object.keys(paramsForEvents).map(key => {
        defaultParams[key] = paramsForEvents[key];
      });
      paramsForEvents = defaultParams;
    } else {
      paramsForEvents = {
        page: page,
        pageSize: pageSize,
        [SORT_FIELD_KEY]: "title:asc"
      };
    }
    setFormState(formState => ({
      ...formState,
      isDataLoading: true
    }));
    if (auth.getUserInfo().role !== null) {
      if (
        auth.getUserInfo().role.name === roleConstants.RPCADMIN ||
        (auth.getUserInfo().role.name === roleConstants.COLLEGEADMIN &&
          auth.getUserInfo().studentInfo.organization.contact.id ===
            auth.getUserInfo().rpc.main_college)
      ) {
        const EVENTS_FOR_RPC_ADMIN =
          strapiConstants.STRAPI_DB_URL +
          strapiConstants.STRAPI_CONTACTS +
          "/" +
          auth.getUserInfo().rpc.id +
          "/get-rpc-events";
        await serviceProviders
          .serviceProviderForGetRequest(EVENTS_FOR_RPC_ADMIN, paramsForEvents)
          .then(res => {
            formState.dataToShow = [];
            formState.tempData = [];
            let eventData = [];
            eventData = convertEventData(res.data.result);
            setFormState(formState => ({
              ...formState,
              events: res.data.result,
              pageSize: res.data.pageSize,
              totalRows: res.data.rowCount,
              page: res.data.page,
              pageCount: res.data.pageCount,
              dataToShow: eventData,
              tempData: eventData,
              isDataLoading: false
            }));
          })
          .catch(error => {
            console.log("error", error);
          });
      } else if (auth.getUserInfo().role.name === roleConstants.ZONALADMIN) {
        const EVENTS_FOR_ZONAL_ADMIN =
          strapiConstants.STRAPI_DB_URL +
          strapiConstants.STRAPI_CONTACTS +
          "/" +
          auth.getUserInfo().zone.id +
          "/get-zone-events";
        await serviceProviders
          .serviceProviderForGetRequest(EVENTS_FOR_ZONAL_ADMIN, paramsForEvents)
          .then(res => {
            formState.dataToShow = [];
            formState.tempData = [];
            let eventData = [];
            eventData = convertEventData(res.data.result);
            setFormState(formState => ({
              ...formState,
              events: res.data.result,
              pageSize: res.data.pageSize,
              totalRows: res.data.rowCount,
              page: res.data.page,
              pageCount: res.data.pageCount,
              dataToShow: eventData,
              tempData: eventData,
              isDataLoading: false
            }));
          })
          .catch(error => {
            console.log("error", error);
          });
      }
    } else {
      auth.clearAppStorage();
      history.push({
        pathname: routeConstants.SIGN_IN_URL
      });
    }
  };

  const convertEventData = data => {
    let x = [];
    if (data.length > 0) {
      for (let i in data) {
        var eventIndividualData = {};
        let startDate = new Date(data[i]["start_date_time"]);
        let endDate = new Date(data[i]["end_date_time"]);
        eventIndividualData["id"] = data[i]["id"];

        eventIndividualData["title"] = data[i]["title"] ? data[i]["title"] : "";
        eventIndividualData["start_date_time"] = startDate.toDateString();
        eventIndividualData["end_date_time"] = endDate.toDateString();

        /** Several feedback flags are taken form the response itself  */

        /** can a college admin add/edit/cannot give feedback */

        /**  */
        eventIndividualData["question_set"] = data[i]["question_set"]
          ? true
          : false;
        eventIndividualData["giveFeedback"] = false;
        eventIndividualData["editFeedback"] = false;
        eventIndividualData["cannotGiveFeedback"] = false;
        eventIndividualData["feedbackId"] = data[i]["feedbackSetId"];

        if (
          auth.getUserInfo().role.name === roleConstants.RPCADMIN ||
          (auth.getUserInfo().role.name === roleConstants.COLLEGEADMIN &&
            auth.getUserInfo().studentInfo.organization.contact.id ===
              auth.getUserInfo().rpc.main_college)
        ) {
          /** Can college admin view feedback */
          eventIndividualData["isFeedbackFromCollegePresent"] =
            data[i]["isFeedbackFromCollegePresent"];

          if (data[i]["question_set"] && !data[i]["isFeedbackProvidedbyRPC"]) {
            eventIndividualData["giveFeedback"] = true;
          } else if (
            data[i]["question_set"] &&
            data[i]["isFeedbackProvidedbyRPC"]
          ) {
            eventIndividualData["editFeedback"] = true;
          } else if (!data[i]["question_set"]) {
            eventIndividualData["cannotGiveFeedback"] = true;
          } else {
            eventIndividualData["cannotGiveFeedback"] = true;
          }
        } else {
          if (data[i]["question_set"] && !data[i]["isFeedbackProvidedbyZone"]) {
            eventIndividualData["giveFeedback"] = true;
          } else if (
            data[i]["question_set"] &&
            data[i]["isFeedbackProvidedbyZone"]
          ) {
            eventIndividualData["editFeedback"] = true;
          } else if (!data[i]["question_set"]) {
            eventIndividualData["cannotGiveFeedback"] = true;
          } else {
            eventIndividualData["cannotGiveFeedback"] = true;
          }
        }

        x.push(eventIndividualData);
      }
      return x;
    }
  };

  /** Pagination */
  const handlePerRowsChange = async (perPage, page) => {
    /** If we change the now of rows per page with filters supplied then the filter should by default be applied*/
    if (formUtilities.checkEmpty(formState.filterDataParameters)) {
      await getEventData(perPage, page);
    } else {
      if (formState.isFilterSearch) {
        await searchFilter(perPage, page);
      } else {
        await getEventData(perPage, page, formState.filterDataParameters);
      }
    }
  };

  const handlePageChange = async page => {
    if (formUtilities.checkEmpty(formState.filterDataParameters)) {
      await getEventData(formState.pageSize, page);
    } else {
      if (formState.isFilterSearch) {
        await searchFilter(formState.pageSize, page);
      } else {
        await getEventData(
          formState.pageSize,
          page,
          formState.filterDataParameters
        );
      }
    }
  };

  const handleRowSelected = useCallback(state => {
    if (state.selectedCount >= 1) {
      setFormState(formState => ({
        ...formState,
        selectedRowFilter: false,
        toggleCleared: false
      }));
    } else {
      setFormState(formState => ({
        ...formState,
        selectedRowFilter: true
      }));
    }
    setSelectedRows(state.selectedRows);
  }, []);

  const selectedRowCleared = data => {
    formState.toggleCleared = data;
    setTimeout(() => {
      setFormState(formState => ({
        ...formState,
        toggleCleared: false
      }));
    }, 2000);
  };

  /** For Adding feedback */
  const viewFeedback = async cell => {
    setLoaderStatus(true);

    let result = {};
    if (
      auth.getUserInfo().role.name === roleConstants.RPCADMIN ||
      (auth.getUserInfo().role.name === roleConstants.COLLEGEADMIN &&
        auth.getUserInfo().studentInfo.organization.contact.id ===
          auth.getUserInfo().rpc.main_college)
    ) {
      result = {
        [roleConstants.COLLEGEADMIN]: null
      };
    }

    const QUESTION_SET_URL =
      strapiConstants.STRAPI_DB_URL +
      strapiConstants.STRAPI_EVENTS +
      "/" +
      cell.id +
      "/" +
      strapiConstants.STRAPI_RPC +
      "/" +
      auth.getUserInfo().rpc.id +
      "/getCollegeFeedbackForRPC";

    await serviceProviders
      .serviceProviderForGetRequest(QUESTION_SET_URL)
      .then(res => {
        result[roleConstants.COLLEGEADMIN] = res.data.result;
        setLoaderStatus(false);
      })
      .catch(error => {
        result[roleConstants.COLLEGEADMIN] = [];
        setLoaderStatus(false);
      });

    setFeedbackState(feedbackState => ({
      ...feedbackState,
      isViewFeedback: true,
      isEditFeedback: false,
      isGiveFeedback: false,
      showModalFeedback: true,
      EventTitle: cell.title,
      eventId: cell.id,
      feedBackGiven: false,
      fromFeedBackModal: false,
      successErrorMessage: "",
      result: result,
      showErrorModalFeedback: false
    }));
  };

  /** For Viewing feedback for Zonal Admin feedback */
  const viewCollegeFeedback = async cell => {
    setLoaderStatus(true);
    const COLLEGE_FEEDBACK =
      strapiConstants.STRAPI_DB_URL +
      strapiConstants.STRAPI_EVENTS +
      "/" +
      cell.id +
      "/getFeedbackForZone/" +
      auth.getUserInfo().zone.id +
      "/DataFor/college/FeedbackType/rating";

    const ZONE_FEEDBACK =
      strapiConstants.STRAPI_DB_URL +
      strapiConstants.STRAPI_EVENTS +
      "/" +
      cell.id +
      "/getFeedbackForZone/" +
      auth.getUserInfo().zone.id +
      "/DataFor/rpc/FeedbackType/rating";

    let result = {};
    if (auth.getUserInfo().role.name === roleConstants.ZONALADMIN) {
      result = {
        [roleConstants.RPCADMIN]: null,
        [roleConstants.COLLEGEADMIN]: null
      };
    }

    await serviceProviders
      .serviceProviderForGetRequest(COLLEGE_FEEDBACK)
      .then(res => {
        result[roleConstants.COLLEGEADMIN] = res.data.result;
      })
      .catch(error => {
        result[roleConstants.COLLEGEADMIN] = [];
      });

    await serviceProviders
      .serviceProviderForGetRequest(ZONE_FEEDBACK)
      .then(res => {
        setLoaderStatus(false);
        result[roleConstants.RPCADMIN] = res.data.result;
      })
      .catch(error => {
        setLoaderStatus(false);
        result[roleConstants.RPCADMIN] = [];
      });

    setFeedbackState(feedbackState => ({
      ...feedbackState,
      isViewFeedback: true,
      isEditFeedback: false,
      isGiveFeedback: false,
      showModalFeedback: true,
      EventTitle: cell.title,
      eventId: cell.id,
      feedBackGiven: false,
      fromFeedBackModal: false,
      successErrorMessage: "",
      result: result,
      showErrorModalFeedback: false,
      dataFor: "college"
    }));
  };

  /** Give feedback */
  const giveFeedback = async event => {
    setLoaderStatus(true);
    const QUESTION_SET_URL =
      strapiConstants.STRAPI_DB_URL +
      strapiConstants.STRAPI_EVENTS +
      "/" +
      event.id +
      "/" +
      strapiConstants.STRAPI_QUESTION_SET;
    await serviceProviders
      .serviceProviderForGetRequest(QUESTION_SET_URL)
      .then(res => {
        setFeedbackState(feedbackState => ({
          ...feedbackState,
          showModalFeedback: true,
          EventTitle: event.title,
          eventId: event.id,
          isGiveFeedback: true,
          isEditFeedback: false,
          isViewFeedback: false,
          showErrorModalFeedback: false,
          entityQuestionSet: res.data.result.questions,
          questionSetId: res.data.result.id,
          feedBackGiven: false,
          fromFeedBackModal: false,
          successErrorMessage: ""
        }));
        setLoaderStatus(false);
      })
      .catch(error => {
        setFeedbackState(feedbackState => ({
          ...feedbackState,
          showModalFeedback: false,
          showErrorModalFeedback: true,
          EventTitle: event.title,
          isEditFeedback: false,
          isGiveFeedback: false,
          isViewFeedback: false,
          feedBackGiven: false,
          fromFeedBackModal: false,
          successErrorMessage: "",
          errorHeading: "Add Feedback",
          errorMessage: "Cannot add feedback"
        }));
        setLoaderStatus(false);
        console.log("error giving feedback");
      });
  };

  /** ------ */
  /** Edit feedback */
  const editFeedback = async event => {
    setLoaderStatus(true);
    let FEEDBACK_SET_URL = "";
    if (auth.getUserInfo().role.name === roleConstants.COLLEGEADMIN) {
      FEEDBACK_SET_URL =
        strapiConstants.STRAPI_DB_URL +
        strapiConstants.STRAPI_FEEDBACK_SETS +
        "/role/" +
        auth.getUserInfo().rpcAdminRole.id;
    } else {
      FEEDBACK_SET_URL =
        strapiConstants.STRAPI_DB_URL + strapiConstants.STRAPI_FEEDBACK_SETS;
    }
    await serviceProviders
      .serviceProviderForGetOneRequest(FEEDBACK_SET_URL, event.feedbackId)
      .then(res => {
        setFeedbackState(feedbackState => ({
          ...feedbackState,
          EventTitle: event.eventName,
          eventId: event.id,
          isGiveFeedback: false,
          isEditFeedback: true,
          isViewFeedback: false,
          showModalFeedback: true,
          showErrorModalFeedback: false,
          feedbackSetId: event.feedbackId,
          questionSetId: res.data.result.question_set.id,
          entityQuestionSet: res.data.result.questions,
          feedBackGiven: false,
          fromFeedBackModal: false,
          successErrorMessage: ""
        }));
        setLoaderStatus(false);
      })
      .catch(error => {
        setFeedbackState(feedbackState => ({
          ...feedbackState,
          showModalFeedback: false,
          showErrorModalFeedback: true,
          EventTitle: event.eventName,
          isGiveFeedback: false,
          isEditFeedback: false,
          isViewFeedback: false,
          feedBackGiven: false,
          fromFeedBackModal: false,
          successErrorMessage: "",
          errorHeading: "Edit Feedback",
          errorMessage: "Cannot edit feedback"
        }));
        setLoaderStatus(false);
        console.log("error giving feedback");
      });
  };

  /** ---------------------------------------------------- */

  /** Used for restoring data */
  const restoreData = () => {
    getEventData(formState.pageSize, 1);
  };

  /** Filter methods and functions */
  /** This restores all the data when we clear the filters*/

  const clearFilter = () => {
    selectedRowCleared(true);

    setFormState(formState => ({
      ...formState,
      isFilterSearch: false,
      /** Clear all filters */
      filterDataParameters: {},
      /** Turns on the spinner */
      isClearResetFilter: true,
      isDataLoading: true,
      texttvalue: "",
      startDate: null,
      endDate: null,
      eventFilterData: [],
      errors: {}
    }));
    restoreData();
  };

  /** Handle Start Date filter change */
  const handleStartDateChange = (START_DATE_FILTER, event) => {
    let startDate = moment(event).format("YYYY-MM-DDT00:00:00.000Z");
    if (startDate === "Invalid date") {
      startDate = null;
      delete formState.filterDataParameters[START_DATE_FILTER];
    } else {
      formState.filterDataParameters[START_DATE_FILTER] = new Date(
        startDate
      ).toISOString();
      if (
        formState.filterDataParameters.hasOwnProperty(END_DATE_FILTER) &&
        formState.filterDataParameters[START_DATE_FILTER] >
          formState.filterDataParameters[END_DATE_FILTER]
      ) {
        formState.errors["dateFrom"] = [
          "Start date cannot be greater than end date"
        ];
      } else {
        delete formState.errors["dateTo"];
        delete formState.errors["dateFrom"];
      }
    }

    setFormState(formState => ({
      ...formState,
      startDate: event
    }));
  };

  /** Handle End Date filter change */
  const handleEndDateChange = (END_DATE_FILTER, event) => {
    let endDate = moment(event)
      .add(1, "days")
      .format("YYYY-MM-DDT00:00:00.000Z");
    if (endDate === "Invalid date") {
      endDate = null;
      delete formState.filterDataParameters[END_DATE_FILTER];
    } else {
      formState.filterDataParameters[END_DATE_FILTER] = new Date(
        endDate
      ).toISOString();
      if (
        formState.filterDataParameters.hasOwnProperty(START_DATE_FILTER) &&
        formState.filterDataParameters[END_DATE_FILTER] <
          formState.filterDataParameters[START_DATE_FILTER]
      ) {
        formState.errors["dateTo"] = [
          "End date cannot be less than start date"
        ];
      } else {
        delete formState.errors["dateFrom"];
        delete formState.errors["dateTo"];
      }
    }

    setFormState(formState => ({
      ...formState,
      endDate: event
    }));
  };

  const checkEmpty = obj => {
    return !Object.keys(obj).length ? true : false;
  };

  const handleFilterChangeForEventField = event => {
    setFormState(formState => ({
      ...formState,
      filterDataParameters: {
        ...formState.filterDataParameters,
        [EVENT_FILTER]: event.target.value
      }
    }));
    event.persist();
  };

  /** Search filter is called when we select filters and click on search button */
  const searchFilter = async (perPage = formState.pageSize, page = 1) => {
    if (!formUtilities.checkEmpty(formState.filterDataParameters)) {
      formState.isFilterSearch = true;
      await getEventData(perPage, page, formState.filterDataParameters);
    } else {
      await getEventData(perPage, page);
    }
  };

  const handleSort = (
    column,
    sortDirection,
    perPage = formState.pageSize,
    page = 1
  ) => {
    formState.filterDataParameters[SORT_FIELD_KEY] =
      column.selector + ":" + sortDirection;
    getEventData(perPage, page, formState.filterDataParameters);
  };

  const hasError = field => (formState.errors[field] ? true : false);

  /**Handle Closed model */
  const handleCloseFeedBackModal = (
    status,
    message,
    isModalClosedWithoutGivingFeedbach
  ) => {
    if (isModalClosedWithoutGivingFeedbach) {
      setFeedbackState(feedbackState => ({
        ...feedbackState,
        showAddEditModalFeedback: false,
        isGiveFeedback: false,
        isEditFeedback: false,
        isViewFeedback: false,
        showModalFeedback: false,
        EventTitle: null,
        eventId: null,
        feedBackGiven: false,
        fromFeedBackModal: false,
        successErrorMessage: ""
      }));
    } else {
      if (status) {
        setOpen(true);
        setFeedbackState(feedbackState => ({
          ...feedbackState,
          showAddEditModalFeedback: false,
          isGiveFeedback: false,
          isEditFeedback: false,
          isViewFeedback: false,
          showModalFeedback: false,
          EventTitle: null,
          eventId: null,
          feedBackGiven: true,
          fromFeedBackModal: true,
          successErrorMessage: message
        }));
        getEventData(
          formState.pageSize,
          formState.page,
          formState.filterDataParameters
        );
      } else {
        setFeedbackState(feedbackState => ({
          ...feedbackState,
          showAddEditModalFeedback: false,
          isGiveFeedback: false,
          isEditFeedback: false,
          isViewFeedback: false,
          showModalFeedback: false,
          EventTitle: null,
          eventId: null,
          feedBackGiven: false,
          fromFeedBackModal: true,
          successErrorMessage: message
        }));
      }
    }
  };

  const handleCloseModal = () => {
    setFeedbackState(feedbackState => ({
      ...feedbackState,
      showModalFeedback: false,
      showErrorModalFeedback: false,
      showAddEditModalFeedback: false,
      isGiveFeedback: false,
      isEditFeedback: false,
      isViewFeedback: false,
      feedBackGiven: false,
      fromFeedBackModal: false,
      dataFor: ""
    }));
  };

  /** Table Data */
  const column = [
    {
      name: "Name",
      sortable: true,
      selector: "title",
      cell: row => <ToolTipComponent data={row.title} />
    },
    {
      name: "Start Date",
      sortable: true,
      selector: "start_date_time",
      cell: row => <ToolTipComponent data={row.start_date_time} />
    },
    {
      name: "End Date",
      sortable: true,
      selector: "end_date_time",
      cell: row => <ToolTipComponent data={row.end_date_time} />
    },
    {
      name: "Actions",
      cell: cell => (
        <div className={classes.DisplayFlex}>
          {/** For RPC */}
          {auth.getUserInfo().role.name === roleConstants.RPCADMIN ||
          (auth.getUserInfo().role.name === roleConstants.COLLEGEADMIN &&
            auth.getUserInfo().studentInfo.organization.contact.id ===
              auth.getUserInfo().rpc.main_college) ? (
            cell.isFeedbackFromCollegePresent ? (
              <div className={classes.PaddingActionButton}>
                <FeedBack
                  message={"View college feedback"}
                  id={cell.id}
                  isViewFeedback={true}
                  value={cell.title}
                  onClick={() => viewFeedback(cell)}
                />
              </div>
            ) : !cell.question_set ? (
              <div className={classes.PaddingActionButton}>
                <FeedBack
                  feedbackNotAvailable={true}
                  message={"No question set with this event"}
                  id={cell.id}
                  isViewFeedback={true}
                  value={cell.title}
                  onClick={() => {}}
                />
              </div>
            ) : (
              <div className={classes.PaddingActionButton}>
                <FeedBack
                  feedbackNotAvailable={true}
                  message={"No college feedback available"}
                  id={cell.id}
                  isViewFeedback={true}
                  value={cell.title}
                  onClick={() => {}}
                />
              </div>
            )
          ) : null}

          {/** For Zone */}
          {auth.getUserInfo().role.name === roleConstants.ZONALADMIN ? (
            <React.Fragment>
              <div className={classes.PaddingActionButton}>
                <FeedBack
                  message={"View feedback"}
                  id={cell.id}
                  isViewFeedback={true}
                  value={cell.title}
                  onClick={() => viewCollegeFeedback(cell)}
                />
              </div>
            </React.Fragment>
          ) : null}

          {auth.getUserInfo().role.name === roleConstants.RPCADMIN ||
          auth.getUserInfo().role.name === roleConstants.ZONALADMIN ||
          (auth.getUserInfo().role.name === roleConstants.COLLEGEADMIN &&
            auth.getUserInfo().studentInfo.organization.contact.id ===
              auth.getUserInfo().rpc.main_college) ? (
            cell.giveFeedback ? (
              <div className={classes.PaddingActionButton}>
                <FeedBack
                  isGiveFeedback={true}
                  isEditFeedback={false}
                  cannotGiveFeedback={false}
                  id={cell.id}
                  value={cell.title}
                  onClick={() => giveFeedback(cell)}
                />
              </div>
            ) : cell.editFeedback ? (
              <div className={classes.PaddingActionButton}>
                <FeedBack
                  isGiveFeedback={false}
                  isEditFeedback={true}
                  cannotGiveFeedback={false}
                  id={cell.id}
                  value={cell.title}
                  onClick={() => editFeedback(cell)}
                />
              </div>
            ) : cell.cannotGiveFeedback ? (
              <div className={classes.PaddingActionButton}>
                <FeedBack
                  isGiveFeedback={false}
                  isEditFeedback={false}
                  cannotGiveFeedback={true}
                  isdisabled={true}
                  id={cell.id}
                  value={cell.title}
                  onClick={() => {}}
                />
              </div>
            ) : null
          ) : null}
        </div>
      ),
      width: "20%",
      cellStyle: {
        width: "auto",
        maxWidth: "auto"
      }
    }
  ];

  return (
    <Grid>
      <Grid item xs={12} className={classes.title}>
        <Typography variant="h4" gutterBottom>
          Event Feedback
        </Typography>
      </Grid>
      <Grid item xs={12} className={classes.formgrid}>
        {feedbackState.fromFeedBackModal && feedbackState.feedBackGiven ? (
          <Collapse in={open}>
            <Alert
              severity="success"
              action={
                <IconButton
                  aria-label="close"
                  color="inherit"
                  size="small"
                  onClick={() => {
                    setOpen(false);
                  }}
                >
                  <CloseIcon fontSize="inherit" />
                </IconButton>
              }
            >
              {feedbackState.successErrorMessage}
            </Alert>
          </Collapse>
        ) : null}

        {feedbackState.fromFeedBackModal && !feedbackState.feedBackGiven ? (
          <Collapse in={open}>
            <Alert
              severity="error"
              action={
                <IconButton
                  aria-label="close"
                  color="inherit"
                  size="small"
                  onClick={() => {
                    setOpen(false);
                  }}
                >
                  <CloseIcon fontSize="inherit" />
                </IconButton>
              }
            >
              {feedbackState.successErrorMessage}
            </Alert>
          </Collapse>
        ) : null}

        <Card>
          <CardContent className={classes.Cardtheming}>
            <Grid className={classes.filterOptions} container spacing={1}>
              <Grid item>
                <TextField
                  label="Name"
                  margin="normal"
                  variant="outlined"
                  value={formState.filterDataParameters[EVENT_FILTER] || ""}
                  placeholder="Name"
                  className={classes.autoCompleteField}
                  onChange={handleFilterChangeForEventField}
                />
              </Grid>
              <Grid item className={classes.paddingDate}>
                <InlineDatePicker
                  id="startDate"
                  label="Start Date"
                  placeholder="Start Date"
                  value={formState.startDate}
                  name={START_DATE_FILTER}
                  onChange={event =>
                    handleStartDateChange(START_DATE_FILTER, event)
                  }
                  error={hasError("dateFrom")}
                  helperText={
                    hasError("dateFrom")
                      ? formState.errors["dateFrom"].map(error => {
                          return error + " ";
                        })
                      : null
                  }
                />
              </Grid>
              <Grid item className={classes.paddingDate}>
                <InlineDatePicker
                  id="endDate"
                  label="End Date"
                  placeholder="End Date"
                  value={formState.endDate}
                  name={END_DATE_FILTER}
                  onChange={event =>
                    handleEndDateChange(END_DATE_FILTER, event)
                  }
                  error={hasError("dateTo")}
                  helperText={
                    hasError("dateTo")
                      ? formState.errors["dateTo"].map(error => {
                          return error + " ";
                        })
                      : null
                  }
                />
              </Grid>
              <Grid item className={classes.filterButtonsMargin}>
                <YellowButton
                  variant="contained"
                  color="primary"
                  disableElevation
                  disabled={checkEmpty(formState.errors) ? false : true}
                  onClick={event => {
                    event.persist();
                    searchFilter();
                  }}
                >
                  Search
                </YellowButton>
              </Grid>
              <Grid item className={classes.filterButtonsMargin}>
                <GrayButton
                  variant="contained"
                  color="primary"
                  onClick={clearFilter}
                  disableElevation
                >
                  Reset
                </GrayButton>
              </Grid>
            </Grid>
          </CardContent>
        </Card>
        <Card className={classes.tabledata} variant="outlined">
          {formState.dataToShow ? (
            formState.dataToShow.length ? (
              <Table
                data={formState.dataToShow}
                column={column}
                defaultSortField="title"
                defaultSortAsc={formState.sortAscending}
                paginationResetDefaultPage={formState.resetPagination}
                onSelectedRowsChange={handleRowSelected}
                onSort={handleSort}
                sortServer={true}
                paginationDefaultPage={formState.page}
                paginationPerPage={formState.pageSize}
                progressPending={formState.isDataLoading}
                paginationTotalRows={formState.totalRows}
                paginationRowsPerPageOptions={[10, 20, 50]}
                onChangeRowsPerPage={handlePerRowsChange}
                onChangePage={handlePageChange}
                clearSelectedRows={formState.toggleCleared}
              />
            ) : (
              <Spinner />
            )
          ) : (
            <div className={classes.noDataMargin}>No data to show</div>
          )}
          {/** Feedback modal calling */}
          {feedbackState.isViewFeedback ? (
            <ViewFeedBack
              showModal={feedbackState.showModalFeedback}
              modalClose={handleCloseModal}
              Title={feedbackState.EventTitle}
              id={feedbackState.eventId}
              fromEvent={true}
              fromActivity={false}
              fromRPC={
                auth.getUserInfo().role.name === roleConstants.RPCADMIN ||
                (auth.getUserInfo().role.name === roleConstants.COLLEGEADMIN &&
                  auth.getUserInfo().studentInfo.organization.contact.id ===
                    auth.getUserInfo().rpc.main_college)
                  ? true
                  : false
              }
              fromZone={
                auth.getUserInfo().role.name === roleConstants.ZONALADMIN
                  ? true
                  : false
              }
              result={feedbackState.result}
              dataFor={feedbackState.dataFor}
              dataToShow={feedbackState.ratings}
            />
          ) : null}
          {feedbackState.isGiveFeedback ? (
            <AddEditFeedBack
              isAddFeedback={true}
              showModal={feedbackState.showModalFeedback}
              modalClose={handleCloseFeedBackModal}
              Title={feedbackState.EventTitle}
              id={feedbackState.eventId}
              entityQuestionSet={feedbackState.entityQuestionSet}
              questionSetId={feedbackState.questionSetId}
              fromEvent={true}
              fromActivity={false}
              formMainCollege={
                auth.getUserInfo().role.name === roleConstants.COLLEGEADMIN &&
                auth.getUserInfo().studentInfo.organization.contact.id ===
                  auth.getUserInfo().rpc.main_college
                  ? true
                  : false
              }
            />
          ) : feedbackState.isEditFeedback ? (
            <AddEditFeedBack
              isEditFeedback={true}
              showModal={feedbackState.showModalFeedback}
              modalClose={handleCloseFeedBackModal}
              Title={feedbackState.EventTitle}
              id={feedbackState.eventId}
              entityQuestionSet={feedbackState.entityQuestionSet}
              questionSetId={feedbackState.questionSetId}
              feedbackSetId={feedbackState.feedbackSetId}
              fromEvent={true}
              fromActivity={false}
              formMainCollege={
                auth.getUserInfo().role.name === roleConstants.COLLEGEADMIN &&
                auth.getUserInfo().studentInfo.organization.contact.id ===
                  auth.getUserInfo().rpc.main_college
                  ? true
                  : false
              }
            />
          ) : null}
          {!feedbackState.isGiveFeedback &&
          !feedbackState.isEditFeedback &&
          !feedbackState.showModalFeedback &&
          feedbackState.showErrorModalFeedback ? (
            <NoFeedback
              showModal={feedbackState.showErrorModalFeedback}
              modalClose={handleCloseModal}
              Title={feedbackState.EventTitle}
              errorHeading={"View Feedback"}
              errorMessage={feedbackState.errorMessage}
            />
          ) : null}
        </Card>
      </Grid>
    </Grid>
  );
}
Example #19
Source File: index.js    From yasn with MIT License 4 votes vote down vote up
export default function PostCard(props) {
  const classes = useStyles();
  const [expanded, setExpanded] = useState(false);
  const [selected, setSelected] = useState(false);
  const [likeCount, setLikeCount] = useState(props.likes.likers.length);
  const comments = props.comments;

  const handleExpandClick = () => {
    setExpanded(!expanded);
  };

  useEffect(() => {
    if (cookies.get('userDetails')) {
      name = cookies.get('userDetails').name;
      userId = cookies.get('userDetails')._id;
      username = cookies.get('userDetails').username;
    }
    if (props.likes.likers.find((e) => e === userId)) setSelected(true);
  }, []);

  const handleLike = (selected) => {
    let liked = !selected;

    axios
      .post(
        `${ConnectServerUrl}/handlelike?` +
          queryString.stringify({ _id: props._id, email, googleToken }),
        {
          currentUserId: cookies.get('userDetails')._id,
          email,
          liked,
          //liked is true if user like , false if unliked ;
        }
      )
      .then((res) => console.log(res))
      .catch((err) => console.log(err));
  };

  return (
    <Card className={classes.root + " card"}>
      <CardHeader
        avatar={
          <Link to={`/user/${props.creator.username}`}>
            <Avatar aria-label="recipe" className={classes.avatar}>
              {props.creator
                ? props.creator.name
                  ? props.creator.name[0]
                  : // + props.creator.name.split(" ")[1][0]
                    props.Name[0]
                : // + props.Name.split(" ")[1][0]
                props.Name
                ? props.Name
                : 'X'}
            </Avatar>
          </Link>
        }
        action={
          <IconButton aria-label="settings">
            <MoreVertIcon />
          </IconButton>
        }
        title={props.title}
        subheader={
          <Moment format="MMM D, YYYY" withTitle>
            {props.date}
          </Moment>
        }
      />
      {props.imageUrl ? (
        <>
          <CardMedia
            className={classes.media}
            image={
              `https://res.cloudinary.com/${CloudName}/image/upload/c_crop,g_custom/v1/` +
              props.imageUrl
            }
            title="AcadVault"
          />
        </>
      ) : (
        <>
          <video width="300" height="200" controls>
            <source
              type="video/mp4"
              data-reactid=".0.1.0.0.0"
              src={
                `https://res.cloudinary.com/${CloudName}/video/upload/q_auto/v1588194153/` +
                props.videoUrl
              }
            ></source>
          </video>
        </>
      )}

      <CardContent>
        <Typography
          className="desc"
          variant="body2"
          color="textSecondary"
          component="p"
        >
          <Linkify properties={{ target: '_blank' }}>
            {props.description ? props.description : ''}
          </Linkify>
        </Typography>
      </CardContent>
      <CardActions disableSpacing>
        <Box alignItems="center" display={'flex'}>
            <IconButton
              style= {{paddingRight:0}}
              onClick={() => {
                handleLike(selected);
                selected
                  ? setLikeCount(likeCount - 1)
                  : setLikeCount(likeCount + 1);
                setSelected(!selected);
              }}
            >
              {selected ? (
                <FavoriteIcon color="secondary" />
              ) : (
                <FavoriteIcon />
              )}
            </IconButton>
          <Box l={3} p={1} b={4}>
            <Typography style={{ fontSize: '1.15rem' }}>
              {likeCount}
            </Typography>
          </Box>
          <Box display={'flex'}>
            <IconButton aria-label="share">
              <CommentIcon />
            </IconButton>
            <Typography style={{ fontSize: '1.15rem', marginTop: '.5rem' }}>
              {' '}
              {props.comments.length}
            </Typography>
          </Box>
        </Box>
        <IconButton
          className={clsx(classes.expand, {
            [classes.expandOpen]: expanded,
          })}
          onClick={handleExpandClick}
          aria-expanded={expanded}
          aria-label="show more"
        >
          <ExpandMoreIcon />
        </IconButton>
      </CardActions>
      <Collapse in={expanded} timeout="auto" unmountOnExit>
      <Divider/>
        <CardContent>
          
          <Typography variant="h6" className={classes.title}>
            Comments
          </Typography>
          <AddComment
            name={name}
            postId={props._id}
            userId={userId}
            username={username}
          />

          {comments
            ? comments.map((comment) => (
                <Comment
                  {...comment}
                  key={comment.date}
                  // onClick={handleComments}
                />
              ))
            : null}
        </CardContent>
      </Collapse>
    </Card>
  );
}
Example #20
Source File: SurveyPageView.jsx    From defizap-frontend with GNU General Public License v2.0 4 votes vote down vote up
SurveyPageView = props => {
  const {
    onAnswer,
    surveyList,
    reDoSurvey,
    isLoading,
    surveyComplete,
    submitResults,
    recommendedZaps,
    activeStep,
    moveToStep,
    answers,
    isResultsDisabled,
    stats
  } = props;

  const getZap = () => {
    return (
      <>
        <br /> <br />
        <h4>
          You might find these Zaps useful: <br />
        </h4>
        <Row className="justify-content-center">
          {recommendedZaps.map(zap => {
            if (stats)
              stats.forEach(stat => {
                if (zaps[zap].name === stat.name) zaps[zap].stats = stat;
              });
            return <Zap key={zaps[zap].name} {...zaps[zap]} />;
          })}
        </Row>
        <br />
        <Row className="justify-content-center pb-3">
          <Button
            variant="info"
            target="_blank"
            size="lg"
            href="https://defizap.typeform.com/to/UZSZg5"
            type="link"
            className="m-3"
            block
            onClick={() =>
              registerEvent({
                category: GENERATE_ZAP,
                action: SURVEY_PAGE
              })
            }
          >
            Don&apos;t see your Zap? Submit a request and we will create one!
          </Button>
        </Row>
        <Row>
          <h5 style={{ fontSize: 15 }} className="mx-3">
            DISCLOSURE:
            <p>
              Please note that DeFiZap is an experimental project. DeFiZap is
              not providing any investment advisory or recommendation service.
              By using DeFiZap or its services, you agree that you are using the
              Services at your own risk and that you will not and do not hold
              DeFiZap or its team members liable should the services not perform
              as per your expectation.
            </p>
            <p>
              DeFiZap is not a licensed financial advisor under any law. Please
              consult your own independent investment advisor before making any
              investment decisions.
            </p>
          </h5>
        </Row>
      </>
    );
  };

  const generateResult = () => {
    return (
      <>
        <Button
          variant="outline-primary"
          onClick={reDoSurvey}
          className="mx-1 my-3 px-1"
          size="lg"
        >
          Start Over
        </Button>
        <Button
          disabled={isResultsDisabled}
          variant="primary"
          onClick={submitResults}
          className="mx-3 my-3 px-3"
          size="lg"
        >
          Get Results
        </Button>
        {isLoading ? (
          <>
            <Spinner animation="grow" />
            <Spinner animation="grow" />
          </>
        ) : null}
      </>
    );
  };

  const surveySteps = () => {
    return (
      <Collapse in={!surveyComplete}>
        <Stepper
          activeStep={activeStep}
          nonLinear
          orientation="vertical"
          style={{ backgroundColor: 'inherit' }}
        >
          {surveyList.map(question => {
            return (
              <Step
                key={question.questionNumber}
                completed={!isEmpty(answers[question.questionNumber])}
              >
                <StepLabel onClick={() => moveToStep(question.questionNumber)}>
                  <h5>{question.question}</h5>
                  <p className="text-monospace text-uppercase">
                    {answers[question.questionNumber]}
                  </p>
                </StepLabel>
                <StepContent>
                  {question.options.map(option => {
                    return (
                      <Button
                        key={option.value}
                        variant="outline-primary"
                        size="auto"
                        onClick={() => onAnswer(option.key)}
                        className="shadow"
                        block
                      >
                        {option.value}
                      </Button>
                    );
                  })}
                </StepContent>
              </Step>
            );
          })}
        </Stepper>
      </Collapse>
    );
  };

  return (
    <Container>
      <NavigationBar />
      <h4>
        Answer a few multiple choice questions to see which Zap might fit your
        needs
      </h4>
      {surveySteps()}
      {activeStep === 4 ? generateResult() : null}
      {surveyComplete ? getZap() : null}
    </Container>
  );
}
Example #21
Source File: Comment.jsx    From archeage-tools with The Unlicense 4 votes vote down vote up
render() {
    const {
      id,
      postId,
      body,
      author,
      createDate,
      editDate,
      replies,
      deleted,
      depth,
      onUpdateComments,
      sortAsc,
    } = this.props;
    const { collapsed, reply, edit, deleteOpen } = this.state;
    const isEdited = (editDate && editDate !== createDate) && !deleted;

    return (
      <div className="paper-border no-border comment-box">
        <div className="collapsible-left">
          <Avatar user={author} size={0.875} />
          <Tooltip title={collapsed ? 'Expand' : 'Collapse'} placement="top">
            <div className="collapse sm" onClick={this.setCollapsed(!collapsed)} />
          </Tooltip>
        </div>
        <div className="collapsible-right">
          <div>
            <Username user={author} />
            <Tooltip title={new Date(createDate).toLocaleString(navigator.language || 'en-US')}>
              <Typography variant="caption" className="time">
                {moment(createDate).fromNow()}
              </Typography>
            </Tooltip>
            {isEdited &&
            <Tooltip title={new Date(editDate).toLocaleString(navigator.language || 'en-US')}>
              <Typography variant="caption" className="time edited">
                (edited {moment(editDate).fromNow()})
              </Typography>
            </Tooltip>}
          </div>
          <Collapse in={!collapsed}>
            {!edit
              ? <Viewer value={body} />
              : <EditComment
                {...this.props}
                onCancel={this.setEdit(false)}
              />}
            {!deleted &&
            <div className="small-buttons">
              <IfPerm permission="comment.create">
                <Button
                  startIcon={<ReplyIcon />}
                  onClick={this.setReply(true)}
                >
                  Reply
                </Button>
              </IfPerm>
              <IfPerm permission="comment.edit" orUserIs={author}>
                <Button
                  startIcon={<EditIcon />}
                  onClick={this.setEdit(true)}
                >
                  Edit
                </Button>
              </IfPerm>
              <IfPerm permission="comment.delete" orUserIs={author}>
                <Button
                  startIcon={<DeleteIcon />}
                  onClick={this.setDelete(true)}
                >
                  Delete
                </Button>
              </IfPerm>
            </div>}
            <Collapse in={reply} unmountOnExit>
              <EditComment
                postId={postId}
                onUpdateComments={onUpdateComments}
                onCancel={this.setReply(false)}
                depth={depth + 1}
                replyUser={author}
                reply={id}
              />
            </Collapse>
            {replies && replies.sort(sortBy('createDate', sortAsc)).map(reply => (
              <ConnectedComment
                {...reply}
                onUpdateComments={onUpdateComments}
                key={`comment-${reply.id}`}
                depth={depth + 1}
                sortAsc={sortAsc}
              />
            ))}
          </Collapse>
        </div>
        <Dialog
          open={deleteOpen}
          onClose={this.setDelete(false)}
        >
          <AppBar position="static">
            <Toolbar variant="dense">
              <Typography variant="subtitle1" className="title-text">Delete Comment</Typography>
              <Tooltip title="Close">
                <IconButton onClick={this.setDelete(false)}>
                  <CloseIcon />
                </IconButton>
              </Tooltip>
            </Toolbar>
          </AppBar>
          <DialogContent style={{ minHeight: 92 }}>
            <blockquote><Viewer value={body} /></blockquote>
            <Typography>Are you sure you want to delete this comment?</Typography>
          </DialogContent>
          <DialogActions>
            <Button onClick={this.setDelete(false)}>Cancel</Button>
            <Button color="primary" onClick={this.handleDelete}>Delete</Button>
          </DialogActions>
        </Dialog>
      </div>
    );
  }
Example #22
Source File: NavSection.js    From course-manager with MIT License 4 votes vote down vote up
function NavItem({ item, active }) {
  const theme = useTheme();
  const isActiveRoot = active(item.path);
  const { title, path, icon, info, children } = item;
  const [open, setOpen] = useState(isActiveRoot);

  const handleOpen = () => {
    setOpen((prev) => !prev);
  };

  const activeRootStyle = {
    color: 'primary.main',
    fontWeight: 'fontWeightMedium',
    bgcolor: alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity),
    '&:before': { display: 'block' }
  };

  const activeSubStyle = {
    color: 'text.primary',
    fontWeight: 'fontWeightMedium'
  };

  if (children) {
    return (
      <>
        <ListItemStyle
          onClick={handleOpen}
          sx={{
            ...(isActiveRoot && activeRootStyle)
          }}
        >
          <ListItemIconStyle>{icon && icon}</ListItemIconStyle>
          <ListItemText disableTypography primary={title} />
          {info && info}
          <Box
            component={Icon}
            icon={open ? arrowIosDownwardFill : arrowIosForwardFill}
            sx={{ width: 16, height: 16, ml: 1 }}
          />
        </ListItemStyle>

        <Collapse in={open} timeout="auto" unmountOnExit>
          <List component="div" disablePadding>
            {children.map((item) => {
              const { title, path } = item;
              const isActiveSub = active(path);

              return (
                <ListItemStyle
                  key={title}
                  component={RouterLink}
                  to={path}
                  sx={{
                    ...(isActiveSub && activeSubStyle)
                  }}
                >
                  <ListItemIconStyle>
                    <Box
                      component="span"
                      sx={{
                        width: 4,
                        height: 4,
                        display: 'flex',
                        borderRadius: '50%',
                        alignItems: 'center',
                        justifyContent: 'center',
                        bgcolor: 'text.disabled',
                        transition: (theme) => theme.transitions.create('transform'),
                        ...(isActiveSub && {
                          transform: 'scale(2)',
                          bgcolor: 'primary.main'
                        })
                      }}
                    />
                  </ListItemIconStyle>
                  <ListItemText disableTypography primary={title} />
                </ListItemStyle>
              );
            })}
          </List>
        </Collapse>
      </>
    );
  }

  return (
    <ListItemStyle
      component={RouterLink}
      to={path}
      sx={{
        ...(isActiveRoot && activeRootStyle)
      }}
    >
      <ListItemIconStyle>{icon && icon}</ListItemIconStyle>
      <ListItemText disableTypography primary={title} />
      {info && info}
    </ListItemStyle>
  );
}
Example #23
Source File: verticalCollapse.js    From x-admin-device-donation with MIT License 4 votes vote down vote up
function VerticalCollapse({ activePath, ...props }) {
  const [open, setOpen] = useState(() =>
    needsToBeOpened(window.location, props.item)
  );
  const { item, nestedLevel, publicity } = props;

  const classes = useStyles({
    itemPadding: nestedLevel > 0 ? 40 + nestedLevel * 16 : 24,
  });

  useEffect(() => {
    if (needsToBeOpened(window.location, item)) {
      setOpen(true);
    }
  }, [item]);

  function handleClick() {
    setOpen(!open);
  }

  return (
    <ul className={clsx(classes.root, open && "open")}>
      <ListItem
        button
        disableRipple
        style={{ color: "white", paddingTop: "0px", paddingBottom: "0px" }}
        className={clsx(classes.item, "list-item")}
        onClick={handleClick}
        component="li"
        to={`/${item.name}`}
        role="button"
      >
        {/* {item.icon && createElement(CustomIcons[item.icon])}      */}
        <ListItemText
          style={{ paddingLeft: "16px" }}
          primary={item.name}
          classes={{ primary: "text-14" }}
        />

        <IconButton
          disableRipple
          style={{ color: "white" }}
          className="w-40 h-40 p-0 focus:bg-transparent hover:bg-transparent"
          onClick={(ev) => ev.preventDefault()}
        >
          {createElement(!open ? KeyboardArrowDownIcon : KeyboardArrowUpIcon)}
        </IconButton>
      </ListItem>

      {item.children && (
        <Collapse
          in={open}
          className="collapse-children"
          style={{ marginLeft: "16px" }}
        >
          {item.children.map((i, index) => {
            if (i.children) {
              return (
                <VerticalCollapse
                  key={index}
                  activePath={activePath}
                  item={i}
                  publicity={publicity}
                  nestedLevel={props.nestedLevel + 1}
                  permissions={permissions}
                />
              );
            }
            return (
              <VerticalItem
                activePath={activePath}
                key={index}
                item={i}
                nestedLevel={props.nestedLevel + 1}
              />
            );
          })}
        </Collapse>
      )}
    </ul>
  );
}
Example #24
Source File: Sidebar.jsx    From Edlib with GNU General Public License v3.0 4 votes vote down vote up
Sidebar = () => {
    const classes = useStyles();
    const history = useHistory();
    const location = useLocation();
    const [currentlyExpandedName, setCurrentlyExpandedName] =
        React.useState(null);

    React.useEffect(() => {
        setCurrentlyExpandedName(null);
    }, [location]);

    const links = [
        { name: 'Dashboard', to: '/dashboard', icon: <Dashboard /> },
        { name: 'Content Author', to: '/content-author', icon: <Settings /> },
        {
            name: 'Settings',
            to: '/settings',
            icon: <Settings />,
            subLinks: [
                {
                    name: 'External applications',
                    to: '/external-applications',
                },
            ],
        },
        {
            name: 'Monitoring',
            to: '/monitoring',
            icon: <LocalOffer />,
            subLinks: [{ name: 'Status of services', to: '/system-status' }],
        },
        {
            name: 'Jobs',
            to: '/jobs',
            icon: <LocalOffer />,
            subLinks: [
                { name: 'Resources', to: '/resources' },
                { name: 'Auth migration', to: '/auth-migration' },
            ],
        },
        {
            name: 'Analytics',
            to: '/analytics',
            icon: <Assessment />,
            subLinks: [{ name: 'Dashboard', to: '/dashboard' }],
        },
    ];

    return (
        <List dense>
            {links.map(({ name, icon, to, subLinks }) => {
                const isInPath = !!matchPath(location.pathname, {
                    path: to,
                    strict: false,
                });

                const isExpanded = isInPath || currentlyExpandedName === name;

                if (subLinks) {
                    return (
                        <React.Fragment key={name}>
                            <ListItem
                                button
                                selected={isInPath}
                                onClick={() => {
                                    setCurrentlyExpandedName(
                                        currentlyExpandedName === name
                                            ? null
                                            : name
                                    );
                                }}
                            >
                                {icon && <ListItemIcon>{icon}</ListItemIcon>}
                                <ListItemText
                                    primary={name}
                                    primaryTypographyProps={{
                                        className: classes.parentItem,
                                    }}
                                    inset={!icon}
                                />
                                {isExpanded ? <ExpandLess /> : <ExpandMore />}
                            </ListItem>
                            <Collapse
                                in={isExpanded}
                                timeout="auto"
                                unmountOnExit
                            >
                                <List component="div" disablePadding dense>
                                    {subLinks.map((subLink) => {
                                        const subTo = to + subLink.to;
                                        const isInSubPath = !!matchPath(
                                            location.pathname,
                                            {
                                                path: subTo,
                                                strict: false,
                                            }
                                        );

                                        return (
                                            <ListItem
                                                key={subLink.name}
                                                button
                                                onClick={() =>
                                                    history.push(subTo)
                                                }
                                                selected={isInSubPath}
                                            >
                                                <ListItemText
                                                    primary={subLink.name}
                                                    inset
                                                />
                                            </ListItem>
                                        );
                                    })}
                                </List>
                            </Collapse>
                        </React.Fragment>
                    );
                }

                return (
                    <ListItem
                        key={name}
                        button
                        selected={isInPath}
                        onClick={() => history.push(to)}
                    >
                        {icon && <ListItemIcon>{icon}</ListItemIcon>}
                        <ListItemText
                            primary={name}
                            primaryTypographyProps={{
                                className: classes.parentItem,
                            }}
                            inset={!icon}
                        />
                    </ListItem>
                );
            })}
        </List>
    );
}
Example #25
Source File: ComponentSidebar.js    From eSim-Cloud with GNU General Public License v3.0 4 votes vote down vote up
export default function ComponentSidebar ({ compRef, ltiSimResult, setLtiSimResult }) {
  const classes = useStyles()
  const libraries = useSelector(state => state.schematicEditorReducer.libraries)
  const collapse = useSelector(state => state.schematicEditorReducer.collapse)
  const components = useSelector(state => state.schematicEditorReducer.components)
  const isSimulate = useSelector(state => state.schematicEditorReducer.isSimulate)
  const auth = useSelector(state => state.authReducer)

  const dispatch = useDispatch()
  const [isSearchedResultsEmpty, setIssearchedResultsEmpty] = useState(false)
  const [searchText, setSearchText] = useState('')
  const [loading, setLoading] = useState(false)
  const [favourite, setFavourite] = useState(null)
  const [favOpen, setFavOpen] = useState(false)

  const [searchedComponentList, setSearchedComponents] = useState([])
  const [searchOption, setSearchOption] = useState('NAME')
  const [uploaded, setuploaded] = useState(false)
  const [def, setdef] = useState(false)
  const [additional, setadditional] = useState(false)

  // const searchedComponentList = React.useRef([])

  const timeoutId = React.useRef()

  const handleSearchOptionType = (evt) => {
    setSearchedComponents([])
    setSearchOption(evt.target.value)
  }

  const handleSearchText = (evt) => {
    // tempSearchTxt = evt.target.value
    if (searchText.length === 0) {
      setSearchedComponents([])
    }
    setSearchText(evt.target.value)
    setSearchedComponents([])
    // mimic the value so we can access the latest value in our API call.

    // call api from here. and set the result to searchedComponentList.
  }

  React.useEffect(() => {
    if (auth.isAuthenticated) {
      const token = localStorage.getItem('esim_token')
      const config = {
        headers: {
          'Content-Type': 'application/json'
        }
      }
      if (token) {
        config.headers.Authorization = `Token ${token}`
      }
      api
        .get('favouritecomponents', config)
        .then((resp) => {
          setFavourite(resp.data.component)
        })
        .catch((err) => {
          console.log(err)
        })
    }
  }, [auth])

  React.useEffect(() => {
    // if the user keeps typing, stop the API call!
    clearTimeout(timeoutId.current)
    // don't make an API call with no data
    if (!searchText.trim()) return
    // capture the timeoutId so we can
    // stop the call if the user keeps typing
    timeoutId.current = setTimeout(() => {
      // call api here
      setLoading(true)
      let config = {}
      const token = localStorage.getItem('esim_token')
      if (token && token !== undefined) {
        config = {
          headers: {
            Authorization: `Token ${token}`
          }
        }
      }
      api.get(`components/?${searchOptions[searchOption]}=${searchText}`, config)
        .then(
          (res) => {
            if (res.data.length === 0) {
              setIssearchedResultsEmpty(true)
            } else {
              setIssearchedResultsEmpty(false)
              setSearchedComponents([...res.data])
            }
          }
        )
        .catch((err) => { console.error(err) })
      setLoading(false)
    }, 800)
  }, [searchText, searchOption])

  const handleCollapse = (id) => {
    // Fetches Components for given library if not already fetched
    if (collapse[id] === false && components[id].length === 0) {
      dispatch(fetchComponents(id))
    }

    // Updates state of collapse to show/hide dropdown
    dispatch(toggleCollapse(id))
  }

  // For Fetching Libraries
  useEffect(() => {
    dispatch(fetchLibraries())
  }, [dispatch])

  useEffect(() => {
    if (libraries.filter((ob) => { return ob.default === true }).length !== 0) { setdef(true) } else { setdef(false) }
    if (libraries.filter((ob) => { return ob.additional === true }).length !== 0) { setadditional(true) } else { setadditional(false) }
    if (libraries.filter((ob) => { return (!ob.additional && !ob.default) }).length !== 0) { setuploaded(true) } else { setuploaded(false) }
  }, [libraries])

  // Used to chunk array
  const chunk = (array, size) => {
    return array.reduce((chunks, item, i) => {
      if (i % size === 0) {
        chunks.push([item])
      } else {
        chunks[chunks.length - 1].push(item)
      }
      return chunks
    }, [])
  }

  const libraryDropDown = (library) => {
    return (
      <div key={library.id}>
        <ListItem onClick={(e, id = library.id) => handleCollapse(id)} button divider>
          <span className={classes.head}>{library.library_name.slice(0, -4)}</span>
          {collapse[library.id] ? <ExpandLess /> : <ExpandMore />}
        </ListItem>
        <Collapse in={collapse[library.id]} timeout={'auto'} unmountOnExit mountOnEnter exit={false}>
          <List component="div" disablePadding dense >
            {/* Chunked Components of Library */}
            {chunk(components[library.id], COMPONENTS_PER_ROW).map((componentChunk) => {
              return (
                <ListItem key={componentChunk[0].svg_path} divider>
                  {componentChunk.map((component) => {
                    return (
                      <ListItemIcon key={component.full_name}>
                        <SideComp component={component} setFavourite={setFavourite} favourite={favourite} />
                      </ListItemIcon>
                    )
                  })}
                </ListItem>
              )
            })}
          </List>
        </Collapse>
      </div>
    )
  }

  const handleFavOpen = () => {
    setFavOpen(!favOpen)
  }

  return (
    <>
      <Hidden smDown>
        <div className={classes.toolbar} />
      </Hidden>

      <div style={isSimulate ? { display: 'none' } : {}}>
        {/* Display List of categorized components */}
        <List>
          <ListItem button>
            <h2 style={{ margin: '5px' }}>Components List</h2>
          </ListItem>
          <ListItem>

            <TextField
              id="standard-number"
              placeholder="Search Component"
              variant="outlined"
              size="small"
              value={searchText}
              onChange={handleSearchText}
              InputProps={{
                startAdornment: (
                  <InputAdornment position="start">
                    <SearchIcon />
                  </InputAdornment>
                )
              }}
            />

          </ListItem>

          <ListItem divider>
            <TextField
              style={{ width: '100%' }}
              id="searchType"
              size='small'
              variant="outlined"
              select
              label="Search By"
              value={searchOption}
              onChange={handleSearchOptionType}
              SelectProps={{
                native: true
              }}
            >

              {
                searchOptionsList.map((value, i) => {
                  return (<option key={i} value={value}>
                    {value}
                  </option>)
                })
              }

            </TextField>
          </ListItem>
          <div style={{ maxHeight: '70vh', overflowY: 'auto', overflowX: 'hidden' }} >
            {searchText.length !== 0 && searchedComponentList.length !== 0 &&

              searchedComponentList.map((component, i) => {
                return (<ListItemIcon key={i}>
                  <SideComp component={component} />
                </ListItemIcon>)
              }
              )

            }

            <ListItem>

              <Loader
                type="TailSpin"
                color="#F44336"
                height={100}
                width={100}
                visible={loading}
              />
            </ListItem>

            {!loading && searchText.length !== 0 && isSearchedResultsEmpty &&

              <span style={{ margin: '20px' }}>No Components Found</span>

            }

            {/* Collapsing List Mapped by Libraries fetched by the API */}
            {favourite && favourite.length > 0 &&
              <>
                <ListItem button onClick={handleFavOpen} divider>
                  <span className={classes.head}>Favourite Components</span>
                  <div>
                    {favOpen ? <ExpandLess /> : <ExpandMore />}
                  </div>
                </ListItem>
                <Collapse in={favOpen} timeout="auto" unmountOnExit>
                  <List component="div" disablePadding>
                    <ListItem>
                      <div style={{ marginLeft: '-30px' }}>
                        {chunk(favourite, 3).map((componentChunk) => {
                          return (
                            <div key={componentChunk[0].svg_path}>
                              <ListItem key={componentChunk[0].svg_path} divider>
                                {
                                  componentChunk.map((component) => {
                                    return (
                                      <ListItemIcon key={component.full_name}>
                                        <SideComp isFavourite={true} favourite={favourite} setFavourite={setFavourite} component={component} />
                                      </ListItemIcon>
                                    )
                                  }
                                  )
                                }
                              </ListItem>
                            </div>
                          )
                        })}
                      </div>
                    </ListItem>
                  </List>
                </Collapse>
              </>
            }
            {searchText.length === 0 &&
            <>
              <div style={!def ? { display: 'none' } : {}}>
                <Divider />
                <ListItem dense divider style={{ backgroundColor: '#e8e8e8' }}>
                  <span>DEFAULT</span>
                </ListItem>
                <Divider />
                { libraries.sort(function (a, b) {
                  const textA = a.library_name.toUpperCase()
                  const textB = b.library_name.toUpperCase()
                  return (textA < textB) ? -1 : (textA > textB) ? 1 : 0
                }).filter((library) => {
                  if (library.default) { return 1 }
                  return 0
                }).map(
                  (library) => {
                    return (libraryDropDown(library))
                  }
                )}
              </div>
              <div style={!additional ? { display: 'none' } : {}}>
                <ListItem dense divider style={{ backgroundColor: '#e8e8e8' }}>
                  <span className={classes.head}>ADDITIONAL</span>
                </ListItem>
                { libraries.sort(function (a, b) {
                  const textA = a.library_name.toUpperCase()
                  const textB = b.library_name.toUpperCase()
                  return (textA < textB) ? -1 : (textA > textB) ? 1 : 0
                }).filter((library) => {
                  if (library.additional) { return 1 }
                  return 0
                }).map(
                  (library) => {
                    return (libraryDropDown(library))
                  }
                )}
              </div>
              <div style={!uploaded ? { display: 'none' } : {}}>
                <ListItem dense divider style={{ backgroundColor: '#e8e8e8' }}>
                  <span className={classes.head}>UPLOADED</span>
                </ListItem>
                { libraries.sort(function (a, b) {
                  const textA = a.library_name.toUpperCase()
                  const textB = b.library_name.toUpperCase()
                  return (textA < textB) ? -1 : (textA > textB) ? 1 : 0
                }).filter((library) => {
                  if (!library.default && !library.additional) { return 1 }
                  return 0
                }).map(
                  (library) => {
                    return (libraryDropDown(library))
                  }
                )}
              </div>
            </>
            }
          </div>
        </List>
      </div>
      <div style={isSimulate ? {} : { display: 'none' }}>
        {/* Display simulation modes parameters on left side pane */}
        <List>
          <ListItem button divider>
            <h2 style={{ margin: '5px auto 5px 5px' }}>Simulation Modes</h2>
            <Tooltip title="close">
              <IconButton color="inherit" className={classes.tools} size="small" onClick={() => { dispatch(toggleSimulate()) }}>
                <CloseIcon fontSize="small" />
              </IconButton>
            </Tooltip>
          </ListItem>
          <SimulationProperties ltiSimResult={ltiSimResult} setLtiSimResult={setLtiSimResult} />
        </List>
      </div>
    </>
  )
}
Example #26
Source File: ViewActivityBatches.js    From medha-STPC with GNU Affero General Public License v3.0 4 votes vote down vote up
ViewActivityBatches = props => {
  const [open, setOpen] = React.useState(true);
  const classes = useStyles();
  let history = useHistory();

  const [formState, setFormState] = useState({
    dataToShow: [],
    batches: [],
    batchesFilter: [],
    filterDataParameters: {},
    isFilterSearch: false,
    /** This is when we return from edit page */
    isDataEdited: props["location"]["fromEditActivityBatch"]
      ? props["location"]["isDataEdited"]
      : false,
    editedData: props["location"]["fromEditActivityBatch"]
      ? props["location"]["editedData"]
      : {},
    fromEditActivityBatch: props["location"]["fromEditActivityBatch"]
      ? props["location"]["fromEditActivityBatch"]
      : false,
    /** This is when we return from add page */
    isDataAdded: props["location"]["fromAddActivityBatch"]
      ? props["location"]["isDataAdded"]
      : false,
    addedData: props["location"]["fromAddActivityBatch"]
      ? props["location"]["addedData"]
      : {},
    fromAddActivityBatch: props["location"]["fromAddActivityBatch"]
      ? props["location"]["fromAddActivityBatch"]
      : false,
    /** This is for delete */
    isDataDeleted: false,
    dataToEdit: {},
    dataToDelete: {},
    showModalDelete: false,
    /** Pagination and sortinig data */
    isDataLoading: false,
    pageSize: "",
    totalRows: "",
    page: "",
    pageCount: "",
    sortAscending: true,
    isActivityExist: true
  });

  const { activity } = props.match.params;
  const [activityDetails, setActivityDetails] = useState(null);

  const ACTIVITY_URL =
    strapiConstants.STRAPI_DB_URL +
    strapiConstants.STRAPI_ACTIVITY +
    `/${activity}`;

  const ACTIVITY_BATCH_URL =
    strapiConstants.STRAPI_DB_URL +
    strapiConstants.STRAPI_INDIVIDUAL_ACTIVITY +
    `/${activity}/` +
    strapiConstants.STRAPI_ACTIVITIES_BATCHES_URL;

  useEffect(() => {
    serviceProviders
      .serviceProviderForGetRequest(ACTIVITY_URL)
      .then(({ data }) => {
        if (data.result == null) {
          history.push("/404");
        } else {
          setActivityDetails(data.result);
        }
      })
      .catch(() => {
        history.push("/404");
      });
  }, []);

  useEffect(() => {
    serviceProviders
      .serviceProviderForGetRequest(ACTIVITY_BATCH_URL)
      .then(res => {
        setFormState(formState => ({
          ...formState,
          batchesFilter: res.data.result
        }));
      })
      .catch(error => {
        console.log("error", error);
      });

    getActivityBatches(10, 1);
  }, []);

  const [alert, setAlert] = useState({
    isOpen: false,
    message: "",
    severity: ""
  });

  /** This seperate function is used to get the Activity Batches data*/
  const getActivityBatches = async (pageSize, page, params = null) => {
    if (params !== null && !formUtilities.checkEmpty(params)) {
      let defaultParams = {
        page: page,
        pageSize: pageSize
      };
      Object.keys(params).map(key => {
        return (defaultParams[key] = params[key]);
      });
      params = defaultParams;
    } else {
      params = {
        page: page,
        pageSize: pageSize
      };
    }
    setFormState(formState => ({
      ...formState,
      isDataLoading: true
    }));
    await serviceProviders
      .serviceProviderForGetRequest(ACTIVITY_BATCH_URL, params)
      .then(res => {
        formState.dataToShow = [];
        setFormState(formState => ({
          ...formState,
          batches: res.data.result,
          dataToShow: res.data.result,
          pageSize: res.data.pageSize,
          totalRows: res.data.rowCount,
          page: res.data.page,
          pageCount: res.data.pageCount,
          isDataLoading: false
        }));
      })
      .catch(error => {
        console.log("error", error);
      });
  };

  /** Pagination */
  const handlePerRowsChange = async (perPage, page) => {
    /** If we change the now of rows per page with filters supplied then the filter should by default be applied*/
    if (formUtilities.checkEmpty(formState.filterDataParameters)) {
      await getActivityBatches(perPage, page);
    } else {
      if (formState.isFilterSearch) {
        await searchFilter(perPage, page);
      } else {
        await getActivityBatches(perPage, page);
      }
    }
  };

  const handlePageChange = async page => {
    if (formUtilities.checkEmpty(formState.filterDataParameters)) {
      await getActivityBatches(formState.pageSize, page);
    } else {
      if (formState.isFilterSearch) {
        await searchFilter(formState.pageSize, page);
      } else {
        await getActivityBatches(formState.pageSize, page);
      }
    }
  };

  /** Search filter is called when we select filters and click on search button */
  const searchFilter = async (perPage = formState.pageSize, page = 1) => {
    if (!formUtilities.checkEmpty(formState.filterDataParameters)) {
      formState.isFilterSearch = true;
      await getActivityBatches(perPage, page, formState.filterDataParameters);
    }
  };

  const clearFilter = () => {
    setFormState(formState => ({
      ...formState,
      isFilterSearch: false,
      /** Clear all filters */
      filterDataParameters: {},
      /** Turns on the spinner */
      isDataLoading: true
    }));
    /**Need to confirm this thing for resetting the data */
    restoreData();
  };

  const restoreData = () => {
    getActivityBatches(formState.pageSize, 1);
  };

  /**
   * Redirect to Activity batch UI for given activity
   */
  const handleEditActivityBatch = activityBatch => {
    const url = `/edit-activity-batch/${activity}`;
    history.push({
      pathname: url,
      editActivityBatch: true,
      dataForEdit: activityBatch
    });
  };

  const handleCloseDeleteModal = () => {
    /** This restores all the data when we close the modal */
    setFormState(formState => ({
      ...formState,
      isDataDeleted: false,
      showModalDelete: false
    }));
    if (formState.isDataDeleted) {
      getActivityBatches(formState.pageSize, formState.page);
    } else {
    }
  };
  const isDeleteCellCompleted = (status, activityBatch) => {
    formState.isDataDeleted = status;
    if (status === true) {
      setAlert(() => ({
        isOpen: true,
        message: `Activity Batch ${activityBatch.name} Deleted Successfully`,
        severity: "success"
      }));
    } else if (status === false) {
      setAlert(() => ({
        isOpen: true,
        message: activityBatch.response.data.message,
        severity: "error"
      }));
    }
  };

  const handleDeleteActivityBatch = activityBatch => {
    setFormState(formState => ({
      ...formState,
      dataToDelete: { ...activityBatch },
      showModalDelete: true
    }));
  };

  // const handleDeleteActivityBatch = activityBatch => {
  //   const url =
  //     strapiConstants.STRAPI_DB_URL + strapiConstants.STRAPI_ACTIVITY_BATCH_URL;
  //   const activityBatchId = activityBatch.id;
  //   serviceProviders
  //     .serviceProviderForDeleteRequest(url, activityBatchId)
  //     .then(() => {
  //       setAlert(() => ({
  //         isOpen: true,
  //         message: `Batch ${activityBatch.name} deleted successfully`,
  //         severity: "success"
  //       }));
  //       getActivityBatches(10, 1);
  //     })
  //     .catch(({ response }) => {
  //       setAlert(() => ({
  //         isOpen: true,
  //         message: response.data.message,
  //         severity: "error"
  //       }));
  //     });
  // };

  const handleFilterChange = event => {
    setFormState(formState => ({
      ...formState,
      filterDataParameters: {
        ...formState.filterDataParameters,
        [ACTIVITY_BATCH_FILTER]: event.target.value
      }
    }));
    event.persist();
  };
  /** Columns to show in table */
  const column = [
    { name: "Batch", sortable: true, selector: "name" },
    { name: "Activity", sortable: true, selector: "activity.title" },
    {
      cell: cell => (
        <div className={classes.DisplayFlex}>
          <div className={classes.PaddingFirstActionButton}>
            <EditGridIcon
              id={cell.id}
              value={cell.name}
              onClick={() => {
                handleEditActivityBatch(cell);
              }}
              title="Manage Batch"
            />
          </div>
          <div className={classes.PaddingActionButton}>
            <DeleteGridIcon
              id={cell.id}
              value={cell.title}
              onClick={() => handleDeleteActivityBatch(cell)}
            />
          </div>
        </div>
      ),
      button: true,
      conditionalCellStyles: [],
      width: "200px"
    }
  ];

  const handleAddActivityClick = () => {
    const addActivityBatchURL = `/add-activity-batch/${activity}`;
    history.push({
      pathname: addActivityBatchURL,
      editActivityBatch: false,
      dataForEdit: null
    });
  };

  const breadcrumbs = [
    { title: "Activity", href: "/manage-activity" },
    {
      title: `${activityDetails ? activityDetails.title : ""} Batches`,
      href: "/"
    }
  ];

  const AlertAPIResponseMessage = () => {
    return (
      <Collapse in={alert.isOpen}>
        <Alert
          severity={alert.severity || "warning"}
          action={
            <IconButton
              aria-label="close"
              color="inherit"
              size="small"
              onClick={() => {
                setAlert(() => ({ isOpen: false }));
              }}
            >
              <CloseIcon fontSize="inherit" />
            </IconButton>
          }
        >
          {alert.message}
        </Alert>
      </Collapse>
    );
  };

  return (
    <Grid>
      <div className={classes.breadCrumbs}>
        {activityDetails ? <Breadcrumbs list={breadcrumbs} /> : null}
      </div>
      <Grid
        container
        spacing={3}
        justify="space-between"
        className={classes.title}
      >
        <Grid item>
          <Typography variant="h4" gutterBottom>
            {`${activityDetails ? activityDetails.title : ""} batches`}
          </Typography>
        </Grid>
        <Grid item>
          <GreenButton
            variant="contained"
            color="primary"
            onClick={handleAddActivityClick}
            disableElevation
            to={`/add-activity-batch/${activity}`}
            startIcon={<AddCircleOutlineOutlinedIcon />}
          >
            {genericConstants.ADD_ACTIVITY_BATCHES}
          </GreenButton>
        </Grid>
      </Grid>

      <Grid item xs={12} className={classes.formgrid}>
        {/** Error/Success messages to be shown for edit */}
        {formState.fromEditActivityBatch && formState.isDataEdited ? (
          <Collapse in={open}>
            <Alert
              severity="success"
              action={
                <IconButton
                  aria-label="close"
                  color="inherit"
                  size="small"
                  onClick={() => {
                    setOpen(false);
                  }}
                >
                  <CloseIcon fontSize="inherit" />
                </IconButton>
              }
            >
              Batch
              {formState.editedData ? ` ${formState.editedData.name} ` : " "}
              has been updated successfully.
            </Alert>
          </Collapse>
        ) : null}
        {formState.fromEditActivityBatch && !formState.isDataEdited ? (
          <Collapse in={open}>
            <Alert
              severity="error"
              action={
                <IconButton
                  aria-label="close"
                  color="inherit"
                  size="small"
                  onClick={() => {
                    setOpen(false);
                  }}
                >
                  <CloseIcon fontSize="inherit" />
                </IconButton>
              }
            >
              An error has occured while updating activity batch. Kindly, try
              again.
            </Alert>
          </Collapse>
        ) : null}

        {/** Error/Success messages to be shown for add */}
        {formState.fromAddActivityBatch && formState.isDataAdded ? (
          <Collapse in={open}>
            <Alert
              severity="success"
              action={
                <IconButton
                  aria-label="close"
                  color="inherit"
                  size="small"
                  onClick={() => {
                    setOpen(false);
                  }}
                >
                  <CloseIcon fontSize="inherit" />
                </IconButton>
              }
            >
              Batch {formState.addedData ? `${formState.addedData.name} ` : " "}
              has been added successfully.
            </Alert>
          </Collapse>
        ) : null}
        {formState.fromAddActivityBatch && !formState.isDataAdded ? (
          <Collapse in={open}>
            <Alert
              severity="error"
              action={
                <IconButton
                  aria-label="close"
                  color="inherit"
                  size="small"
                  onClick={() => {
                    setOpen(false);
                  }}
                >
                  <CloseIcon fontSize="inherit" />
                </IconButton>
              }
            >
              An error has occured while adding activity batch. Kindly, try
              again.
            </Alert>
          </Collapse>
        ) : null}

        {/* If there is error from any api show here */}
        <AlertAPIResponseMessage />

        <Card className={styles.filterButton}>
          <CardContent className={classes.Cardtheming}>
            <Grid className={classes.filterOptions} container spacing={1}>
              <Grid item>
                <TextField
                  label="Batch Name"
                  placeholder="Batch Name"
                  variant="outlined"
                  value={
                    formState.filterDataParameters[ACTIVITY_BATCH_FILTER] || ""
                  }
                  name={ACTIVITY_BATCH_FILTER}
                  className={classes.autoCompleteField}
                  onChange={handleFilterChange}
                />
              </Grid>
              <Grid item className={classes.filterButtonsMargin}>
                <YellowButton
                  variant="contained"
                  color="primary"
                  disableElevation
                  onClick={event => {
                    event.persist();
                    searchFilter();
                  }}
                >
                  {genericConstants.SEARCH_BUTTON_TEXT}
                </YellowButton>
              </Grid>
              <Grid item className={classes.filterButtonsMargin}>
                <GrayButton
                  variant="contained"
                  color="primary"
                  onClick={clearFilter}
                  disableElevation
                >
                  {genericConstants.RESET_BUTTON_TEXT}
                </GrayButton>
              </Grid>
            </Grid>
          </CardContent>
        </Card>
        <Table
          data={formState.dataToShow}
          column={column}
          defaultSortField="name"
          defaultSortAsc={formState.sortAscending}
          progressPending={formState.isDataLoading}
          paginationTotalRows={formState.totalRows}
          paginationRowsPerPageOptions={[10, 20, 50]}
          onChangeRowsPerPage={handlePerRowsChange}
          onChangePage={handlePageChange}
          noDataComponent="No Activity Batch details found"
        />
      </Grid>
      <DeleteActivityBatch
        showModal={formState.showModalDelete}
        closeModal={handleCloseDeleteModal}
        activityBatch={formState.dataToDelete}
        deleteEvent={isDeleteCellCompleted}
      />
    </Grid>
  );
}
Example #27
Source File: nav-menu.js    From horondi_admin with MIT License 4 votes vote down vote up
NavMenu = ({ width }) => {
  const classes = useStyles();
  const dispatch = useDispatch();

  const [navbarTab, setNavbarTab] = useState({
    clientTab: false,
    catalogTab: false,
    certificatesTab: false,
    constructorTab: false,
    staticTab: false,
    materialsTab: false,
    promoTab: false
  });

  const staticArray = {
    clientTab: false,
    catalogTab: false,
    certificatesTab: false,
    constructorTab: false,
    staticTab: false,
    materialsTab: false,
    promoTab: false
  };

  const { sideMenuStatus, pendingQuestionsCount } = useSelector(
    ({ Theme, EmailQuestions }) => ({
      sideMenuStatus: Theme.sideMenuStatus,
      pendingQuestionsCount: EmailQuestions.pendingCount
    })
  );

  const returnedList = (pathTitle, pathTo, PathIcon, nested) => (
    <ListItem
      onClick={() => {
        dispatch(setSideMenuStatus(!sideMenuStatus));
        dispatch(resetPagination());
        if (!nested) {
          setNavbarTab({
            ...staticArray
          });
        }
      }}
      button
      key={pathTitle}
      component={NavLink}
      to={pathTo}
      className={pathTitle === 'Слайдер' ? classes.sliderTab : nested || null}
      activeClassName={classes.selectedCategory}
      isActive={(props) => (props ? props.url === pathTo : null)}
    >
      <ListItemIcon>
        <PathIcon />
      </ListItemIcon>
      <ListItemText primary={pathTitle} />
      {pathTitle === titles.emailQuestionsTitles.mainPageTitle && (
        <Badge badgeContent={pendingQuestionsCount} color='error' />
      )}
    </ListItem>
  );

  const menuItems = config.menuCategories.map((category) =>
    returnedList(category[0], category[1], category[2])
  );

  const materialMenuItems = config.materialMenuCategories.map((category) =>
    returnedList(...category, classes.nested)
  );

  const clientMenuItems = config.clientMenuCategories.map((category) =>
    returnedList(category[0], category[1], category[2], classes.nested)
  );

  const catalogMenuItems = config.catalogMenuCategories.map((category) =>
    returnedList(category[0], category[1], category[2], classes.nested)
  );

  const promoMenuItems = config.promoMenuCategories.map((category) =>
    returnedList(...category, classes.nested)
  );

  const staticPagesMenuItems = config.staticPagesCategories.map((category) =>
    returnedList(category[0], category[1], category[2], classes.nested)
  );

  const constructorPagesMenuItems = config.constructorMenuCategories.map(
    (category) =>
      returnedList(category[0], category[1], category[2], classes.nested)
  );

  const certificatesMenuItems = config.certificatesMenuCategories.map(
    (category) =>
      returnedList(category[0], category[1], category[2], classes.nested)
  );

  const parentMenuTabsProperties = [
    [
      () =>
        setNavbarTab({
          ...staticArray,
          clientTab: !navbarTab.clientTab
        }),
      navbarTab.clientTab,
      clientMenuItems,
      MENU_TABS.CLIENTS,
      AccessibilityNewIcon
    ],
    [
      () =>
        setNavbarTab({
          ...staticArray,
          catalogTab: !navbarTab.catalogTab
        }),
      navbarTab.catalogTab,
      catalogMenuItems,
      MENU_TABS.CATALOG,
      ImportContactsIcon
    ],
    [
      () =>
        setNavbarTab({
          ...staticArray,
          certificatesTab: !navbarTab.certificatesTab
        }),
      navbarTab.certificatesTab,
      certificatesMenuItems,
      MENU_TABS.CERTIFICATES,
      TuneIcon
    ],
    [
      () =>
        setNavbarTab({
          ...staticArray,
          promoTab: !navbarTab.promoTab
        }),
      navbarTab.promoTab,
      promoMenuItems,
      MENU_TABS.PROMOCODE,
      PromoIcon
    ],
    [
      () =>
        setNavbarTab({
          ...staticArray,
          constructorTab: !navbarTab.constructorTab
        }),
      navbarTab.constructorTab,
      constructorPagesMenuItems,
      MENU_TABS.CONSTRUCTOR,
      AccessibilityNewIcon
    ],
    [
      () =>
        setNavbarTab({
          ...staticArray,
          materialsTab: !navbarTab.materialsTab
        }),
      navbarTab.materialsTab,
      materialMenuItems,
      MENU_TABS.MATERIALS,
      ExtensionIcon
    ],
    [
      () =>
        setNavbarTab({
          ...staticArray,
          staticTab: !navbarTab.staticTab
        }),
      navbarTab.staticTab,
      staticPagesMenuItems,
      MENU_TABS.STATIC_PAGES,
      LayersIcon
    ]
  ];

  const parentMenuItems = parentMenuTabsProperties.map((category) => {
    const handleClick = category[0];
    const stateMenu = category[1];
    const subList = category[2];
    const primary = category[3];
    const ItemIcon = category[4];

    return (
      <Fragment key={category.toString()}>
        <ListItem button onClick={handleClick}>
          <ListItemIcon>
            <ItemIcon />
          </ListItemIcon>
          <ListItemText primary={primary} />
          {stateMenu ? <ExpandLess /> : <ExpandMore />}
        </ListItem>
        <Collapse in={stateMenu} timeout='auto' unmountOnExit>
          <List>{subList}</List>
        </Collapse>
      </Fragment>
    );
  });

  const handleDrawerToggle = () => {
    dispatch(setSideMenuStatus(!sideMenuStatus));
  };

  const checkWidth = () =>
    TEMPORARY_WIDTHS.find((element) => element === width);
  const drawerVariant = checkWidth() ? DRAWER_TEMPORARY : DRAWER_PERMANENT;

  return (
    <Drawer
      id='menuDrawer'
      className={classes.drawer}
      variant={drawerVariant}
      open={sideMenuStatus}
      onClose={handleDrawerToggle}
      classes={{
        paper: classes.drawerPaper
      }}
    >
      <div className={classes.toolbar} />
      <Divider />
      <List>
        {menuItems}
        {parentMenuItems}
      </List>
      <Divider />
    </Drawer>
  );
}
Example #28
Source File: Map.js    From pwa with MIT License 4 votes vote down vote up
function Map() {
    // FIXME you are using leaflet but you haven't imported it in this component because you have put it in index.html
    // try to use react leaflet and help encapsulation components (and Separation of concerns)

    const [chosenMap, setChosenMap] = useState(null);
    const [map, setMap] = useState(null);
    const [data, setData] = useState([]);
    const [label, setLabel] = useState([]);
    const [zoom, setZoom] = useState(0);
    const [anchorEl, setAnchorEl] = useState(null);
    const [isDataFetching, setIsDataFetching] = useState(false);
    const [isDataProcessing, setisDataProcessing] = useState(false);
    const [vpnAlert, setVpnAlert] = useState(true);

    const {user, token} = useSelector((state) => state.MyActivities);

    const {
        isMapFetching,
        isPrivateMapFetching,
        mapList,
        serverError,
    } = useSelector((state) => state.Map);
    const dispatch = useDispatch();

    const drawPolygon = useCallback(
        (color, polygons) => {
            if (map && polygons) {
                for (let polygon of polygons) {
                    let tooltip = null;
                    let width = null;
                    if (isNaN(polygon[polygon.length - 1][0])) {
                        tooltip = polygon[polygon.length - 1][0];
                        width = polygon[polygon.length - 1][1];
                        polygon = polygon.slice(0, polygon.length - 1);
                    }
                    window.L.polygon([polygon], {
                        fillColor: `#${(Number(color) % 0x1000000).toString(16)}`,
                        fill: true,
                        stroke: false,
                        fillOpacity: Number(color) / 0x1000000 / 255.0,
                    }).on('click', function (e) {
                        showTooltip(tooltip, width, e)
                    }).addTo(map);
                }
            }
        },
        [map]
    );

    var popup = map && window.L.popup();

    function showTooltip(tooltip, width, e) {
        if (tooltip !== null) {
            let url = `${process.env.REACT_APP_MAP_IMAGE_CDN}${tooltip}`;
            popup
                .setLatLng(e.latlng)
                .setContent("<div>" +
                    "<img style=\"max-width: 1000px; width: " + width + "px;\" alt=\"stats\" src=" + url + " /> </div>")
                .openOn(map);
        }
    }


    const clearPolygon = useCallback(() => {
        if (map) {
            d3.selectAll('.leaflet-interactive').remove();
        }
    }, [map]);

    const clearLabel = useCallback(() => {
        if (map) {
            d3.selectAll('.leaflet-tooltip').remove();
        }
    }, [map]);

    const getData = (url, result, cached = false) => {
        setIsDataFetching(false);

        if (!result) return undefined;

        // Add to cache if map does not exist
        !cached &&
        db.set({
            data: result,
            fileName: url,
            mapName: chosenMap.id,
        });

        setisDataProcessing(true);
        const line = result;
        const lineNumber = line.length;
        let zzoom = null;
        let polygons = [];
        let sPolygons = [];
        let labels = [];
        for (let i = 0; i <= lineNumber; i++) {
            if (i === lineNumber || line[i].length === 1) {
                if (i > 0) {
                    let sameColor = {};
                    polygons.push(...sPolygons);
                    for (let j = 0; j < polygons.length; j++) {
                        let color = polygons[j][0];
                        let points = [];
                        for (let k = 1; k < polygons[j].length; k += 2)
                            points.push([polygons[j][k], polygons[j][k + 1]]);
                        if (color in sameColor)
                            sameColor[color].push(points);
                        else
                            sameColor[color] = [points];
                    }
                    setData((prevData) => [...prevData, [zzoom, sameColor]]);
                    setLabel((prevLabel) => [...prevLabel, [zzoom, labels]]);
                    polygons = [];
                    sPolygons = [];
                    labels = [];
                }
                if (i < lineNumber)
                    zzoom = Number(line[i][0]);
                continue;
            }
            if (line[i][0] === 'P') {
                polygons.push(line[i].slice(1));
            }
            if (line[i][0] === 'S') {
                sPolygons.push(line[i].slice(1));
            }
            if (line[i][0] === 'L') {
                labels.push({
                    text: line[i][1],
                    point: [line[i][2], line[i][3]],
                    size: line[i][4],
                    color: `#${(Number(line[i][5]) % 0x1000000).toString(16)}`,
                    opacity: Number(line[i][5]) / 0x1000000 / 255.0,
                })
            }
        }
        setisDataProcessing(false);
        setData((prevData) => [...prevData]);
        setLabel((prevData) => [...prevData]);
    };

    const parseFile = async (url, key) => {
        setData([]);
        setLabel([]);
        setIsDataFetching(true);
        const _cached = await db.get(url);
        if (_cached.length) {
            getData(url, _cached[0].data, true);
        } else {
            if (key) {
                const response = await axios({
                    url,
                    method: 'GET',
                    responseType: 'blob',
                });
                const decrypted = decryptPrivateMap(response.data, key);
                decrypted &&
                Papa.parse(decrypted, {
                    complete: (result) => getData(url, result.data, false),
                });
            } else {
                Papa.parse(url, {
                    download: true,
                    complete: (result) => getData(url, result.data, false),
                });
            }
        }
    };

    const findZoomLevels = useCallback(() => {
        const result = [];
        data.map((element) => result.push(element[0]));
        return result;
    }, [data]);

    const findZoom = useCallback(() => {
        const inverseZoomLevel = 10 * Math.pow(2, -(map && map.getZoom()));
        const zoomLevels = data && findZoomLevels();
        for (let i = 0; i < zoomLevels.length - 1; i++) {
            if (inverseZoomLevel <= zoomLevels[i]) {
                setZoom(i);
                break;
            } else if (
                inverseZoomLevel > zoomLevels[i] &&
                inverseZoomLevel <= zoomLevels[i + 1]
            ) {
                setZoom(i + 1);
                break;
            } else {
                setZoom(zoomLevels.length - 1)
            }
        }
    }, [map, data, findZoomLevels]);

    useEffect(() => {
        findZoom();
    }, [findZoom, data]);

    useEffect(() => {
        map &&
        map.on('zoom', function () {
            findZoom();
        });
    });

    const hasPrivateAccess = () => {
        return (
            user &&
            user.permissions.filter((perm) => perm === 'webmap').length &&
            user.permissions.some((perm) => {
                return perm.includes('maps_');
            })
        );
    };

    useEffect(() => {
        dispatch(fetchMaps());
        hasPrivateAccess() && dispatch(fetchPrivateMaps(token));
        setMap(
            new window.L.Map('map', {
                key: process.env.REACT_APP_MAP_TOKEN,
                maptype: 'dreamy',
                poi: true,
                traffic: false,
                zoomControl: false,
                center: [32.4279, 53.688],
                zoom: 4.2,
            })
        );
    }, [dispatch]);

    useEffect(() => {
        mapList && setChosenMap(mapList[0]);
    }, [mapList]);

    useEffect(() => {
        chosenMap &&
        parseFile(
            `${process.env.REACT_APP_MAP_CDN}${chosenMap.id}.${chosenMap.version}.csv`,
            chosenMap.key
        );
    }, [chosenMap]);

    useEffect(() => {
        if (isDataProcessing)
            return;
        clearPolygon();
        if (!((data || {})[zoom] || [])[1]) {
            return;
        }
        console.log("drawpolygon")
        for (let key in data[zoom][1]) {
            if (Object.prototype.hasOwnProperty.call(data[zoom][1], key))
                drawPolygon(key, data[zoom][1][key]);
        }
    }, [map, zoom, data, clearPolygon, drawPolygon]);

    useEffect(() => {
        if (isDataProcessing)
            return;
        clearLabel();
        if (!((label || {})[zoom] || [])[1]) {
            return;
        }
        // TODO clean this shit
        let root = document.documentElement;
        root.style.setProperty('--label-color', '#000000');
        root.style.setProperty('--label-size', 10);
        for (let entry of label[zoom][1]) {
            window.L.marker(entry.point, {
                opacity: 0,
            }).bindTooltip(entry.text, {
                permanent: true,
                className: 'map-label',
                direction: 'top',
            }).addTo(map);
        }
    }, [map, label, zoom, clearLabel]);

    const handleLocate = async () => {
        const myLatLngLocation = await utility.getCurrentPosition();
        map.flyTo(myLatLngLocation, 15);
    };

    const clickMenu = (event) => {
        setAnchorEl(event.currentTarget);
    };

    const closeMenu = (value) => {
        value && setChosenMap(value);
        setAnchorEl(null);
    };

    const renderMenu = () => {
        return (
            <Menu
                classes={{
                    paper: 'map-menu',
                }}
                anchorEl={anchorEl}
                keepMounted
                open={Boolean(anchorEl)}
                onClose={() => closeMenu()}
            >
                {mapList &&
                mapList.map((item) => {
                    return (
                        <MenuItem
                            key={item.id}
                            classes={{root: 'map-menu-item'}}
                            onClick={() => closeMenu(item)}
                        >
                            {item.name}
                        </MenuItem>
                    );
                })}
            </Menu>
        );
    };

    return (
        <div className={`contentWrapper MapWrapper`}>
            <div className="alerts">
                <Collapse
                    className="map-alert-wrapper"
                    in={isDataFetching || isMapFetching || isPrivateMapFetching}
                    addEndListener={null}
                >
                    <Alert
                        severity="info"
                        action={
                            <IconButton
                                color="inherit"
                                size="small"
                                onClick={() => {
                                    setIsDataFetching(false);
                                }}
                            >
                                <CloseIcon fontSize="inherit"/>
                            </IconButton>
                        }
                    >
                        تا دریافت اطلاعات منتظر بمانید.
                    </Alert>
                </Collapse>
                {serverError && (
                    <Collapse
                        className="map-alert-wrapper"
                        in={vpnAlert}
                        addEndListener={null}
                    >
                        <Alert
                            severity="warning"
                            action={
                                <IconButton
                                    color="inherit"
                                    size="small"
                                    onClick={() => {
                                        setVpnAlert(false);
                                    }}
                                >
                                    <CloseIcon fontSize="inherit"/>
                                </IconButton>
                            }
                        >
                            در صورت اتصال، vpn دستگاه را قطع کنید.
                        </Alert>
                    </Collapse>
                )}
            </div>
            <div className="map-button-wrapper">
                <button
                    type="button"
                    className="map-button"
                    onClick={() => handleLocate()}
                >
                    <MyLocationIcon/>
                </button>
                <button
                    type="button"
                    name="chosenMap"
                    className="map-button type"
                    onClick={(e) => clickMenu(e)}
                >
                    <div>{(chosenMap || {}).name}</div>
                    <ExpandMoreIcon/>
                </button>
            </div>
            <div
                id="map"
                style={{
                    position: 'fixed',
                    top: 0,
                    right: 0,
                    width: '100vw',
                    height: '100vh',
                    zIndex: 0,
                }}
            />
            <div className="comment-wrapper">
                <div className="map-comment">{(chosenMap || {}).comment || 'ــ'}</div>
            </div>
            <div className="logo-wrapper right">
                <img src={logo} alt=""/>
            </div>
            <div className="logo-wrapper left">
                <img src={neshanLogo} alt=""/>
            </div>
            {renderMenu()}
        </div>
    );
}
Example #29
Source File: UserMenu.js    From generator-webapp-rocket with MIT License 4 votes vote down vote up
function UserMenu({ drawerOpen, avatar, language, changeLanguage, withGradient }) {
    const [openAvatar, setOpenAvatar] = useState(false);
    const classes = useStyles();
    const { t } = useTranslation();
    const location = useLocation();
    const { oidcUser, logout } = useReactOidc();

    <%_ if (withRights){ _%>
    const userRoles = oidcUser?.profile?.role || emptyArray;<%_ } _%>
  
    const activeRoute = useCallback(routeName => location.pathname.indexOf(routeName) > -1, [location.pathname]) 
    <%_ if (withRights){ _%>
    const { userData } = useUserData();
    const userRights = userData?.rights || emptyArray
    <%_ } _%>
    <% if (withRights){ _%>
    const userMenuItems = userMenuConfig.filter(item => isEmpty(item.rights)
      ? intersect(userRoles, item.roles) || isEmpty(item.roles)
      : (intersect(userRoles, item.roles) && intersect(userRights, item.rights)) || isEmpty(item.roles)
    )<%_ } else { _%>
    const userMenuItems = userMenuConfig
    <%_ } _%>
    
    const openCollapseAvatar = useCallback(e => {
        setOpenAvatar(!openAvatar);
        e.preventDefault();
    }, [openAvatar])

    <%_ if (withMultiTenancy) { _%>
    const setContextTenant = useContext(TenantContext)

    // // TODO: might have the issue https://github.com/apollographql/apollo-client/issues/5179
    const [callMyTenantsQuery, { called, loading: tenantsLoading, data }] = useLazyQuery(MY_TENANTS_QUERY)

    useEffect(() => {
        if (!oidcUser || called || tenantsLoading) { return }

        callMyTenantsQuery();
    }, [callMyTenantsQuery, called, tenantsLoading, oidcUser])
    const myTenants = data?.myTenants 
    <%_}_%>
    <%_ if (withMultiTenancy) { _%>
    const logoutAction = useCallback(e => {
        e.preventDefault();
        logout();
        setContextTenant();
    }, [logout, setContextTenant])
    <%_} else { _%>
    const logoutAction = useCallback(e => {
        e.preventDefault();
        logout();
    }, [logout]) 
    <%_}_%>

    const userName = oidcUser?.profile?.firstName
        ? `${oidcUser.profile.name} ${oidcUser.profile.lastName}`
        : oidcUser?.profile
            ? oidcUser.profile.name.split('@')[0]
            : "User";
    <%_ if (withMultiTenancy) { _%>
    const [tenant, setTenant] = useState(myTenants && oidcUser?.profile?.tid && myTenants.find(t => t.externalId.toUpperCase() === oidcUser?.profile?.tid.toUpperCase()))
    useEffect(() => {
        const localTenant = myTenants && oidcUser?.profile?.tid && myTenants.find(t => t.externalId.toUpperCase() === oidcUser?.profile?.tid.toUpperCase())
        if (!localTenant || tenant) { return }
        setTenant(localTenant)
    }, [myTenants, oidcUser, tenant])

    const handleTenantChange = useCallback(e => {
        setTenant(e)
        setContextTenant(e.code)
    }, [setContextTenant])

    const tenantName = tenant?.name ? ` - ${tenant.name}` : "" 
    <%_}_%>
    const itemText = classes.itemText +
        " " +
        cx({
            [classes.itemTextMini]: !drawerOpen
        });
    <% if (withMultiTenancy) { %> const displayName = `${userName}${tenantName}` <% } %>
    <% if (!withMultiTenancy) { %> const displayName = userName <% } %>
    return (
        <List className={classes.userMenuContainer}>
            <ListItem className={classes.item + " " + classes.userItem}>
                <NavLink to={'/'} className={classes.itemLink} onClick={openCollapseAvatar}>
                    <ListItemIcon className={classes.itemIcon}>
                        <img src={avatar ? avatar : avatar_default} className={classes.photo} alt='...' />
                    </ListItemIcon>
                    <ListItemText
                        primary={displayName}
                        secondary={openAvatar ? <ArrowDropUp className={classes.caret} /> : <ArrowDropDown className={classes.caret} />}
                        disableTypography={true}
                        className={itemText}
                    />
                </NavLink>
                <Collapse in={openAvatar} unmountOnExit classes={{ wrapper: classes.collapseWrapper }}>
                    <List className={classes.list + classes.collapseList}>
                        {userMenuItems.map((userMenu, key) => {
                            return <UserMenuItem key={key} userMenu={userMenu} drawerOpen={drawerOpen} activeRoute={activeRoute} withGradient={withGradient} />
                        })}
                        {oidcUser &&
                            <Tooltip disableHoverListener={drawerOpen} title={t('Tooltips.Logout')}>
                                <ListItem className={classes.collapseItem}>
                                    <NavLink to={"/"} className={classes.itemLink} onClick={logoutAction}>
                                    <ListItemIcon className={classes.itemIcon}>
                                        <PowerSettingsNew />
                                    </ListItemIcon>
                                    <ListItemText
                                        primary={t('Tooltips.Logout')}
                                        disableTypography={true}
                                        className={itemText}
                                    />
                                    </NavLink>
                                </ListItem>
                            </Tooltip>
                        }
                        <ListItem className={classes.selectorItem}>
                            <LanguageSelector
                                language={language}
                                changeLanguage={changeLanguage}
                                drawerOpen={drawerOpen}
                            />
                        </ListItem>
                        <% if (withMultiTenancy) { %> {!tenantsLoading && myTenants?.length > 1 &&
                        <Tooltip disableHoverListener={drawerOpen} title={t('Tooltips.TenantList')}>
                            <ListItem className={classes.selectorItem}>
                                <TenantSelector
                                    tenant={tenant}
                                    tenants={myTenants}
                                    changeTenant={handleTenantChange}
                                    drawerOpen={drawerOpen}
                                />
                            </ListItem>
                        </Tooltip>
                        }<% } -%>
                    </List>
                </Collapse>
            </ListItem>
        </List>
    );
}