@chakra-ui/react#Td JavaScript Examples

The following examples show how to use @chakra-ui/react#Td. 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: components.js    From idena-web with MIT License 6 votes vote down vote up
export function FlipsValueTd(props) {
  return (
    <Td
      color="gray.500"
      fontWeight="500"
      px={[0, 3]}
      py={[2, 3 / 2]}
      {...props}
    />
  )
}
Example #2
Source File: BuilderListSkeleton.jsx    From scaffold-directory with MIT License 6 votes vote down vote up
BuilderListSkeleton = () => (
  <Box overflowX="auto">
    <Center mb={5}>
      <chakra.strong mr={2}>Total builders:</chakra.strong> <SkeletonText noOfLines={1} w={5} />
    </Center>
    <Table>
      <Thead>
        <Tr>
          <Th>Builder</Th>
          <Th>Challenges</Th>
          <Th>Socials</Th>
          <Th>Last Activity</Th>
        </Tr>
      </Thead>
      <Tbody>
        {[1, 2].map(lineNumber => {
          return (
            <Tr key={lineNumber}>
              <Td>
                <SkeletonAddress w="12.5" fontSize="16" />
              </Td>
              <Td>
                <SkeletonText noOfLines={1} py={2} />
              </Td>
              <Td>
                <SkeletonText noOfLines={1} py={2} />
              </Td>
              <Td>
                <SkeletonText noOfLines={1} py={2} />
              </Td>
            </Tr>
          );
        })}
      </Tbody>
    </Table>
  </Box>
)
Example #3
Source File: Table.js    From web-client with Apache License 2.0 6 votes vote down vote up
NotesTable = ({ notes, onDeleteButtonClick }) => {
    return <Table>
        <Thead>
            <Tr>
                <Th>Content</Th>
                <Th style={{ width: '200px' }}>Creation time</Th>
                <Th style={{ width: '140px' }}>Author</Th>
                <Th style={{ width: '140px' }}>Visibility</Th>
                <Th>&nbsp;</Th>
            </Tr>
        </Thead>
        <Tbody>
            {notes.length === 0 && <NoResultsTableRow numColumns={5} />}
            {notes.map((note, index) =>
                <Tr>
                    <Td><ReactMarkdown>{note.content}</ReactMarkdown></Td>
                    <Td><ReactTimeAgo date={note.insert_ts} /></Td>
                    <Td><UserLink userId={note.user_id}>{note.user_name}</UserLink></Td>
                    <Td><VisibilityLegend visibility={note.visibility} /></Td>
                    <Td>
                        <RestrictedComponent roles={['administrator', 'superuser', 'user']}>
                            <DeleteIconButton onClick={ev => onDeleteButtonClick(ev, note)} />
                        </RestrictedComponent>
                    </Td>
                </Tr>
            )}
        </Tbody>
    </Table>
}
Example #4
Source File: components.js    From idena-web with MIT License 6 votes vote down vote up
function TransactionsTd({children, ...props}) {
  return (
    <Td
      px={[0, 3]}
      py={3 / 2}
      borderBottomColor="gray.100"
      borderBottomWidth={[0, '1px']}
      {...props}
    >
      {children}
      <Divider
        display={['block', 'none']}
        color="gray.100"
        mt="6px"
        ml={14}
        w="auto"
      />
    </Td>
  )
}
Example #5
Source File: RecentDocumentsWidget.js    From web-client with Apache License 2.0 6 votes vote down vote up
RecentDocumentsWidget = () => {
    const [documents] = useFetch(`/documents?limit=5`)

    if (!documents) return <Loading />

    return <DashboardWidget title="Recent documents">

        {documents.length === 0 ?
            <p>No documents to show.</p>
            :
            <Table>
                <Thead>
                    <Tr>
                        <Th>Title</Th>
                        <Th>Created</Th>
                    </Tr>
                </Thead>
                <Tbody>
                    {documents.map(doc => <Tr key={doc.id}>
                        <Td><DocumentBadge key={doc.id} document={doc} /></Td>
                        <Td><RelativeDateFormatter date={doc.insert_ts} /></Td>
                    </Tr>)}
                </Tbody>
            </Table>
        }
    </DashboardWidget>
}
Example #6
Source File: components.js    From idena-web with MIT License 6 votes vote down vote up
export function ValidationReportColumn(props) {
  return (
    <Td
      fontWeight={500}
      borderBottomWidth={[0, '1px']}
      px={[0, 2]}
      py={3 / 2}
      {...props}
    />
  )
}
Example #7
Source File: RecentActivityWidget.js    From web-client with Apache License 2.0 6 votes vote down vote up
RecentActivityWidget = () => {
    const [auditLog] = useFetch('/auditlog?limit=5');

    return <DashboardWidget title="Recent activity">

        {auditLog && auditLog.length > 0 ?
            <Table>
                <Thead>
                    <Tr>
                        <Th>Action</Th>
                        <Th>User</Th>
                        <Th>Date/Time</Th>
                    </Tr>
                </Thead>
                <Tbody>
                    {auditLog.map(log => <Tr key={log.id}>
                        <Td><Badge>{log.action}</Badge></Td>
                        <Td>{log.user_name ?
                            <UserLink userId={log.user_id}>{log.user_name}</UserLink> : '-'}</Td>
                        <Td>{log.insert_ts}</Td>
                    </Tr>)}
                </Tbody>
            </Table> :
            <p>No activity to show.</p>
        }
    </DashboardWidget>
}
Example #8
Source File: TechStack.js    From benjamincarlson.io with MIT License 5 votes vote down vote up
TechStack = () => {
    const { colorMode } = useColorMode()

    const colorSecondary = {
        light: 'gray.600',
        dark: 'gray.400'
    }

    const linkColor = {
        light: 'blue.400',
        dark: 'blue.600'
    }

    return (
        <Box as="section" w="100%" mt={10} mb={20}>
            <Heading letterSpacing="tight" size="lg" fontWeight={700} as="h2" mb={4}>
                Tech Stack ⚙️
            </Heading>
            <Text color={colorSecondary[colorMode]} mb={4}>Each piece of technology used in this website is carefully thought out. I believe this is one of the best stacks there is to build websites of any size and domain.</Text>
            <Box flexDir="column" overflowX="auto">
                <Table variant="simple">
                    <Thead>
                        <Tr>
                            <Th>Type</Th>
                            <Th>Name</Th>
                            <Th>Route</Th>
                            <Th>Description</Th>
                        </Tr>
                    </Thead>
                    <Tbody>
                        <Tr>
                            <Td>JS Framework</Td>
                            <Td><Link href="https://nextjs.org" color={linkColor[colorMode]} isExternal>Next JS</Link></Td>
                            <Td>n/a</Td>
                            <Td>Next.js was an easy choice given its large community and ability for rapid development.</Td>
                        </Tr>
                        <Tr>
                            <Td>CSS Framework</Td>
                            <Td><Link href="https://chakra-ui.com" color={linkColor[colorMode]} isExternal>Chakra UI</Link></Td>
                            <Td>n/a</Td>
                            <Td>I use Chakra UI because its components make a beautiful UI out of the box and are highly customizable.</Td>
                        </Tr>
                        <Tr>
                            <Td>Blog</Td>
                            <Td><Code>next-mdx-remote</Code></Td>
                            <Td>/blog/[slug].js</Td>
                            <Td>I use <Link href="https://github.com/hashicorp/next-mdx-remote" color={linkColor[colorMode]} isExternal>next-mdx-remote</Link> for my blog. Posts are stored in <Code>mdx</Code> files and pre-rendered.</Td>
                        </Tr>
                        <Tr>
                            <Td>Real-Time Statistics</Td>
                            <Td>Next.js api routes</Td>
                            <Td>/api/[].js</Td>
                            <Td>Multiple api routes that interact with the GitHub, YouTube, and Strava api to fetch my real-time social media data using Next.JS <Link href="https://nextjs.org/docs/api-routes/introduction" color={linkColor[colorMode]} isExternal>serverless functions</Link>.</Td>
                        </Tr>
                        <Tr>
                            <Td>Realtime Blog Post View/Like Count</Td>
                            <Td>Firebase Realtime Db</Td>
                            <Td>/api</Td>
                            <Td>I use <Link href="https://firebase.google.com" color={linkColor[colorMode]} isExternal>Google's Firebase</Link> to store view and like counts for my blog posts.</Td>
                        </Tr>
                        <Tr>
                            <Td>Deployment</Td>
                            <Td>Vercel</Td>
                            <Td>n/a</Td>
                            <Td>I use <Link href="https://vercel.com" color={linkColor[colorMode]} isExternal>Vercel</Link> to deploy my app. It's free, fast, integrates with GitHub, and overall a great experience.</Td>
                        </Tr>
                        <Tr>
                            <Td>Domain</Td>
                            <Td>Namecheap</Td>
                            <Td>n/a</Td>
                            <Td>My domain name is bought and stored through <Link color="blue.500" href="https://www.namecheap.com/" isExternal>Namecheap</Link>.</Td>
                        </Tr>
                    </Tbody>
                </Table>
            </Box>
        </Box>
    )
}
Example #9
Source File: List.js    From web-client with Apache License 2.0 5 votes vote down vote up
NotificationsList = () => {
    const [notifications, fetchNotifications] = useFetch('/notifications')

    const markNotificationAsRead = notification => {
        secureApiFetch(`/notifications/${notification.id}`, {
            method: 'PUT',
            body: JSON.stringify({ status: 'read' })
        }).then(() => {
            fetchNotifications();
        })
    }

    const deleteNotification = useDelete('/notifications/', fetchNotifications);

    return <>
        <PageTitle value="Notifications" />
        <div className='heading'>
            <Breadcrumb />
        </div>
        <Title title='Notifications' icon={<BellIcon />} />

        <Table>
            <Thead>
                <Tr>
                    <Th w={50}>&nbsp;</Th>
                    <Th w={200}>Date/time</Th>
                    <Th>Content</Th>
                    <Th>&nbsp;</Th>
                </Tr>
            </Thead>
            <Tbody>
                {null === notifications && <LoadingTableRow numColumns={3} />}
                {null !== notifications && notifications.length === 0 && <NoResultsTableRow numColumns={3} />}
                {null !== notifications && notifications.length > 0 &&
                    notifications.map(notification =>
                        <Tr key={notification.id}>
                            <Th>{notification.status === 'read' ? <FontAwesomeIcon icon={faCheck} /> : <>&nbsp;</>}</Th>
                            <Td><RelativeDateFormatter date={notification.insert_ts} /></Td>
                            <Td>
                                <strong>{notification.title}</strong>
                                <div>{notification.content}</div>
                            </Td>
                            <Td textAlign="right">
                                <ButtonGroup>
                                    {notification.status === 'unread' && <Button onClick={() => markNotificationAsRead(notification)} leftIcon={<FontAwesomeIcon icon={faCheck} />}>Mark as read</Button>}
                                    <DeleteIconButton onClick={() => deleteNotification(notification.id)} />
                                </ButtonGroup>
                            </Td>
                        </Tr>
                    )
                }
            </Tbody>
        </Table>
    </>
}
Example #10
Source File: Cart.js    From react-sample-projects with MIT License 5 votes vote down vote up
Cart = () => {
  const dispatch = useDispatch();
  const navigate = useNavigate();
  const cartItems = useSelector(state => state.cart.cartItems);

  const viewProductDetails = (e, item) => {
    navigate(`/product/${item.id}`);
  };

  const deleteItem = (e, item) => {
    e.stopPropagation();
    e.preventDefault();
    dispatch(deleteItemFromCart(item));
  };

  if (cartItems.length === 0) {
    return (
      <Flex>
        <Box
          m={4}
          w="100%"
          fontWeight="semibold"
          letterSpacing="wide"
          textAlign="center"
        >
          You cart empty :(
        </Box>
      </Flex>
    );
  }
  return (
    <Box m={3} p={3}>
      <Table variant="simple">
        <Thead>
          <Tr>
            <Th>#</Th>
            <Th>Image</Th>
            <Th>Title</Th>
            <Th isNumeric>Price</Th>
            <Th isNumeric>Quantity</Th>
            <Th>Action</Th>
          </Tr>
        </Thead>
        <Tbody>
          {cartItems.map((item, index) => (
            <Tr key={item.id} onClick={e => viewProductDetails(e, item)}>
              <Td>{index + 1}</Td>
              <Td>
                <Avatar size={'sm'} src={item.image} alt={item.title} />
              </Td>
              <Td>{item.title}</Td>
              <Td isNumeric>
                ${parseFloat(item.price * item.quantity).toFixed(2)}
              </Td>
              <Td isNumeric>{item.quantity}</Td>
              <Td>
                <Button onClick={e => deleteItem(e, item)}>Delete</Button>
              </Td>
            </Tr>
          ))}
        </Tbody>
      </Table>
    </Box>
  );
}
Example #11
Source File: SubmissionReviewTableSkeleton.jsx    From scaffold-directory with MIT License 5 votes vote down vote up
ChallengesTableSkeleton = () => (
  <Box overflowX="auto">
    <Table mb={4}>
      <Thead>
        <Tr>
          <Th>Builder</Th>
          <Th>Challenge</Th>
          <Th>Contract</Th>
          <Th>Live demo</Th>
          <Th>Submitted time</Th>
          <Th>Actions</Th>
        </Tr>
      </Thead>
      <Tbody>
        {[1, 2].map(lineNumber => {
          return (
            <Tr key={lineNumber}>
              <Td>
                <SkeletonAddress w="12.5" fontSize="16" />
              </Td>
              <Td>
                <SkeletonText noOfLines={1} py={4} />
              </Td>
              <Td>
                <SkeletonText noOfLines={1} py={4} />
              </Td>
              <Td>
                <SkeletonText noOfLines={1} py={4} />
              </Td>
              <Td>
                <SkeletonText noOfLines={1} py={4} />
              </Td>
              <Td>
                <Skeleton startColor="blue.100" endColor="blue.500">
                  <Button type="button" size="xs">
                    Review
                  </Button>
                </Skeleton>
              </Td>
            </Tr>
          );
        })}
      </Tbody>
    </Table>
  </Box>
)
Example #12
Source File: AuditLogsTable.js    From web-client with Apache License 2.0 5 votes vote down vote up
AuditLogsTable = ({ auditLog, hideUserColumns = false }) => {
    const numColumns = hideUserColumns ? 4 : 6;

    return <Table>
        <Thead>
            <Tr>
                <Th>Event</Th>
                <Th>IP address</Th>
                <Th>User agent</Th>
                <Th>Date/Time</Th>
                {!hideUserColumns &&
                    <>
                        <Th>User</Th>
                        <Th>Role</Th>
                    </>
                }
                <Th>Data</Th>
            </Tr>
        </Thead>
        <Tbody>
            {auditLog !== null && auditLog.length === 0 && <NoResultsTableRow numColumns={numColumns} />}
            {auditLog !== null && auditLog.map(entry => {
                return <Tr key={entry.id}>
                    <Td>
                        <Badge>{entry.action}</Badge>
                    </Td>
                    <Td><Ipv4Link value={entry.client_ip} /></Td>
                    <Td>{entry.user_agent ? <UserAgentLabel userAgent={entry.user_agent} /> : '-'}</Td>
                    <Td>{entry.insert_ts}</Td>
                    {!hideUserColumns &&
                        <>
                            <Td>{entry.user_name ?
                                <UserLink userId={entry.user_id}>{entry.user_name}</UserLink> : '-'}</Td>
                            <Td><UserRoleBadge role={entry.user_role} /></Td>
                        </>
                    }
                    <Td>{entry.object}</Td>
                </Tr>
            })}
        </Tbody>
    </Table>
}
Example #13
Source File: components.js    From idena-web with MIT License 5 votes vote down vote up
export function ValidationReportTd(props) {
  return <Td color="gray.500" fontWeight="500" px={3} py={3 / 2} {...props} />
}
Example #14
Source File: Targets.js    From web-client with Apache License 2.0 4 votes vote down vote up
ProjectTargets = ({ project }) => {
    const query = useQuery();
    const urlPageNumber = query.get('page') !== null ? parseInt(query.get('page')) : 1;
    const [pageNumber, setPageNumber] = useState(urlPageNumber);

    const [numberPages, setNumberPages] = useState(1);
    const [targets, setTargets] = useState([]);

    const { isOpen: isAddTargetDialogOpen, onOpen: openAddTargetDialog, onClose: closeAddTargetDialog } = useDisclosure();

    const onDeleteButtonClick = (ev, targetId) => {
        ev.preventDefault();

        secureApiFetch(`/targets/${targetId}`, { method: 'DELETE' })
            .then(() => {
                reloadTargets();
            })
    }

    const onTargetFormSaved = () => {
        reloadTargets();
        closeAddTargetDialog();
    }

    const reloadTargets = useCallback(() => {
        setTargets([]);

        secureApiFetch(`/targets?projectId=${project.id}&page=${pageNumber - 1}`, { method: 'GET' })
            .then(resp => {
                if (resp.headers.has('X-Page-Count')) {
                    setNumberPages(resp.headers.get('X-Page-Count'))
                }
                return resp.json()
            })
            .then(data => {
                setTargets(data);
            });
    }, [pageNumber, project]);

    const onPrevPageClick = () => {
        setPageNumber(pageNumber - 1);
    }
    const onNextPageClick = () => {
        setPageNumber(pageNumber + 1);
    }

    useEffect(() => {
        reloadTargets()
    }, [reloadTargets])

    return <section>
        <h4>
            <IconServer />Targets
            <RestrictedComponent roles={['administrator', 'superuser', 'user']}>
                <ButtonGroup>
                    <TargetModalDialog project={project} isOpen={isAddTargetDialogOpen} onSubmit={onTargetFormSaved} onCancel={closeAddTargetDialog} />
                    <CreateButton onClick={openAddTargetDialog}>Add target...</CreateButton>
                </ButtonGroup>
            </RestrictedComponent>
        </h4>
        {!targets ? <Loading /> :
            <>
                {numberPages > 1 && <Center>
                    <Pagination page={pageNumber - 1} total={numberPages} handlePrev={onPrevPageClick} handleNext={onNextPageClick} />
                </Center>}
                <Table>
                    <Thead>
                        <Tr>
                            <Th>Name</Th>
                            <Th>Sub-target</Th>
                            <Th>Kind</Th>
                            <Th>Vulnerable?</Th>
                            <Th>&nbsp;</Th>
                        </Tr>
                    </Thead>
                    <Tbody>
                        {targets.length === 0 && <NoResultsTableRow numColumns={4} />}
                        {targets.map((target, index) =>
                            <Tr key={index}>
                                <Td>
                                    {target.parent_id === null &&
                                        <HStack>
                                            <Link to={`/targets/${target.id}`}><TargetBadge name={target.name} /></Link>
                                        </HStack>
                                    }
                                    {target.parent_id !== null &&
                                        <>{target.parent_name ?? '-'}</>
                                    }
                                </Td>
                                <Td>{target.parent_id !== null ?
                                    <>
                                        <Link to={`/targets/${target.id}`}><TargetBadge name={target.name} /></Link>
                                    </> : '-'}</Td>
                                <Td>{target.kind} <Tags values={target.tags} /></Td>
                                <Td>{target.num_vulnerabilities > 0 ? `Yes (${target.num_vulnerabilities} vulnerabilities found)` : "No"}</Td>
                                <Td>
                                    <RestrictedComponent roles={['administrator', 'superuser', 'user']}>
                                        <DeleteIconButton onClick={ev => onDeleteButtonClick(ev, target.id)} />
                                    </RestrictedComponent>
                                </Td>
                            </Tr>
                        )}
                    </Tbody>
                </Table>
            </>
        }
    </section>
}
Example #15
Source File: ActivityPage.js    From DAOInsure with MIT License 4 votes vote down vote up
function ActivityPage() {
	const [data, setData] = useState();

	const [loadingData, setLoadingData] = useState();
	useEffect(() => {
		async function init() {
			setLoadingData(true);
			// querying superfluid subgraph to create pie diagram of flow towards DAO Contract
			const response = await axios.post(
				"https://api.thegraph.com/subgraphs/name/superfluid-finance/superfluid-mumbai",
				{
					query: `
                    {
                        flows(where:{ recipient: "0xb77963bfd55f5246068c09a2048fa3ab310e4a17" }) {
                        id
                        flowRate
                        lastUpdate
                            owner {
                                id
                            }
                        }
                    }
                `,
				}
			);

			let datas = [];

			response.data.data.flows.map((flow) => {
				let secondsElapsed =
					Math.floor(Date.now() / 1000) - parseInt(flow.lastUpdate);
				let outFlowed = web3.utils.fromWei(
					web3.utils
						.toBN(flow.flowRate)
						.mul(web3.utils.toBN(secondsElapsed))
						.toString(),
					"ether"
				);
				let obj = {
					id: flow.owner.id,
					label: flow.owner.id,
					value: outFlowed,
					flowRate: web3.utils.toBN(flow.flowRate),
					sumInWei: web3.utils
						.toBN(flow.flowRate)
						.mul(web3.utils.toBN(secondsElapsed)),
				};
				datas.push(obj);
			});
			setData(datas);
			setLoadingData(false);
		}
		init();
	}, [data]);

	useEffect(() => {
		if (data != undefined) {
			setTimeout(() => {
				for (let i = 0; i < data.length; i++) {
					data[i].value = web3.utils
						.fromWei(data[i].sumInWei.add(data[i].flowRate))
						.toString();
					data[i].sumInWei = data[i].sumInWei.add(data[i].flowRate);
				}
				setData(data);
			}, 1000);
		}
	}, [data]);

	return (
		<Grid px='250px' gridGap='10px' py='20px'>
			<Heading fontSize='24px' color='whatsapp.500'>
				Members
			</Heading>
			<Box height='400px'>
				{loadingData ? <Spinner /> : <MyResponsivePie data={data} />}
			</Box>
			<Table>
				<Thead>
					<Tr>
						<Th>Address</Th>
						<Th>outFlowed</Th>
					</Tr>
				</Thead>
				<Tbody>
					{data == undefined ? (
						<Spinner />
					) : (
						<>
							{data.map((data, index) => {
								return (
									<Tr>
										<Td>
											<GreenTag>{data.id}</GreenTag>
										</Td>
										<Td>{data.value}</Td>
									</Tr>
								);
							})}
						</>
					)}
				</Tbody>
			</Table>
		</Grid>
	);
}
Example #16
Source File: VulnerabilitiesTable.js    From web-client with Apache License 2.0 4 votes vote down vote up
VulnerabilitiesTable = ({ tableModel, tableModelSetter: setTableModel, reloadCallback, showSelection = true, showProjectColumn = true }) => {
    const onSortChange = (ev, column, order) => {
        ev.preventDefault();

        setTableModel({ ...tableModel, sortBy: { column: column, order: order } })
    }

    const onSelectionChange = ev => {
        const target = ev.target;
        const selectionId = parseInt(target.value);
        if (target.checked) {
            setTableModel({ ...tableModel, selection: [...tableModel.selection, selectionId] })
        } else {
            setTableModel({ ...tableModel, selection: tableModel.selection.filter(value => value !== selectionId) })
        }
    };

    const onHeaderCheckboxClick = ev => {
        if (ev.target.checked) {
            setTableModel({ ...tableModel, selection: tableModel.vulnerabilities.map(vulnerability => vulnerability.id) })
        } else {
            setTableModel({ ...tableModel, selection: [] })
        }
    }

    const numColumns = 6 + (showSelection ? 1 : 0) + (showProjectColumn ? 1 : 0);
    const vulnerabilitiesLength = null !== tableModel.vulnerabilities ? tableModel.vulnerabilities.length : 0;

    const deleteVulnerability = useDelete('/vulnerabilities/', reloadCallback, 'Do you really want to delete this vulnerability?', 'The vulnerability has been deleted.');

    return <Table>
        <Thead>
            <Tr>
                {showSelection && <Th style={{ width: "32px", textAlign: "left" }}><Checkbox onChange={onHeaderCheckboxClick} isChecked={tableModel.selection.length && tableModel.selection.length === vulnerabilitiesLength} isDisabled={tableModel.vulnerabilitiesLength === 0} /></Th>}
                <Th style={{ width: '190px' }}>Summary</Th>
                {showProjectColumn && <Th style={{ width: '190px' }}>Project</Th>}
                <Th style={{ width: '120px' }}><DescendingSortLink callback={onSortChange} property="status" /> Status <AscendingSortLink callback={onSortChange} property="status" /></Th>
                <Th style={{ width: '120px' }}><DescendingSortLink callback={onSortChange} property="risk" /> Risk <AscendingSortLink callback={onSortChange} property="risk" /></Th>
                <Th style={{ width: '120px' }}><DescendingSortLink callback={onSortChange} property="cvss_score" /> <abbr title="Common Vulnerability Scoring System">CVSS</abbr> score <AscendingSortLink callback={onSortChange} property="cvss_score" /></Th>
                <Th className='only-desktop' style={{ width: '20%' }}><DescendingSortLink callback={onSortChange} property="category_name" /> Category <AscendingSortLink callback={onSortChange} property="category_name" /></Th>
                <Th style={{ width: '15%', textAlign: 'right' }}><ReloadButton onClick={reloadCallback} /></Th>
            </Tr>
        </Thead>
        <Tbody>
            {null === tableModel.vulnerabilities &&
                <LoadingTableRow numColumns={numColumns} />}
            {null !== tableModel.vulnerabilities && 0 === tableModel.vulnerabilities.length &&
                <NoResultsTableRow numColumns={numColumns} />}
            {null !== tableModel.vulnerabilities && tableModel.vulnerabilities.length > 0 &&
                tableModel.vulnerabilities.map((vulnerability, index) => {
                    return <Tr key={index}>
                        {showSelection &&
                            <Td>
                                <Checkbox
                                    value={vulnerability.id}
                                    onChange={onSelectionChange}
                                    isChecked={tableModel.selection.includes(vulnerability.id)}
                                />
                            </Td>
                        }
                        <Td>
                            <Stack>
                                <VulnerabilityBadge vulnerability={vulnerability} />
                                <div><Tags values={vulnerability.tags} /></div>
                            </Stack>
                        </Td>
                        {showProjectColumn && <Td>{vulnerability.is_template ? <span title="Not applicable">(n/a)</span> : <ProjectBadge project={{ id: vulnerability.project_id, name: vulnerability.project_name }} />}</Td>}
                        <Td><VulnerabilityStatusBadge vulnerability={vulnerability} /></Td>
                        <Td><RiskBadge risk={vulnerability.risk} /></Td>
                        <Td><CvssScore score={vulnerability.cvss_score} /></Td>
                        <Td className='only-desktop'>
                            <VulnerabilityCategorySpan name={vulnerability.category_name} parentName={vulnerability.parent_category_name} />
                        </Td>
                        <Td textAlign="right">
                            <RestrictedComponent roles={['administrator', 'superuser', 'user']}>
                                <LinkButton href={`/vulnerabilities/${vulnerability.id}/edit`}>Edit</LinkButton>
                                {reloadCallback &&
                                    <DeleteIconButton onClick={() => deleteVulnerability(vulnerability.id)} />
                                }
                            </RestrictedComponent>
                        </Td>
                    </Tr>
                })}
        </Tbody>
    </Table>
}
Example #17
Source File: rent.js    From idena-web with MIT License 4 votes vote down vote up
export default function Rent() {
  const router = useRouter()
  const {t} = useTranslation()

  const {coinbase} = useAuthState()

  const buySharedNodeDisclosure = useDisclosure()

  const [state, setState] = useState(0)

  const [checkedProviders, setCheckedProviders] = useState([])

  const {
    data: indexerData,
    isFetched: indexerIsFetched,
    isLoading: indexerIsLoading,
  } = useQuery(['last-block'], () => getLastBlock(), {
    retry: false,
    refetchOnWindowFocus: false,
  })

  const {data: identity, isLoading: identityIsLoading} = useQuery(
    ['fetch-identity', coinbase],
    () => fetchIdentity(coinbase, true),
    {
      enabled: !!coinbase,
      refetchOnWindowFocus: false,
    }
  )

  const {data: providers, isLoading: providersIsLoading} = useQuery(
    ['providers'],
    getProviders,
    {
      initialData: [],
      enabled: !!indexerIsFetched,
      refetchOnWindowFocus: false,
    }
  )

  const indexerLastBlock = indexerData?.height || 0

  useEffect(() => {
    async function updateStatus() {
      const shuffled = shuffle(providers.filter(x => Boolean(x.slots)))
      shuffled.forEach(provider => {
        checkProviderSyncing(provider.data.url)
          .then(response =>
            setCheckedProviders(prev => {
              const blocksLeft = indexerLastBlock - response?.currentBlock
              return mergeProviders(prev, {
                ...provider,
                duration: response.duration,
                blocksLeft,
                status:
                  blocksLeft > SYNCING_DIFF
                    ? ProviderStatus.OutOfSync
                    : ProviderStatus.Success,
              })
            })
          )
          .catch(() =>
            setCheckedProviders(prev =>
              mergeProviders(prev, {
                ...provider,
                duration: MAX_DURATION,
                status: ProviderStatus.Error,
              })
            )
          )
      })
    }
    if (providers.length) updateStatus()
  }, [indexerLastBlock, providers])

  const isLoading = indexerIsLoading || identityIsLoading || providersIsLoading

  const isDesktop = useIsDesktop()

  const {
    isOpen: isOpenRentDetailDrawer,
    onOpen: onOpenRentDetailDrawer,
    onClose: onCloseRentDetailDrawer,
  } = useDisclosure()

  const selectedProvider = checkedProviders.length && checkedProviders[state]

  return (
    <Layout canRedirect={false}>
      <Page mb={14} pt={[4, 6]}>
        <Box w="full">
          <Flex align="center" justify="space-between">
            <AngleArrowBackIcon
              stroke="#578FFF"
              display={['block', 'none']}
              position="absolute"
              left={4}
              top={4}
              h="28px"
              w="28px"
              onClick={() => {
                router.back()
              }}
            />
            <PageTitleNew>{t('Rent a shared node')}</PageTitleNew>
            <CloseButton
              display={['none', 'flex']}
              onClick={() => router.back()}
            />
          </Flex>
          <Box>
            <Table>
              <Thead display={['none', 'table-header-group']}>
                <Tr>
                  <RoundedTh isLeft width={rem(40)}></RoundedTh>
                  <RoundedTh>{t('Node URL')}</RoundedTh>
                  <RoundedTh>{t('Owner')}</RoundedTh>
                  <RoundedTh>{t('Location')}</RoundedTh>
                  <RoundedTh>{t('Latency, sec')}</RoundedTh>
                  <RoundedTh textAlign="right">
                    {t('Slots available')}
                  </RoundedTh>
                  <RoundedTh isRight textAlign="right">
                    {t('Price per validation')}
                  </RoundedTh>
                </Tr>
              </Thead>
              <Tbody>
                {isLoading
                  ? new Array(10).fill(0).map((_, idx) => (
                      <Tr key={idx}>
                        <Td colSpan={7} px={0}>
                          <Skeleton h={[32, 8]} />
                        </Td>
                      </Tr>
                    ))
                  : checkedProviders.map((p, idx) => (
                      <Tr key={idx}>
                        <Td display={['none', 'table-cell']}>
                          <Radio
                            isChecked={state === idx}
                            onClick={() => setState(idx)}
                            borderColor="#d2d4d9"
                          />
                        </Td>
                        <Td
                          borderBottom={['solid 0px', 'solid 1px #e8eaed']}
                          px={[0, 3]}
                          py={[1, 2]}
                        >
                          <Flex
                            direction="column"
                            border={['solid 1px', 'initial']}
                            borderColor={['gray.100', 'inherit']}
                            borderRadius={['8px', 0]}
                            p={[4, 0]}
                            onClick={() => {
                              setState(idx)
                              if (!isDesktop) onOpenRentDetailDrawer()
                            }}
                          >
                            <Flex justifyContent="flex-start">
                              <Flex
                                direction="column"
                                maxW={['100%', 'initial']}
                              >
                                <Text
                                  fontSize={['mdx', 'md']}
                                  fontWeight={[500, 400]}
                                  isTruncated
                                >
                                  {p.data.url}
                                </Text>
                                <ProviderStatusLabel
                                  status={p.status}
                                  blocksLeft={p.blocksLeft}
                                ></ProviderStatusLabel>
                              </Flex>
                              <Flex display="none">
                                <Text
                                  fontSize="mdx"
                                  fontWeight={500}
                                  color="gray.064"
                                >
                                  FILL_RATING
                                </Text>
                                <SoftStarIcon mt="3px" ml="3px" h={4} w={4} />
                              </Flex>
                            </Flex>
                            <Flex
                              display={['flex', 'none']}
                              justifyContent="flex-start"
                            >
                              <Flex
                                direction="column"
                                fontSize="base"
                                color="gray.064"
                                mt={4}
                                w="50%"
                              >
                                <Text>{t('Latency, sec')}</Text>
                                <Flex>
                                  <Text color="gray.500" mr={1}>
                                    {p.status === ProviderStatus.Error
                                      ? '—'
                                      : (p.duration / 1000).toFixed(3)}
                                  </Text>
                                  <Text display="none">/ FILL_SLOTS</Text>
                                </Flex>
                              </Flex>
                              <Flex
                                direction="column"
                                fontSize="base"
                                color="gray.064"
                                mt={4}
                                w="50%"
                              >
                                <Text>Price</Text>
                                <Flex>
                                  <Text color="gray.500">
                                    {GetProviderPrice(
                                      p.data,
                                      identity?.state,
                                      identity?.age
                                    )}{' '}
                                    iDNA
                                  </Text>
                                </Flex>
                              </Flex>
                            </Flex>
                          </Flex>
                        </Td>
                        <Td display={['none', 'table-cell']}>
                          <Link
                            target="_blank"
                            rel="noreferrer"
                            color="brandBlue.100"
                            href={`https://t.me/${p.data.ownerName}`}
                          >
                            {p.data.ownerName}
                          </Link>
                        </Td>
                        <Td display={['none', 'table-cell']}>
                          {p.data.location}
                        </Td>
                        <Td display={['none', 'table-cell']}>
                          {p.status === ProviderStatus.Error
                            ? '—'
                            : (p.duration / 1000).toFixed(3)}
                        </Td>
                        <Td display={['none', 'table-cell']} textAlign="right">
                          {p.slots}
                        </Td>
                        <Td display={['none', 'table-cell']} textAlign="right">
                          {GetProviderPrice(
                            p.data,
                            identity?.state,
                            identity?.age
                          )}{' '}
                          iDNA
                        </Td>
                      </Tr>
                    ))}
              </Tbody>
            </Table>
          </Box>
        </Box>
        <Stack
          display={['none', 'flex']}
          isInline
          spacing={2}
          justify="flex-end"
          bg="white"
          borderTop="1px"
          borderTopColor="gray.100"
          px={4}
          py={3}
          h={14}
          position="fixed"
          bottom={0}
          left={0}
          right={0}
        >
          <SecondaryButton onClick={router.back}>Cancel</SecondaryButton>
          <PrimaryButton onClick={buySharedNodeDisclosure.onOpen}>
            {t('Continue')}
          </PrimaryButton>
        </Stack>
      </Page>

      {selectedProvider && identity && (
        <ProviderInfoDrawer
          p={selectedProvider}
          identity={identity}
          isOpen={isOpenRentDetailDrawer}
          onClose={onCloseRentDetailDrawer}
          onSubmit={buySharedNodeDisclosure.onOpen}
        />
      )}

      <BuySharedNodeForm
        {...buySharedNodeDisclosure}
        providerId={selectedProvider && selectedProvider.id}
        url={selectedProvider && selectedProvider.data.url}
        from={coinbase}
        amount={
          selectedProvider &&
          GetProviderPrice(
            selectedProvider.data,
            identity?.state,
            identity?.age
          )
        }
        to={selectedProvider && selectedProvider.data.address}
      />
    </Layout>
  )
}
Example #18
Source File: List.js    From web-client with Apache License 2.0 4 votes vote down vote up
ReportTemplatesList = () => {
    const [templates, refetchTemplates] = useFetch('/reports/templates')

    const destroy = useDelete('/reports/', refetchTemplates);

    const deleteTemplate = (ev, templateId) => {
        ev.stopPropagation();

        destroy(templateId);
    }

    const { isOpen: isAddReportTemplateDialogOpen, onOpen: openAddReportTemplateDialog, onClose: closeAddReportTemplateDialog } = useDisclosure();

    const onReportTemplateFormSaved = () => {
        refetchTemplates();
        closeAddReportTemplateDialog();
    }

    const handleDownload = (reportId) => {
        secureApiFetch(`/attachments/${reportId}`, { method: 'GET', headers: {} })
            .then(resp => {
                const contentDispositionHeader = resp.headers.get('Content-Disposition');
                const filenameRe = new RegExp(/filename="(.*)";/)
                const filename = filenameRe.exec(contentDispositionHeader)[1]
                return Promise.all([resp.blob(), filename]);
            })
            .then((values) => {
                const blob = values[0];
                const filename = values[1];
                const url = URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = url;
                a.download = filename;
                a.click();
            })
    }

    const safeResolveMime = mimeType => {
        try {
            return resolveMime(mimeType)['name']
        } catch (err) {
            console.error(err);
            return mimeType;
        }
    }
    return <>
        <PageTitle value="Report templates" />
        <div className='heading'>
            <Breadcrumb>
                <Link to="/reports">Reports</Link>
            </Breadcrumb>

            <ReportModalDialog isOpen={isAddReportTemplateDialogOpen} onSubmit={onReportTemplateFormSaved} onCancel={closeAddReportTemplateDialog} />
            <CreateButton onClick={openAddReportTemplateDialog}>Add report template...</CreateButton>
        </div>
        <Title title='Report templates' icon={<IconDocumentDuplicate />} />

        <Alert status="info">
            <AlertIcon />
            Needing some inspiration? Have a look at hundred of penetration test reports available at&nbsp;<ExternalLink href="http://pentestreports.com/">http://pentestreports.com/</ExternalLink>
        </Alert>

        <Alert status="info">
            <AlertIcon />
            Visit this <ExternalLink href={UserManualUrl + 'reports/report-template-variables.html'}>user manual's page</ExternalLink> if you want to find out which variables are available to your report templates.
        </Alert>

        {!templates ? <Loading /> :
            <Table variant="simple">
                <Thead>
                    <Tr>
                        <Th style={{ width: '190px' }}>Name</Th>
                        <Th>Description</Th>
                        <Th style={{ width: '190px' }}>File name</Th>
                        <Th>Mime type</Th>
                        <Th>Downloads</Th>
                        <Th>&nbsp;</Th>
                    </Tr>
                </Thead>
                <Tbody>
                    {templates.length === 0 ?
                        <Tr><Td colSpan={3}><NoResults /></Td></Tr>
                        :
                        templates.map((template) =>
                            <Tr key={template.id}>
                                <Td>{template.version_name}</Td>
                                <Td><EmptyField value={template.version_description} /></Td>
                                <Td>{template.client_file_name}</Td>
                                <Td><span title={safeResolveMime(template.file_mimetype)}>{template.file_mimetype}</span></Td>
                                <Td>
                                    <SecondaryButton onClick={() => handleDownload(template.attachment_id)}>
                                        <IconDocument /> DOCX
                                    </SecondaryButton>
                                </Td>
                                <Td textAlign="right">
                                    <DeleteIconButton disabled={template.generated_by_uid === 0} title={template.generated_by_uid === 0 ? "System templates cannot be deleted" : ""} onClick={ev => deleteTemplate(ev, template.id)} />
                                </Td>
                            </Tr>
                        )
                    }
                </Tbody>
            </Table>
        }
    </>
}
Example #19
Source File: ChallengeReviewRow.jsx    From scaffold-directory with MIT License 4 votes vote down vote up
export default function ChallengeReviewRow({ challenge, isLoading, approveClick, rejectClick, userProvider }) {
  const [comment, setComment] = useState(challenge.reviewComment ?? "");
  const [testPassed, setTestPassed] = useState(null);
  const [isRunningTests, setIsRunningTests] = useState(false);
  const { isOpen, onOpen, onClose } = useDisclosure();
  const address = useUserAddress(userProvider);

  if (!challengeInfo[challenge.id]) {
    return null;
  }

  // We asume that rejected challenges will always have review Comments.
  const isAutograded = challenge.autograding;
  // ToDo. Use the stored events.
  const isResubmitted = !isAutograded && !!challenge.reviewComment;

  const runTests = async () => {
    try {
      console.log("Testing challenge with the auto-grader");

      setIsRunningTests(true);
      setTestPassed(null);

      const result = await runAutograderTest(challenge.id, challenge.contractUrl, address);
      const resultData = result.data;

      console.log("Testing results", resultData);
      setTestPassed(resultData.success);
      setComment(resultData.feedback ?? resultData.error);
    } catch (e) {
      console.log("Error calling the auto-grader", e);
    } finally {
      setIsRunningTests(false);
    }
  };

  const challengeReviewDisplay = (
    <Link as={RouteLink} to={`/challenge/${challenge.id}`}>
      {challengeInfo[challenge.id].label}
      {isResubmitted && (
        <>
          <br />
          <Text fontSize="xs">(Resubmitted)</Text>
        </>
      )}
      {isAutograded && (
        <>
          <br />
          <Text fontSize="xs" color="orange.500">
            (Autograded)
          </Text>
        </>
      )}
    </Link>
  );

  const submittedMoment = moment(challenge.submittedTimestamp);

  const reviewRow = (
    <>
      <Td>
        <Link as={RouteLink} to={`/builders/${challenge.userAddress}`} pos="relative">
          <Address address={challenge.userAddress} w="12.5" fontSize="16" />
        </Link>
      </Td>
      <Td>{challengeReviewDisplay}</Td>
      <Td>
        <DateWithTooltip timestamp={challenge.submittedTimestamp} />
      </Td>
    </>
  );

  return (
    <Tr>
      {reviewRow}
      <Td>
        <Button type="button" colorScheme="blue" disabled={isLoading} className="danger" onClick={onOpen} size="xs">
          Review
        </Button>
      </Td>
      <Modal isOpen={isOpen} onClose={onClose} size="xl">
        <ModalOverlay />
        <ModalContent maxW="56rem">
          <ModalHeader>Review Challenge</ModalHeader>
          <ModalCloseButton />
          <Table mb={4}>
            <Thead>
              <Tr>
                <Th>Builder</Th>
                <Th>Challenge & Links</Th>
              </Tr>
            </Thead>
            <Tbody>
              <Tr>
                <Td>
                  <Link as={RouteLink} to={`/builders/${challenge.userAddress}`} pos="relative">
                    <Address address={challenge.userAddress} w="12.5" fontSize="16" />
                  </Link>
                </Td>
                <Td>
                  {challengeReviewDisplay}
                  <UnorderedList>
                    <ListItem>
                      <Link
                        // Legacy branchUrl
                        href={challenge.contractUrl || challenge.branchUrl}
                        color="teal.500"
                        target="_blank"
                        rel="noopener noreferrer"
                      >
                        Contract
                      </Link>
                    </ListItem>
                    <ListItem>
                      <Link href={challenge.deployedUrl} color="teal.500" target="_blank" rel="noopener noreferrer">
                        Demo
                      </Link>
                    </ListItem>
                    <ListItem>
                      Submitted{" "}
                      <Tooltip label={submittedMoment.format("YYYY-MM-DD, HH:mm")}>
                        <chakra.span cursor="pointer">{submittedMoment.fromNow()}</chakra.span>
                      </Tooltip>
                    </ListItem>
                    <ListItem listStyleType="none" mt={2}>
                      <Flex align="center">
                        <Button onClick={runTests} isLoading={isRunningTests} mr={2}>
                          Run tests
                        </Button>
                        {isBoolean(testPassed) && (
                          <Badge colorScheme={testPassed ? "green" : "red"}>
                            {testPassed ? "Accepted" : "Rejected"}
                          </Badge>
                        )}
                      </Flex>
                    </ListItem>
                  </UnorderedList>
                </Td>
              </Tr>
            </Tbody>
          </Table>
          <ModalBody px={6} pb={0}>
            <Tabs variant="enclosed-colored">
              <TabList>
                <Tab>Write</Tab>
                <Tab>Preview</Tab>
              </TabList>
              <TabPanels align="left">
                <TabPanel p={0}>
                  <Textarea
                    onChange={e => {
                      const value = e.target.value;
                      setComment(value);
                    }}
                    placeholder="Comment"
                    style={{ marginBottom: 10 }}
                    rows={10}
                    value={comment}
                    borderTopRadius={0}
                  />
                </TabPanel>
                <TabPanel>
                  <ReactMarkdown components={ChakraUIRenderer(chakraMarkdownComponents)}>{comment}</ReactMarkdown>
                </TabPanel>
              </TabPanels>
            </Tabs>
          </ModalBody>
          <ModalFooter>
            <Button
              type="button"
              colorScheme="red"
              disabled={isLoading}
              className="danger"
              onClick={() => rejectClick(challenge.userAddress, challenge.id, comment)}
              size="sm"
              isFullWidth
            >
              Reject
            </Button>
            <Button
              type="button"
              colorScheme="green"
              disabled={isLoading}
              ml={3}
              onClick={() => approveClick(challenge.userAddress, challenge.id, comment)}
              size="sm"
              isFullWidth
            >
              Approve
            </Button>
          </ModalFooter>
        </ModalContent>
      </Modal>
    </Tr>
  );
}
Example #20
Source File: Outputs.js    From web-client with Apache License 2.0 4 votes vote down vote up
CommandOutputs = ({ command }) => {
    const [commandOutputs, updateCommandOutputs] = useFetch(`/attachments?parentType=command&parentId=${command.id}`)
    const [modalVisible, setModalVisible] = useState(false);
    const [content, setContent] = useState(null);

    const onDeleteOutputClick = (ev, attachmentId) => {
        ev.preventDefault();

        secureApiFetch(`/attachments/${attachmentId}`, { method: 'DELETE' })
            .then(() => {
                actionCompletedToast("The output has been deleted.");
                updateCommandOutputs();
            })
            .catch(err => console.error(err))
    }

    const onDownloadClick = (ev, attachmentId) => {
        secureApiFetch(`/attachments/${attachmentId}`, { method: 'GET', headers: {} })
            .then(resp => {
                const contentDispositionHeader = resp.headers.get('Content-Disposition');
                const filenameRe = new RegExp(/filename="(.*)";/)
                const filename = filenameRe.exec(contentDispositionHeader)[1]
                return Promise.all([resp.blob(), filename]);
            })
            .then((values) => {
                const blob = values[0];
                const filename = values[1];
                const url = URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = url;
                a.download = filename;
                a.click();
            })
    }

    const onViewClick = (ev, attachmentId) => {
        secureApiFetch(`/attachments/${attachmentId}`, { method: 'GET', headers: {} })
            .then(resp => {
                const contentDispositionHeader = resp.headers.get('Content-Disposition');
                const filenameRe = new RegExp(/filename="(.*)";/)
                const filename = filenameRe.exec(contentDispositionHeader)[1]
                return Promise.all([resp.blob(), filename]);
            })
            .then(async (values) => {
                const blob = values[0];
                setContent(await blob.text());
                setModalVisible(true);
            })
    }

    const onModalClose = () => {
        setModalVisible(false);
    }

    return <>
        <ModalDialog visible={modalVisible} title="Preview output" onModalClose={onModalClose} style={{ width: '80%', height: '80%', maxHeight: '80%' }}>
            <Textarea style={{ width: '100%', height: '90%' }} defaultValue={content} readOnly>
            </Textarea>
        </ModalDialog>

        <RestrictedComponent roles={['administrator', 'superuser', 'user']}>
            <AttachmentsDropzone parentType={"command"} parentId={command.id} onUploadFinished={updateCommandOutputs} />
        </RestrictedComponent>

        <h4>
            Command output list
        </h4>

        <Table>
            <Thead>
                <Tr>
                    <Th>Filename</Th>
                    <Th>Mimetype</Th>
                    <Th>File size</Th>
                    <Th>Upload date</Th>
                    <Th>Uploaded by</Th>
                    <Th>&nbsp;</Th>
                </Tr>
            </Thead>
            <Tbody>
                {null === commandOutputs && <LoadingTableRow numColumns={6} />}
                {null !== commandOutputs && commandOutputs.length === 0 && <NoResultsTableRow numColumns={6} />}
                {null !== commandOutputs && commandOutputs.length !== 0 && commandOutputs.map((commandOutput, index) =>
                    <Tr key={index}>
                        <Td>{commandOutput.client_file_name}</Td>
                        <Td>{commandOutput.file_mimetype}</Td>
                        <Td><FileSizeSpan fileSize={commandOutput.file_size} /></Td>
                        <Td><RelativeDateFormatter date={commandOutput.insert_ts} /></Td>
                        <Td><UserLink userId={commandOutput.submitter_uid}>{commandOutput.submitter_name}</UserLink></Td>
                        <Td textAlign="right">
                            <ButtonGroup isAttached>
                                <SecondaryButton onClick={ev => onViewClick(ev, commandOutput.id)}>View</SecondaryButton>
                                <SecondaryButton onClick={ev => onDownloadClick(ev, commandOutput.id)}>Download</SecondaryButton>
                                <DeleteIconButton onClick={ev => onDeleteOutputClick(ev, commandOutput.id)} />
                            </ButtonGroup>
                        </Td>
                    </Tr>
                )}
            </Tbody>
        </Table>
    </>
}