@mui/material#ListItem TypeScript Examples

The following examples show how to use @mui/material#ListItem. 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: Vault.tsx    From NekoMaid with MIT License 6 votes vote down vote up
Groups: React.FC<{ plugin: Plugin, id: string | undefined, onClose: () => void, groups: GroupInfo[] }> =
  ({ plugin, id, onClose, groups }) => {
    const [loading, setLoading] = useState(true)
    const [playerGroups, setPlayerGroups] = useState<Record<string, true>>({ })
    const refresh = () => {
      setLoading(true)
      plugin.emit('vault:playerGroup', (res: string[]) => {
        if (!res) return
        const obj: Record<string, true> = { }
        res.forEach(it => (obj[it] = true))
        setPlayerGroups(obj)
        setLoading(false)
      }, id, null, 0)
    }
    useEffect(() => {
      setPlayerGroups({})
      if (!id) return
      refresh()
    }, [id])
    return <Dialog onClose={onClose} open={!!id}>
      <DialogTitle>{lang.vault.whosPermissionGroup(id!)}</DialogTitle>
      <List sx={{ pt: 0 }}>
        {groups.map(it => <ListItem onClick={() => { }} key={it.id}>
          <ListItemIcon><Checkbox
            tabIndex={-1}
            disabled={loading}
            checked={!!playerGroups[it.id]}
            onChange={e => plugin.emit('vault:playerGroup', (res: boolean) => {
              action(res)
              refresh()
            }, id, it.id, e.target.checked ? 1 : 2)}
          /></ListItemIcon>
          <ListItemText primary={it.id} />
        </ListItem>)}
      </List>
      <DialogActions><Button onClick={onClose}>{minecraft['gui.back']}</Button></DialogActions>
    </Dialog>
  }
Example #2
Source File: DesktopSideBar.tsx    From Tachidesk-WebUI with Mozilla Public License 2.0 6 votes vote down vote up
export default function DesktopSideBar({ navBarItems }: IProps) {
    const location = useLocation();
    const theme = useTheme();

    const iconFor = (path: string, IconComponent: any, SelectedIconComponent: any) => {
        if (location.pathname === path) return <SelectedIconComponent sx={{ color: 'primary.main' }} fontSize="large" />;
        return <IconComponent sx={{ color: (theme.palette.mode === 'dark') ? 'grey.A400' : 'grey.600' }} fontSize="large" />;
    };

    return (
        <SideNavBarContainer>
            {
                // eslint-disable-next-line react/destructuring-assignment
                navBarItems.map(({
                    path, title, IconComponent, SelectedIconComponent,
                }: NavbarItem) => (
                    <Link to={path} style={{ color: 'inherit', textDecoration: 'none' }} key={path}>
                        <ListItem disableRipple button key={title}>
                            <ListItemIcon sx={{ minWidth: '0' }}>
                                <Tooltip placement="right" title={title}>
                                    {iconFor(path, IconComponent, SelectedIconComponent)}
                                </Tooltip>
                            </ListItemIcon>
                        </ListItem>
                    </Link>
                ))
            }
        </SideNavBarContainer>
    );
}
Example #3
Source File: Profile.tsx    From abrechnung with GNU Affero General Public License v3.0 6 votes vote down vote up
export default function Profile() {
    const user = useRecoilValue(userData);
    const isGuest = useRecoilValue(isGuestUser);
    useTitle("Abrechnung - Profile");

    return (
        <MobilePaper>
            <Typography component="h3" variant="h5">
                Profile
            </Typography>
            {isGuest && (
                <Alert severity="info">
                    You are a guest user on this Abrechnung and therefore not permitted to create new groups or group
                    invites.
                </Alert>
            )}
            <List>
                <ListItem>
                    <ListItemText primary="Username" secondary={user.username} />
                </ListItem>
                <ListItem>
                    <ListItemText primary="E-Mail" secondary={user.email} />
                </ListItem>
                <ListItem>
                    <ListItemText
                        primary="Registered"
                        secondary={DateTime.fromISO(user.registered_at).toLocaleString(DateTime.DATETIME_FULL)}
                    />
                </ListItem>
            </List>
        </MobilePaper>
    );
}
Example #4
Source File: FileList.tsx    From frontend with MIT License 6 votes vote down vote up
function FileList({ files, onDelete }: Props) {
  return (
    <List dense>
      {files.map((file, key) => (
        <ListItem
          key={key}
          secondaryAction={
            <IconButton edge="end" aria-label="delete" onClick={() => onDelete && onDelete(file)}>
              <Delete />
            </IconButton>
          }>
          <ListItemAvatar>
            <Avatar>
              <UploadFile />
            </Avatar>
          </ListItemAvatar>
          <ListItemText primary={file.type} />
          <ListItemText primary={file.name} />
        </ListItem>
      ))}
    </List>
  )
}
Example #5
Source File: list-item-link.tsx    From example with MIT License 6 votes vote down vote up
export function ListItemLink(props: IListItemLinkProps) {
	const { icon, primary, to } = props
	const location = useLocation();

	const renderLink = React.useMemo(
		() =>
			React.forwardRef(function Link(itemProps, ref) {
				return <RouterLink to={to} ref={ref as any} {...itemProps} role={undefined} />
			}),
		[to],
	)

	return (
		<li>
			<ListItem
				button
				component={renderLink}
				selected={
					location.pathname === to ||
					(props.default && (location.pathname === "" || location.pathname === "/"))
				}>
				{icon ? <ListItemIcon>{icon}</ListItemIcon> : null}
				<ListItemText primary={primary} />
			</ListItem>
		</li>
	)
}
Example #6
Source File: Header.tsx    From fluttertemplates.dev with MIT License 6 votes vote down vote up
displayMobile = (isOpen: boolean, onToggle: any) => {
  return (
    <div>
      <IconButton onClick={onToggle}>
        <MenuRounded />
      </IconButton>
      <Drawer open={isOpen} anchor="bottom" onClose={onToggle}>
        {commonNav.map((item) => (
          <ListItem
            key={item.props.href}
            style={{
              padding: 16,
              justifyContent: "center",
            }}
          >
            {item}
          </ListItem>
        ))}
      </Drawer>
    </div>
  );
}
Example #7
Source File: AppNavbar.tsx    From sapio-studio with Mozilla Public License 2.0 6 votes vote down vote up
function SettingsMenuItem() {
    const dispatch = useDispatch();
    return (
        <ListItem
            disableGutters
            button={false}
            key={'settings'}
            onClick={() => dispatch(switch_showing('Settings'))}
        >
            <ListItemIcon>
                <SettingsIcon />
            </ListItemIcon>
            <ListItemText primary={'Settings'} />
        </ListItem>
    );
}
Example #8
Source File: NativeListItem.tsx    From GTAV-NativeDB with MIT License 6 votes vote down vote up
function NativeListItem({ nativeHash }: NativeListItemProps) {
  const native = useNative(nativeHash)
  const history = useHistory()
  const { native: selectedNativeHash } = useParams<{ native: string } >()
  
  const onClick = useCallback(() => {
    history.push(`/natives/${nativeHash}${history.location.search}`)
  }, [history, nativeHash])

  return (
    <ListItem
      onClick={onClick}
      selected={selectedNativeHash === nativeHash}
      button
      dense
    >
      <NativeDefinition
        name={native.name}
        returnType={native.returnType}
        params={native.params}
        nameCopyable={false}
        noWrap
      />
    </ListItem>
  )
}
Example #9
Source File: WalletListItem.tsx    From wallet-adapter with Apache License 2.0 6 votes vote down vote up
WalletListItem: FC<WalletListItemProps> = ({ onClick, wallet, ...props }) => {
    return (
        <ListItem {...props}>
            <Button onClick={onClick} endIcon={<WalletIcon wallet={wallet} />}>
                {wallet.adapter.name}
            </Button>
        </ListItem>
    );
}
Example #10
Source File: index.tsx    From Search-Next with GNU General Public License v3.0 6 votes vote down vote up
MenuListItem: React.FC<MenuListItemProps> = ({
  icon,
  primary,
  ...props
}) => {
  return (
    <ListItem {...props}>
      <ListItemIcon className="min-w-min mr-2">{icon}</ListItemIcon>
      <ListItemText primary={primary} />
    </ListItem>
  );
}
Example #11
Source File: Facet.tsx    From cli with Apache License 2.0 5 votes vote down vote up
FacetRenderer: FunctionComponent<FacetRendererProps> = (props) => {
  const {controller} = props;
  const [state, setState] = useState(controller.state);

  useEffect(
    () => controller.subscribe(() => setState(controller.state)),
    [controller]
  );

  const toggleSelect = (value: FacetValue) => {
    controller.toggleSelect(value);
  };

  const showMore = () => {
    controller.showMoreValues();
  };

  const showLess = () => {
    controller.showLessValues();
  };

  return (
    <Box mb={5} mr={3} p={1}>
      <Box pb={1}>
        <Typography variant="h6" component="h6">
          {props.title}
        </Typography>
      </Box>
      <Divider />
      <List dense>
        {state.values.map((value: FacetValue) => {
          const labelId = `checkbox-list-label-${value}`;

          return (
            <ListItem
              style={{padding: 0}}
              key={value.value}
              role={undefined}
              button
              onClick={() => toggleSelect(value)}
            >
              <Checkbox
                size="small"
                edge="start"
                checked={controller.isValueSelected(value)}
                tabIndex={-1}
                disableRipple
                inputProps={{'aria-labelledby': labelId}}
              />
              <ListItemText
                className="truncate inline"
                primary={`${value.value}`}
                secondary={`(${value.numberOfResults})`}
              />
            </ListItem>
          );
        })}
      </List>
      {state.canShowLessValues && (
        <Button size="small" onClick={() => showLess()}>
          Show Less
        </Button>
      )}
      {state.canShowMoreValues && (
        <Button size="small" onClick={() => showMore()}>
          Show More
        </Button>
      )}
    </Box>
  );
}
Example #12
Source File: SkeletonComponent.tsx    From firecms with MIT License 5 votes vote down vote up
function renderMap<T extends object>(property: MapProperty<T>, size: PreviewSize) {

    if (!property.properties)
        return <></>;

    let mapProperties: string[];
    if (!size) {
        mapProperties = Object.keys(property.properties);
    } else {
        if (property.previewProperties)
            mapProperties = property.previewProperties as string[];
        else
            mapProperties = Object.keys(property.properties).slice(0, 3);
    }

    if (size)
        return (
            <List>
                {mapProperties && mapProperties.map((key: string) => (
                    <ListItem key={property.title + key}>
                        <SkeletonComponent
                            property={(property.properties as any)[key]}
                            size={"small"}/>
                    </ListItem>
                ))}
            </List>
        );

    return (
        <Table size={"small"}>
            <TableBody>
                {mapProperties &&
                mapProperties.map((key, index) => {
                    return (
                        <TableRow key={`table_${property.title}_${index}`}
                                  sx={{
                                      "&:last-child th, &:last-child td": {
                                          borderBottom: 0
                                      }
                                  }}>
                            <TableCell key={`table-cell-title-${key}`}
                                       component="th">
                                <Skeleton variant="text"/>
                            </TableCell>
                            <TableCell key={`table-cell-${key}`} component="th">
                                <SkeletonComponent
                                    property={(property.properties as any)[key]}
                                    size={"small"}/>
                            </TableCell>
                        </TableRow>
                    );
                })}
            </TableBody>
        </Table>
    );

}
Example #13
Source File: ResultList.tsx    From cli with Apache License 2.0 5 votes vote down vote up
ResultListRenderer: FunctionComponent<ResultListProps> = (props) => {
  const {controller} = props;
  const engine = useContext(EngineContext)!;
  const [state, setState] = useState(controller.state);

  const headlessResultTemplateManager: ResultTemplatesManager<Template> =
    buildResultTemplatesManager(engine);

  headlessResultTemplateManager.registerTemplates({
    conditions: [],
    content: (result: Result) => (
      <ListItem disableGutters key={result.uniqueId}>
        <Box my={2}>
          <Box pb={1}>{ListItemLink(engine, result)}</Box>

          {result.excerpt && (
            <Box pb={1}>
              <Typography color="textPrimary" variant="body2">
                {result.excerpt}
              </Typography>
            </Box>
          )}

          {result.raw.source && (
            <FieldValue caption="Source" value={result.raw.source} />
          )}
          {result.raw.objecttype && (
            <FieldValue caption="Object Type" value={result.raw.objecttype} />
          )}
        </Box>
      </ListItem>
    ),
  });

  useEffect(
    () => controller.subscribe(() => setState(controller.state)),
    [controller]
  );

  return (
    <List>
      {state.results.map((result: Result) => {
        const template = headlessResultTemplateManager.selectTemplate(result);
        return template ? template(result) : null;
      })}
    </List>
  );
}
Example #14
Source File: FieldDisplay.tsx    From genshin-optimizer with MIT License 5 votes vote down vote up
export default function FieldsDisplay({ fields }: { fields: IFieldDisplay[] }) {
  return <FieldDisplayList sx={{ m: 0 }}>
    {fields.map((field, i) => <FieldDisplay key={i} field={field} component={ListItem} />)}
  </FieldDisplayList>
}
Example #15
Source File: TLSCertificate.tsx    From console with GNU Affero General Public License v3.0 5 votes vote down vote up
TLSCertificate = ({
  classes,
  certificateInfo,
  onDelete = () => {},
}: ITLSCertificate) => {
  const certificates = certificateInfo.domains || [];
  return (
    <Chip
      key={certificateInfo.name}
      variant="outlined"
      color="primary"
      className={classes.certificateWrapper}
      label={
        <Container>
          <Grid item xs={1} className={classes.certificateIcon}>
            <CertificateIcon />
          </Grid>
          <Grid item xs={11} className={classes.certificateInfo}>
            <Typography variant="subtitle1" display="block" gutterBottom>
              {certificateInfo.name}
            </Typography>
            <Box className={classes.certificateExpiry}>
              <EventBusyIcon color="inherit" fontSize="small" />
              &nbsp;
              <span className={"label"}>Expiry:&nbsp;</span>
              <span>
                <Moment format="YYYY/MM/DD">{certificateInfo.expiry}</Moment>
              </span>
            </Box>
            <Divider />
            <br />
            <Box className={classes.certificateDomains}>
              <span className="label">{`${certificates.length} Domain (s):`}</span>
            </Box>
            <List className={classes.certificatesList}>
              {certificates.map((dom) => (
                <ListItem className={classes.certificatesListItem}>
                  <ListItemAvatar>
                    <LanguageIcon />
                  </ListItemAvatar>
                  <ListItemText primary={dom} />
                </ListItem>
              ))}
            </List>
          </Grid>
        </Container>
      }
      onDelete={onDelete}
    />
  );
}
Example #16
Source File: Dashboard.tsx    From NekoMaid with MIT License 5 votes vote down vote up
Players: React.FC<{ players?: CurrentStatus['players'] }> = React.memo(({ players }) => {
  const his = useHistory()
  const plugin = usePlugin()
  const globalData = useGlobalData()
  const [page, setPage] = useState(1)
  const [id, update] = useState(0)
  return <Card>
    <CardHeader title={lang.dashboard.onlinePlayers} />
    <Divider />
    <CardContent>
      {players?.length === 0
        ? <Empty />
        : <>
        <List sx={{ paddingTop: 0 }}>
          {players
            ? players.slice((page - 1) * 8, page * 8).map(p => {
              const name = typeof p === 'string' ? p : p.name
              return <Tooltip key={name} title={'IP: ' + ((p as any).ip || lang.unknown)}>
                <ListItem
                  secondaryAction={<>
                    <IconButton
                      edge='end'
                      size='small'
                      onClick={() => dialog(lang.dashboard.confirmKick(<span className='bold'>{name}</span>), lang.reason)
                        .then(it => it != null && plugin.emit('dashboard:kick', (res: boolean) => {
                          action(res)
                          if (!players) return
                          players.splice(players.indexOf(it!), 1)
                          update(id + 1)
                        }, name, it || null))
                      }
                    ><ExitToApp /></IconButton>
                    <IconButton edge='end' onClick={() => his.push('/NekoMaid/playerList/' + name)} size='small'><MoreHoriz /></IconButton>
                  </>
                  }
                >
                  <ListItemAvatar>
                    <Avatar
                      src={getSkin(globalData, name, true)}
                      imgProps={{ crossOrigin: 'anonymous', onClick () { his.push('/NekoMaid/playerList/' + name) }, style: { width: 40, height: 40 } }}
                      sx={{ cursor: 'pointer' }}
                      variant='rounded'
                    />
                  </ListItemAvatar>
                  <ListItemText primary={name} />
                </ListItem>
              </Tooltip>
            })
            : <LoadingList />
          }
        </List>
        {players && <Pagination
          page={page}
          onChange={(_, it) => setPage(it)}
          count={Math.max(Math.ceil(players.length / 8), 1)}
          sx={{ display: 'flex', justifyContent: 'flex-end' }}
        />}
      </>}
    </CardContent>
  </Card>
})
Example #17
Source File: SortFilter.tsx    From Tachidesk-WebUI with Mozilla Public License 2.0 5 votes vote down vote up
export default function SortFilter(props: Props) {
    const {
        values,
        name,
        state,
        position,
        group,
        updateFilterValue,
        update,
    } = props;
    const [val, setval] = React.useState(state);

    const [open, setOpen] = React.useState(false);

    const handleClick = () => {
        setOpen(!open);
    };

    if (values) {
        const handleChange = (event:
        React.MouseEvent<HTMLDivElement, MouseEvent>, index: number) => {
            const tmp = val;
            if (tmp.index === index) {
                tmp.ascending = !tmp.ascending;
            } else {
                tmp.ascending = true;
            }
            tmp.index = index;
            setval(tmp);
            const upd = update.filter((e: {
                position: number; group: number | undefined;
            }) => !(position === e.position && group === e.group));
            updateFilterValue([...upd, { position, state: JSON.stringify(tmp), group }]);
        };

        const ret = (
            <FormControl fullWidth>
                <ListItemButton onClick={handleClick}>
                    <ListItemText primary={name} />
                    {open ? <ExpandLess /> : <ExpandMore />}
                </ListItemButton>
                <Collapse in={open}>
                    <List>
                        {values.map((value: string, index: number) => {
                            let icon;
                            if (val.index === index) {
                                icon = val.ascending ? (<ArrowUpwardIcon color="primary" />)
                                    : (<ArrowDownwardIcon color="primary" />);
                            }
                            return (
                                <ListItem disablePadding key={`${name} ${value}`}>
                                    <ListItemButton
                                        onClick={(event) => handleChange(event, index)}
                                    >
                                        <ListItemIcon>
                                            {icon}
                                        </ListItemIcon>
                                        <ListItemText primary={value} />
                                    </ListItemButton>
                                </ListItem>
                            );
                        })}
                    </List>
                </Collapse>
            </FormControl>
        );
        return (
            <Box key={name} sx={{ display: 'flex', flexDirection: 'column', minWidth: 120 }}>
                {ret}
            </Box>
        );
    }
    return (<></>);
}
Example #18
Source File: QueryStateEditor.tsx    From mui-toolpad with MIT License 5 votes vote down vote up
export default function QueryStateEditor() {
  const dom = useDom();
  const state = usePageEditorState();
  const domApi = useDomApi();

  const [editedState, setEditedState] = React.useState<NodeId | null>(null);
  const editedStateNode = editedState ? appDom.getNode(dom, editedState, 'queryState') : null;
  const handleEditStateDialogClose = React.useCallback(() => setEditedState(null), []);

  const page = appDom.getNode(dom, state.nodeId, 'page');
  const { queryStates = [] } = appDom.getChildNodes(dom, page) ?? [];

  // To keep dialog content around during closing animation
  const lastEditedStateNode = useLatest(editedStateNode);

  const handleRemove = React.useCallback(() => {
    if (editedStateNode) {
      domApi.removeNode(editedStateNode.id);
    }
    handleEditStateDialogClose();
  }, [editedStateNode, handleEditStateDialogClose, domApi]);

  return queryStates.length > 0 ? (
    <Stack spacing={1} alignItems="start">
      <List>
        {queryStates.map((stateNode) => {
          return (
            <ListItem key={stateNode.id} button onClick={() => setEditedState(stateNode.id)}>
              {stateNode.name}
            </ListItem>
          );
        })}
      </List>
      {lastEditedStateNode ? (
        <Dialog
          fullWidth
          maxWidth="lg"
          open={!!editedStateNode}
          onClose={handleEditStateDialogClose}
          scroll="body"
        >
          <DialogTitle>Edit Query State ({lastEditedStateNode.id})</DialogTitle>
          <DialogContent>
            <QueryStateNodeEditor node={lastEditedStateNode} />
          </DialogContent>
          <DialogActions>
            <Button color="inherit" variant="text" onClick={handleEditStateDialogClose}>
              Close
            </Button>
            <Button onClick={handleRemove}>Remove</Button>
          </DialogActions>
        </Dialog>
      ) : null}
    </Stack>
  ) : null;
}
Example #19
Source File: Loading.tsx    From NekoMaid with MIT License 5 votes vote down vote up
LoadingList: React.FC<{ count?: number }> = ({ count = 3 }) => <>{Array.from({ length: count }, (_, i) => <ListItem key={i}>
  <ListItemAvatar><Skeleton animation='wave' variant='circular' width={40} height={40} /></ListItemAvatar>
  <ListItemText primary={<Skeleton animation='wave' />} />
</ListItem>)}</>
Example #20
Source File: IrregularityFile.tsx    From frontend with MIT License 5 votes vote down vote up
export default function IrregularityFile({ file, irregularityId }: Props) {
  const { t } = useTranslation('irregularity')
  const queryClient = useQueryClient()
  const router = useRouter()

  const mutation = useMutation<AxiosResponse<IrregularityFileResponse>, AxiosError<ApiErrors>>({
    mutationFn: deleteIrregularityFile(file.id),
    onError: () => AlertStore.show(t('admin.alerts.error'), 'error'),
    onSuccess: () => {
      AlertStore.show(t('admin.alerts.delete-file'), 'success')
      queryClient.invalidateQueries(endpoints.irregularity.viewIrregularity(irregularityId).url)
      router.push(routes.admin.irregularity.index)
    },
  })

  const deleteFileHandler = () => {
    mutation.mutate()
  }

  return (
    <ListItem key={file.id}>
      <ListItemAvatar>
        <Avatar>
          <FilePresentIcon />
        </Avatar>
      </ListItemAvatar>
      <ListItemText primary={file.filename} />
      <></>
      <Tooltip
        title={
          'Note: This link is public on the API side! Need to correct before official release!'
        }>
        <Button>
          {/* TODO: to be discussed. Tracked in issue: https://github.com/podkrepi-bg/frontend/issues/811 */}
          <a style={{ color: 'red' }} href={API_URL + `/irregularity-file/${file.id}`}>
            {t('admin.cta.download') + '*'}
          </a>
        </Button>
      </Tooltip>
      <Button onClick={deleteFileHandler}>{t('admin.cta.delete')}</Button>
    </ListItem>
  )
}
Example #21
Source File: StatsDialog.tsx    From GTAV-NativeDB with MIT License 5 votes vote down vote up
export default function StatsDialog({ open, onClose }: Props) {
  const stats = useStats()

  return (
    <Dialog open={open} onClose={onClose} fullWidth maxWidth="xs">
      <DialogTitle>
        Stats
      </DialogTitle>
      <List dense>
        <ListItem sx={{ px: 3 }} >
          <ListItemText 
            primary="Namespaces"
            secondary={stats.namespaces}
          />
        </ListItem>
        <ListItem sx={{ px: 3 }} >
          <ListItemText 
            primary="Natives"
            secondary={stats.natives}
          />
        </ListItem>
        <ListItem sx={{ px: 3 }} >
          <ListItemText 
            primary="Comments"
            secondary={stats.comments}
          />
        </ListItem>
        <ListItem sx={{ px: 3 }} >
          <ListItemText 
            primary="Known names"
            secondary={`${stats.knownNames.confirmed} (${stats.knownNames.total})`}
          />
        </ListItem>
      </List>
      <DialogActions>
        <Button onClick={onClose}>Close</Button>
      </DialogActions>
    </Dialog>
  )
}
Example #22
Source File: WalletDialog.tsx    From wallet-adapter with Apache License 2.0 5 votes vote down vote up
WalletDialog: FC<WalletDialogProps> = ({
    title = 'Select your wallet',
    featuredWallets = 3,
    onClose,
    ...props
}) => {
    const { wallets, select } = useWallet();
    const { open, setOpen } = useWalletDialog();
    const [expanded, setExpanded] = useState(false);

    const [featured, more] = useMemo(
        () => [wallets.slice(0, featuredWallets), wallets.slice(featuredWallets)],
        [wallets, featuredWallets]
    );

    const handleClose = useCallback(
        (event: SyntheticEvent, reason?: 'backdropClick' | 'escapeKeyDown') => {
            if (onClose) onClose(event, reason!);
            if (!event.defaultPrevented) setOpen(false);
        },
        [setOpen, onClose]
    );

    const handleWalletClick = useCallback(
        (event: SyntheticEvent, walletName: WalletName) => {
            select(walletName);
            handleClose(event);
        },
        [select, handleClose]
    );

    const handleExpandClick = useCallback(() => setExpanded(!expanded), [setExpanded, expanded]);

    return (
        <RootDialog open={open} onClose={handleClose} {...props}>
            <DialogTitle>
                {title}
                <IconButton onClick={handleClose} size="large">
                    <CloseIcon />
                </IconButton>
            </DialogTitle>
            <DialogContent>
                <List>
                    {featured.map((wallet) => (
                        <WalletListItem
                            key={wallet.adapter.name}
                            onClick={(event) => handleWalletClick(event, wallet.adapter.name)}
                            wallet={wallet}
                        />
                    ))}
                    {more.length ? (
                        <>
                            <Collapse in={expanded} timeout="auto" unmountOnExit>
                                <List>
                                    {more.map((wallet) => (
                                        <WalletListItem
                                            key={wallet.adapter.name}
                                            onClick={(event) => handleWalletClick(event, wallet.adapter.name)}
                                            wallet={wallet}
                                        />
                                    ))}
                                </List>
                            </Collapse>
                            <ListItem>
                                <Button onClick={handleExpandClick}>
                                    {expanded ? 'Less' : 'More'} options
                                    {expanded ? <CollapseIcon /> : <ExpandIcon />}
                                </Button>
                            </ListItem>
                        </>
                    ) : null}
                </List>
            </DialogContent>
        </RootDialog>
    );
}
Example #23
Source File: AppNavbar.tsx    From sapio-studio with Mozilla Public License 2.0 5 votes vote down vote up
function NodeMenu(props: { bitcoin_node_manager: BitcoinNodeManager }) {
    const dispatch = useDispatch();
    const nodeRef = React.useRef<HTMLLIElement>(null);
    const [node_open, setNodeOpen] = React.useState(false);
    const close = () => setNodeOpen(false);

    return (
        <>
            <ListItem
                disableGutters
                button={false}
                key={'Bitcoin Node'}
                onClick={() => setNodeOpen(true)}
                ref={nodeRef}
            >
                <ListItemIcon></ListItemIcon>
                <ListItemText primary={'Bitcoin Node'} />
            </ListItem>
            <Menu
                anchorEl={nodeRef.current}
                anchorOrigin={{
                    vertical: 'center',
                    horizontal: 'right',
                }}
                keepMounted
                open={node_open}
                onClose={close}
            >
                <MenuItem
                    onClick={async () => {
                        close();
                        const addr =
                            await props.bitcoin_node_manager.get_new_address();
                        window.electron.write_clipboard(addr);
                    }}
                >
                    Get New Address to Clipboard
                </MenuItem>
                <MenuItem
                    onClick={() => {
                        close();
                        props.bitcoin_node_manager
                            .generate_blocks(10)
                            .catch((err) => console.error(err));
                    }}
                >
                    Generate 10 Blocks
                </MenuItem>
                <Divider />
                <MenuItem
                    onClick={() => {
                        close();
                        dispatch(toggle_status_bar());
                    }}
                >
                    Toggle Status
                </MenuItem>
            </Menu>
        </>
    );
}
Example #24
Source File: SidebarGroupList.tsx    From abrechnung with GNU Affero General Public License v3.0 5 votes vote down vote up
export default function SidebarGroupList({ group = null }) {
    const groups = useRecoilValue(groupList);
    const isGuest = useRecoilValue(isGuestUser);
    const [showGroupCreationModal, setShowGroupCreationModal] = useState(false);

    const openGroupCreateModal = () => {
        setShowGroupCreationModal(true);
    };

    const closeGroupCreateModal = (evt, reason) => {
        if (reason !== "backdropClick") {
            setShowGroupCreationModal(false);
        }
    };

    return (
        <>
            <List sx={{ pt: 0 }}>
                <ListItem sx={{ pt: 0, pb: 0 }}>
                    <ListItemText secondary="Groups" />
                </ListItem>
                {groups.map((it) => (
                    <ListItemLink key={it.id} to={`/groups/${it.id}`} selected={group && group.id === it.id}>
                        <ListItemText primary={it.name} />
                    </ListItemLink>
                ))}
                {!isGuest && (
                    <ListItem sx={{ padding: 0 }}>
                        <Grid container justifyContent="center">
                            <IconButton size="small" onClick={openGroupCreateModal}>
                                <Add />
                            </IconButton>
                        </Grid>
                    </ListItem>
                )}
            </List>
            {!isGuest && <GroupCreateModal show={showGroupCreationModal} onClose={closeGroupCreateModal} />}
        </>
    );
}
Example #25
Source File: FileList.tsx    From frontend with MIT License 5 votes vote down vote up
function FileList({ files, onDelete, onSetFileRole, filesRole = [] }: Props) {
  const setFileRole = (file: File) => {
    return (event: SelectChangeEvent<CampaignFileRole>) => {
      if (Object.values(CampaignFileRole).includes(event.target.value as CampaignFileRole)) {
        onSetFileRole(file, event.target.value as CampaignFileRole)
      }
    }
  }

  return (
    <List dense>
      {files.map((file, key) => (
        <ListItem
          key={key}
          secondaryAction={
            <IconButton edge="end" aria-label="delete" onClick={() => onDelete && onDelete(file)}>
              <Delete />
            </IconButton>
          }>
          <ListItemAvatar>
            <Avatar>
              <UploadFile />
            </Avatar>
          </ListItemAvatar>
          <ListItemText primary={file.type} />
          <ListItemText primary={file.name} />
          <FormControl>
            <InputLabel id="choose-type-label">{'Избери роля'}</InputLabel>
            <Select<CampaignFileRole>
              id="choose-type"
              label="Избери роля"
              labelId="choose-type-label"
              value={
                filesRole.find((f) => f.file === file.name)?.role ?? CampaignFileRole.background
              }
              onChange={setFileRole(file)}>
              {Object.values(CampaignFileRole).map((role) => (
                <MenuItem key={role} value={role}>
                  {role}
                </MenuItem>
              ))}
            </Select>
          </FormControl>
        </ListItem>
      ))}
    </List>
  )
}
Example #26
Source File: Worlds.tsx    From NekoMaid with MIT License 4 votes vote down vote up
Worlds: React.FC = () => {
  const plugin = usePlugin()
  const globalData = useGlobalData()
  const [worlds, setWorlds] = useState<World[]>([])
  const [selected, setSelected] = useState('')
  const [open, setOpen] = useState(false)
  const update = () => plugin.emit('worlds:fetch', (data: World[]) => {
    setWorlds(data)
    if (data.length) setSelected(old => data.some(it => it.id === old) ? old : '')
  })
  useEffect(() => {
    const offUpdate = plugin.on('worlds:update', update)
    update()
    return () => { offUpdate() }
  }, [])
  const sw = worlds.find(it => it.id === selected)
  const getSwitch = (name: string, configId = name) => sw
    ? <ListItem
      secondaryAction={<Switch disabled={!globalData.hasMultiverse} checked={(sw as any)[name]}
      onChange={e => {
        plugin.emit('worlds:set', sw.id, configId, e.target.checked.toString())
        success()
      }}
    />}><ListItemText primary={(lang.worlds as any)[name]} /></ListItem>
    : null

  return <Box sx={{ minHeight: '100%', py: 3 }}>
    <Toolbar />
    <Container maxWidth={false}>
      <Grid container spacing={3}>
        <Grid item lg={8} md={12} xl={9} xs={12}>
        <Card>
          <CardHeader title={lang.worlds.title} />
          <Divider />
          <Box sx={{ position: 'relative' }}>
            <TableContainer>
              <Table>
                <TableHead>
                  <TableRow>
                    <TableCell padding='checkbox' />
                    <TableCell>{lang.worlds.name}</TableCell>
                    {globalData.hasMultiverse && <TableCell>{lang.worlds.alias}</TableCell>}
                    <TableCell>{lang.worlds.players}</TableCell>
                    <TableCell>{lang.worlds.chunks}</TableCell>
                    <TableCell>{lang.worlds.entities}</TableCell>
                    <TableCell>{lang.worlds.tiles}</TableCell>
                    <TableCell>{lang.worlds.time}</TableCell>
                    <TableCell>{lang.worlds.weather}</TableCell>
                  </TableRow>
                </TableHead>
                <TableBody>
                  {worlds.map(it => <TableRow key={it.id}>
                    <TableCell padding='checkbox'><Checkbox checked={selected === it.id} onClick={() => setSelected(it.id)} /></TableCell>
                    <TableCell><Tooltip title={it.id}><span>{it.name}</span></Tooltip></TableCell>
                    {globalData.hasMultiverse && <TableCell>{it.alias}
                      <IconButton size='small' onClick={() => dialog(lang.inputValue, lang.worlds.alias).then(res => {
                        if (res == null) return
                        plugin.emit('worlds:set', it.id, 'alias', res)
                        success()
                      })}><Edit fontSize='small' /></IconButton>
                      </TableCell>}
                    <TableCell>{it.players}</TableCell>
                    <TableCell>{it.chunks}</TableCell>
                    <TableCell>{it.entities}</TableCell>
                    <TableCell>{it.tiles}</TableCell>
                    <TableCell><Countdown time={it.time} max={24000} interval={50} /></TableCell>
                    <TableCell><IconButton size='small' onClick={() => {
                      plugin.emit('worlds:weather', it.id)
                      success()
                    }}>
                      {React.createElement((it.weather === 1 ? WeatherRainy : it.weather === 2 ? WeatherLightningRainy : WbSunny) as any)}
                    </IconButton></TableCell>
                  </TableRow>)}
                </TableBody>
              </Table>
            </TableContainer>
          </Box>
        </Card>
        </Grid>
        <Grid item lg={4} md={6} xl={3} xs={12}>
          <Card>
            <CardHeader
              title={lang.operations}
              sx={{ position: 'relative' }}
              action={<Tooltip title={lang.worlds.save} placement='left'>
                <IconButton
                  size='small'
                  onClick={() => {
                    if (!sw) return
                    plugin.emit('worlds:save', sw.id)
                    success()
                  }}
                  sx={cardActionStyles}
                ><Save /></IconButton>
              </Tooltip>}
            />
            <Divider />
            <Box sx={{ position: 'relative' }}>
              {sw
                ? <List sx={{ width: '100%' }} component='nav'>
                  <ListItem secondaryAction={<ToggleButtonGroup
                    exclusive
                    color='primary'
                    size='small'
                    value={sw.difficulty}
                    onChange={(_, value) => {
                      plugin.emit('worlds:difficulty', sw.id, value)
                      success()
                    }}
                  >
                    {difficulties.map(it => <ToggleButton value={it.toUpperCase()} key={it}>{minecraft['options.difficulty.' + it]}</ToggleButton>)}
                  </ToggleButtonGroup>}><ListItemText primary={minecraft['options.difficulty']} /></ListItem>
                  <ListItem secondaryAction={<Switch checked={sw.pvp} onChange={e => {
                    plugin.emit('worlds:pvp', sw.id, e.target.checked)
                    success()
                  }} />}><ListItemText primary='PVP' /></ListItem>
                  {getSwitch('allowAnimals', 'spawning.animals.spawn')}
                  {getSwitch('allowMonsters', 'spawning.monsters.spawn')}
                  {globalData.hasMultiverse && <>
                    {getSwitch('allowFlight')}
                    {getSwitch('autoHeal')}
                    {getSwitch('hunger')}
                  </>}
                  <ListItem secondaryAction={globalData.canSetViewDistance
                    ? <IconButton
                      onClick={() => dialog({
                        content: lang.inputValue,
                        input: {
                          error: true,
                          type: 'number',
                          helperText: lang.invalidValue,
                          validator: (it: string) => /^\d+$/.test(it) && +it > 1 && +it < 33
                        }
                      }).then(res => {
                        if (!res) return
                        plugin.emit('worlds:viewDistance', sw.id, parseInt(res as any))
                        success()
                      })}
                    ><Edit /></IconButton>
                    : undefined}>
                    <ListItemText primary={lang.worlds.viewDistance + ': ' + sw.viewDistance} />
                  </ListItem>
                  <ListItem><ListItemText primary={minecraft['selectWorld.enterSeed']} secondary={sw.seed} /></ListItem>
                  <ListItemButton onClick={() => setOpen(!open)}>
                    <ListItemText primary={minecraft['selectWorld.gameRules']} />
                    {open ? <ExpandLess /> : <ExpandMore />}
                  </ListItemButton>
                  <Collapse in={open} timeout="auto" unmountOnExit>
                    <List component='div' dense disablePadding>
                      {sw.rules.map(([key, value]) => {
                        const isTrue = value === 'true'
                        const isBoolean = isTrue || value === 'false'
                        const isNumber = /^\d+$/.test(value)
                        return <ListItem
                          key={key}
                          sx={{ pl: 4 }}
                          secondaryAction={isBoolean
                            ? <Switch
                              checked={isTrue}
                              onChange={e => {
                                plugin.emit('worlds:rule', sw.id, key, e.target.checked.toString())
                                success()
                              }}
                            />
                            : <IconButton
                              onClick={() => dialog({
                                content: lang.inputValue,
                                input: isNumber
                                  ? {
                                      error: true,
                                      type: 'number',
                                      helperText: lang.invalidValue,
                                      validator: (it: string) => /^\d+$/.test(it)
                                    }
                                  : { }
                              }).then(res => {
                                if (res == null) return
                                plugin.emit('worlds:rule', sw.id, key, res)
                                success()
                              })}
                            ><Edit /></IconButton>}
                        >
                          <ListItemText primary={(minecraft['gamerule.' + key] || key) + (isBoolean ? '' : ': ' + value)} />
                        </ListItem>
                      })}
                    </List>
                  </Collapse>
                </List>
                : <CardContent><Empty /></CardContent>
              }
            </Box>
          </Card>
        </Grid>
      </Grid>
    </Container>
  </Box>
}
Example #27
Source File: AppNavbar.tsx    From sapio-studio with Mozilla Public License 2.0 4 votes vote down vote up
function ContractMenu(props: { relayout: () => void }) {
    const dispatch = useDispatch();
    const workspace = useSelector(selectWorkspace);
    const contractRef = React.useRef<HTMLLIElement>(null);
    const [contracts_open, setContractsOpen] = React.useState(false);

    return (
        <div>
            <ListItem
                disableGutters
                button={false}
                key={'Contract'}
                onClick={() => setContractsOpen(true)}
                ref={contractRef}
            >
                <ListItemIcon></ListItemIcon>
                <ListItemText primary={'Contract'} />
            </ListItem>
            <Menu
                anchorEl={contractRef.current}
                anchorOrigin={{
                    vertical: 'center',
                    horizontal: 'right',
                }}
                keepMounted
                open={contracts_open}
                onClose={() => setContractsOpen(false)}
            >
                <MenuItem
                    onClick={() => {
                        setContractsOpen(false);
                        dispatch(open_modal('LoadHex'));
                    }}
                >
                    Open Contract from Clipboard
                </MenuItem>
                <MenuItem
                    onClick={() => {
                        setContractsOpen(false);
                        dispatch(create_contract_from_file());
                    }}
                >
                    Open Contract from File
                </MenuItem>
                <MenuItem
                    onClick={() => {
                        setContractsOpen(false);
                        dispatch(open_modal('SaveHex'));
                    }}
                >
                    Save Contract
                </MenuItem>
                <MenuItem
                    onClick={() => {
                        setContractsOpen(false);
                        window.electron.sapio.load_wasm_plugin(workspace);
                    }}
                >
                    Load WASM Plugin
                </MenuItem>
                <MenuItem
                    onClick={async () => {
                        setContractsOpen(false);
                        const apis =
                            await window.electron.sapio.load_contract_list(
                                workspace
                            );
                        if ('err' in apis) {
                            alert(apis.err);
                            return;
                        }
                        dispatch(set_apis(apis.ok));
                        dispatch(switch_showing('ContractCreator'));
                    }}
                >
                    Create New Contract
                </MenuItem>
                <MenuItem
                    onClick={() => {
                        setContractsOpen(false);
                        dispatch(recreate_contract());
                    }}
                >
                    Recreate Last Contract
                </MenuItem>
                <Divider />
                <MenuItem
                    onClick={() => {
                        props.relayout();
                    }}
                >
                    Repair Layout
                </MenuItem>
            </Menu>
        </div>
    );
}
Example #28
Source File: DetailsModal.tsx    From frontend with MIT License 4 votes vote down vote up
function DetailsModal() {
  const { getDialogs } = DialogStore
  const handleClose = () => DialogStore.hide()
  const { t } = useTranslation()

  return (
    <>
      {getDialogs.map(({ id, show, title, row }) => {
        return (
          <Dialog
            key={id}
            onClose={handleClose}
            open={show}
            maxWidth="md"
            PaperProps={{ elevation: 5 }}
            BackdropProps={{ style: { opacity: 0.3 } }}>
            {title && <DialogTitle>{title}</DialogTitle>}
            <DialogContent dividers>
              {/* TODO: Extract concrete implementation and use generic one */}
              <Grid item xs={12}>
                <List>
                  <ListItem>
                    <ListItemText
                      primary={`${row.getValue(row.id, 'name')}`}
                      secondary={row.row.person.company}
                    />
                  </ListItem>
                  <ListItem>
                    <ListItemText primary={row.row.person.email} secondary={row.row.person.phone} />
                  </ListItem>
                  <ListItem>{dateFormatter(row.row.createdAt)}</ListItem>
                  <ListItem>
                    <Typography variant="body2">{row.row.message || row.row.comment}</Typography>
                  </ListItem>
                  <ListItem>
                    <Typography variant="caption">{row.row.person.id}</Typography>
                  </ListItem>
                  {'associationMember' in row.row &&
                    [
                      'associationMember',
                      'benefactorCampaign',
                      'benefactorPlatform',
                      'companyOtherText',
                      'companySponsor',
                      'companyVolunteer',
                      'partnerBussiness',
                      'partnerNpo',
                      'partnerOtherText',
                      'roleAssociationMember',
                      'roleBenefactor',
                      'roleCompany',
                      'rolePartner',
                      'roleVolunteer',
                      'volunteerBackend',
                      'volunteerDesigner',
                      'volunteerDevOps',
                      'volunteerFinancesAndAccounts',
                      'volunteerFrontend',
                      'volunteerLawyer',
                      'volunteerMarketing',
                      'volunteerProjectManager',
                      'volunteerQa',
                      'volunteerSecurity',
                    ].map((k, i) => (
                      <ListItem key={i}>
                        <ListItemText
                          primary={k}
                          secondary={row.row[k] ? <Check color="primary" /> : <Clear />}
                        />
                      </ListItem>
                    ))}
                </List>
              </Grid>
              {/*  */}
            </DialogContent>
            <DialogActions>
              <Button autoFocus onClick={handleClose} color="primary">
                {t('common:close')}
              </Button>
            </DialogActions>
          </Dialog>
        )
      })}
    </>
  )
}
Example #29
Source File: Scheduler.tsx    From NekoMaid with MIT License 4 votes vote down vote up
Scheduler: React.FC = () => {
  const plugin = usePlugin()
  const [id, setId] = useState(-1)
  let [tasks, setTasks] = useState<Task[]>([])
  const [name, setName] = useState('')
  const [cron, setCron] = useState('')
  const [values, setValues] = useState('')
  const [whenIdle, setWhenIdle] = useState(false)
  const [cronError, setCronError] = useState('')
  const save = () => plugin.emit('scheduler:update', (res: boolean) => {
    action(res)
    plugin.emit('scheduler:fetch', setTasks)
  }, JSON.stringify(tasks))
  useEffect(() => { plugin.emit('scheduler:fetch', setTasks) }, [])

  return <Box sx={{ minHeight: '100%', py: 3 }}>
    <Toolbar />
    <Container maxWidth={false}>
      <Grid container spacing={3}>
        <Grid item lg={4} md={12} xl={4} xs={12}>
          <Card>
            <CardHeader
              title={lang.scheduler.title}
              sx={{ position: 'relative' }}
              action={<IconButton
                size='small'
                onClick={() => {
                  const task = {
                    name: lang.scheduler.newTask,
                    cron: '*/1 * * * *',
                    enabled: true,
                    whenIdle: false,
                    values: ['/say Hello, %server_tps% (PlaceholderAPI)', 'This is a chat message']
                  }
                  setTasks([...tasks, task])
                  setId(tasks.length)
                  setCronError('')
                  setCron(task.cron)
                  setName(task.name)
                  setValues(task.values.join('\n'))
                  setWhenIdle(false)
                }}
                sx={cardActionStyles}
              ><Add /></IconButton>}
            />
            <Divider />
            {tasks.length
              ? <List
                sx={{ width: '100%' }}
                component='nav'
              >
                {tasks.map((it, i) => <ListItem
                  key={i}
                  disablePadding
                  secondaryAction={<IconButton
                    edge='end'
                    onClick={() => dialog(lang.scheduler.confirmDelete)
                      .then(it => {
                        if (it == null) return
                        setTasks((tasks = tasks.filter((_, id) => i !== id)))
                        save()
                      })}
                  ><Delete /></IconButton>}
                  sx={{ position: 'relative' }}
                >
                  <ListItemIcon sx={{ paddingLeft: 2, position: 'absolute' }}>
                    <Checkbox
                      edge='start'
                      checked={it.enabled}
                      tabIndex={-1}
                    />
                  </ListItemIcon>
                  <ListItemButton onClick={() => {
                    setId(i)
                    setCronError('')
                    setCron(tasks[i].cron)
                    setName(tasks[i].name)
                    setValues(tasks[i].values.join('\n'))
                    setWhenIdle(!!tasks[i].whenIdle)
                  }}><ListItemText inset primary={it.name} /></ListItemButton >
                </ListItem>)}
              </List>
              : <CardContent><Empty /></CardContent>}
          </Card>
        </Grid>
        <Grid item lg={8} md={12} xl={8} xs={12}>
          <Card>
            <CardHeader
              title={lang.scheduler.editor}
              sx={{ position: 'relative' }}
              action={<IconButton
                size='small'
                onClick={() => {
                  tasks[id].values = values.split('\n')
                  tasks[id].cron = cron
                  tasks[id].name = name
                  tasks[id].whenIdle = whenIdle
                  save()
                }}
                sx={cardActionStyles}
                disabled={!tasks[id] || !!cronError}
              ><Save /></IconButton>}
            />
            <Divider />
            <CardContent>
              {tasks[id]
                ? <>
                  <TextField
                    required
                    fullWidth
                    variant='standard'
                    label={lang.scheduler.name}
                    value={name}
                    onChange={e => setName(e.target.value)}
                  />
                  <TextField
                    fullWidth
                    multiline
                    rows={4}
                    value={values}
                    sx={{ marginTop: 3 }}
                    label={lang.scheduler.content}
                    onChange={e => setValues(e.target.value)}
                  />
                  <FormControlLabel
                    control={<Switch checked={whenIdle} />}
                    label={lang.scheduler.whenIdle}
                    onChange={(e: any) => setWhenIdle(e.target.checked)}
                  />
                </>
                : <Empty title={lang.scheduler.notSelected} />}
            </CardContent>
            {tasks[id] && <>
              <Divider textAlign='left'>{lang.scheduler.timer}</Divider>
              <CardContent>
                <Box sx={{
                  '& .MuiTextField-root': { backgroundColor: 'inherit!important' },
                  '& .MuiOutlinedInput-input': { color: 'inherit!important' },
                  '& .MuiTypography-h6': { color: theme => theme.palette.primary.main + '!important' }
                }}>
                  <Cron cron={cron} setCron={setCron} setCronError={setCronError} locale={currentLanguage as any} isAdmin />
                </Box>
              </CardContent>
            </>}
          </Card>
        </Grid>
      </Grid>
    </Container>
  </Box>
}