@chakra-ui/react#Thead JavaScript Examples

The following examples show how to use @chakra-ui/react#Thead. 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: Table.js    From web-client with Apache License 2.0 6 votes vote down vote up
CommandsTable = ({ commands, onDeleteCallback = null }) => {
    return <Table>
        <Thead>
            <Tr>
                <Th style={{ width: '190px' }}>Name</Th>
                <Th className='only-desktop'>Description</Th>
                <Th>Execution environment</Th>
                <Th>Output parser</Th>
                <Th>&nbsp;</Th>
            </Tr>
        </Thead>
        <Tbody>
            {null === commands && <LoadingTableRow numColumns={5} />}
            {null !== commands && 0 === commands.length && <NoResultsTableRow numColumns={5} />}
            {null !== commands && 0 !== commands.length && commands.map(command =>
                <Tr key={command.id}>
                    <Td><CommandBadge command={command} /></Td>
                    <Td className="only-desktop">
                        {command.description}<br />
                        <Tags values={command.tags} />
                    </Td>
                    <Td>{command.executable_type === 'custom' ? 'Host' : 'Container'}</Td>
                    <Td>{command.output_parser ?? '-'}</Td>
                    <Td textAlign="right">
                        <LinkButton href={`/commands/${command.id}/edit`}>Edit</LinkButton>
                        {onDeleteCallback && <DeleteIconButton onClick={() => onDeleteCallback(command.id)} />}
                    </Td>
                </Tr>
            )}
        </Tbody>
    </Table>
}
Example #2
Source File: Integrations.js    From web-client with Apache License 2.0 6 votes vote down vote up
SystemIntegrationsPage = () => {
    const [integrations] = useFetch('/system/integrations')

    return <div>
        <PageTitle value="Integrations" />
        <div className='heading'>
            <Breadcrumb>
                <div>System</div>
            </Breadcrumb>
        </div>
        <Title title="Integrations" icon={<IconExtensions />} />

        <Table>
            <Thead>
                <Tr>
                    <Th>Name</Th>
                    <Th>Description</Th>
                    <Th>External URL</Th>
                    <Th>Configured?</Th>
                    <Th>&nbsp;</Th>
                </Tr>
            </Thead>
            <Tbody>
                {null === integrations && <LoadingTableRow numColumns={5} />}
                {null !== integrations && 0 === integrations.length && <NoResultsTableRow numColumns={5} />}
                {null !== integrations && 0 !== integrations.length && integrations.map((integration, index) =>
                    <Tr key={index}>
                        <Td>{integration.name}</Td>
                        <Td>{integration.description}</Td>
                        <Td><ExternalLink href={integration.externalUrl}>{integration.externalUrl}</ExternalLink></Td>
                        <Td>{integration.configured ? 'Yes' : 'No'}</Td>
                        <Td>-</Td>
                    </Tr>
                )}
            </Tbody>
        </Table>
    </div>
}
Example #3
Source File: Licenses.js    From web-client with Apache License 2.0 6 votes vote down vote up
LicensesPage = () => {

    return <div>
        <PageTitle value="Licenses" />

        <div className='heading'>
            <Breadcrumb />
        </div>
        <Title title="Licenses" icon={<IconQuestionCircle />} />

        <Table>
            <Thead>
                <Th>Dependency</Th>
                <Th>License</Th>
                <Th>Url</Th>
            </Thead>
            <Tbody>
                {Object.entries(Licenses).map(entry => <Tr>
                    <Td>{entry[0]}</Td>
                    <Td>{entry[1].licenses}</Td>
                    <Td>{entry[1].url}</Td>
                </Tr>)}
            </Tbody>
        </Table>

    </div>
}
Example #4
Source File: Table.js    From web-client with Apache License 2.0 6 votes vote down vote up
DocumentsTable = ({ documents, onDeleteButtonClick }) => {
    return <Table>
        <Thead>
            <Tr>
                <Th>Title</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>
            {null === documents && <LoadingTableRow numColumns={6} />}
            {null !== documents && documents.length === 0 && <NoResultsTableRow numColumns={6} />}
            {null !== documents && documents.map((document, index) =>
                <Tr key={`doc_${index}`}>
                    <Td><DocumentBadge document={document} /></Td>
                    <Td><RelativeDateFormatter date={document.insert_ts} /></Td>
                    <Td><UserLink userId={document.user_id}>{document.user_name}</UserLink></Td>
                    <Td><VisibilityLegend visibility={document.visibility} /></Td>
                    <Td style={{ textAlign: "right" }}>
                        <LinkButton href={`/documents/${document.id}/edit`}>Edit</LinkButton>
                        <DeleteIconButton onClick={ev => onDeleteButtonClick(document.id)} />
                    </Td>
                </Tr>
            )}
        </Tbody>
    </Table>
}
Example #5
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 #6
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 #7
Source File: RecentVulnerabilitiesWidget.js    From web-client with Apache License 2.0 6 votes vote down vote up
RecentVulnerabilitiesWidget = () => {
    const [vulnerabilities] = useFetch(`/vulnerabilities?limit=5&orderColumn=insert_ts&orderDirection=desc`)

    if (!vulnerabilities) return <Loading />

    return <DashboardWidget title="Recent vulnerabilities">

        {vulnerabilities.length === 0 ?
            <p>No vulnerabilities to show.</p>
            :
            <Table>
                <Thead>
                    <Tr>
                        <Th>Summary</Th>
                        <Th>Created</Th>
                    </Tr>
                </Thead>
                <Tbody>
                    {vulnerabilities.map(vulnerability => <Tr key={vulnerability.id}>
                        <Td><VulnerabilityBadge key={vulnerability.id} vulnerability={vulnerability} /></Td>
                        <Td><RelativeDateFormatter date={vulnerability.insert_ts} /></Td>
                    </Tr>)}
                </Tbody>
            </Table>
        }
    </DashboardWidget>
}
Example #8
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 #9
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 #10
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 #11
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 #12
Source File: List.js    From web-client with Apache License 2.0 5 votes vote down vote up
ClientsList = () => {
    const navigate = useNavigate();
    const [clients, updateTasks] = useFetch('/clients')

    const destroy = useDelete('/clients/', updateTasks);

    const handleCreateClient = () => {
        navigate(`/clients/create`)
    }

    return <>
        <PageTitle value="Clients" />
        <div className='heading'>
            <Breadcrumb />

            <ButtonGroup isAttached>
                <CreateButton onClick={handleCreateClient}>Add client</CreateButton>

                <Menu>
                    <MenuButton as={IconButton} aria-label='Options' icon={<FontAwesomeIcon icon={faEllipsis} />} variant='outline' />
                    <MenuList>
                        <ExportMenuItem entity="clients" />
                    </MenuList>
                </Menu>
            </ButtonGroup>
        </div>
        <Title title='Clients' icon={<IconBriefcase />} />

        <Table>
            <Thead>
                <Tr>
                    <Th>Name</Th>
                    <Th>Address</Th>
                    <Th>URL</Th>
                    <Th>Number of contacts</Th>
                    <Th>&nbsp;</Th>
                </Tr>
            </Thead>
            <Tbody>
                {null === clients && <LoadingTableRow numColumns={5} />}
                {null !== clients && 0 === clients.length && <NoResultsTableRow numColumns={5} />}
                {null !== clients && 0 < clients.length && clients.map(client =>
                    <Tr key={client.id}>
                        <Td><ClientLink clientId={client.id}>{client.name}</ClientLink></Td>
                        <Td>{client.address || '-'}</Td>
                        <Td>{client.url ? <ExternalLink href={client.url}>{client.url}</ExternalLink> : '-'}</Td>
                        <Td>{client.num_contacts}</Td>
                        <Td textAlign="right">
                            <LinkButton href={`/clients/${client.id}/edit`}>Edit</LinkButton>
                            <DeleteIconButton onClick={() => destroy(client.id)} />
                        </Td>
                    </Tr>
                )
                }
            </Tbody>
        </Table>
    </>
}
Example #13
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 #14
Source File: Table.js    From web-client with Apache License 2.0 5 votes vote down vote up
ProjectsTable = ({ projects, destroy = null, showClientColumn = true }) => {
    const numColumns = showClientColumn ? 7 : 6;

    return <Table>
        <Thead>
            <Tr>
                <Th>Name</Th>
                {showClientColumn && <Th>Client</Th>}
                <Th className="only-desktop">Description</Th>
                <Th>Category</Th>
                <Th>Vulnerability Metrics</Th>
                <Th>Status</Th>
                <Th>&nbsp;</Th>
            </Tr>
        </Thead>
        <Tbody>
            {null === projects && <LoadingTableRow numColumns={numColumns} />}
            {null !== projects && 0 === projects.length && <NoResultsTableRow numColumns={numColumns} />}
            {null !== projects && 0 !== projects.length && projects.map(project =>
                <Tr key={project.id}>
                    <Td>
                        <ProjectBadge project={project} />
                    </Td>
                    {showClientColumn &&
                        <Td>{project.is_template ?
                            <span title="Not applicable">(n/a)</span> :
                            <ClientLink clientId={project.client_id}>{project.client_name}</ClientLink>}
                        </Td>
                    }
                    <Td className="only-desktop">{project.description}</Td>
                    <Td>{project.category_id !== null ? project.category_name : '(undefined)'}</Td>
                    <Td>{project.vulnerability_metrics ? project.vulnerability_metrics : '(undefined)'}</Td>
                    <Td>{project.archived ? 'Archived' : 'Active'}</Td>
                    <Td textAlign="right">
                        <RestrictedComponent roles={['administrator', 'superuser', 'user']}>
                            <LinkButton href={`/projects/${project.id}/edit`}>Edit</LinkButton>
                            {destroy &&
                                <DeleteIconButton onClick={() => destroy(project.id)} />
                            }
                        </RestrictedComponent>
                    </Td>
                </Tr>
            )}
        </Tbody>
    </Table>
}
Example #15
Source File: List.js    From web-client with Apache License 2.0 5 votes vote down vote up
TemplatesList = () => {
    const navigate = useNavigate();
    const [templates, updateTemplates] = useFetch('/projects?isTemplate=1')

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

        secureApiFetch(`/projects/${templateId}/clone`, { method: 'POST' })
            .then(resp => resp.json())
            .then(data => {
                navigate(`/projects/${data.projectId}/edit`);
            });
    }

    const viewProject = (templateId) => {
        navigate(`/projects/templates/${templateId}`);
    }

    const destroy = useDelete('/projects/', updateTemplates);

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

        destroy(templateId);
    }

    const onAddProjectTemplateClick = () => {
        navigate(`/projects/create?isTemplate=true`)
    }

    return <>
        <PageTitle value="Project templates" />
        <div className='heading'>
            <Breadcrumb>
                <Link to="/projects">Projects</Link>
            </Breadcrumb>

            <CreateButton onClick={onAddProjectTemplateClick}>Add project template</CreateButton>
        </div>
        <Title title='Project templates' icon={<IconDocumentDuplicate />} />
        {!templates ? <Loading /> :
            <Table>
                <Thead>
                    <Tr>
                        <Th style={{ width: '190px' }}>Name</Th>
                        <Th>Description</Th>
                        <Th style={{ width: '16ch' }}>Number of tasks</Th>
                        <Th>&nbsp;</Th>
                    </Tr>
                </Thead>
                <Tbody>
                    {templates.length === 0 ?
                        <Td colSpan={4}><NoResults /></Td>
                        :
                        templates.map((template) =>
                            <Tr key={template.id} onClick={() => viewProject(template.id)}>
                                <Td><ProjectBadge project={template} /></Td>
                                <Td>{template.description}</Td>
                                <Td><BadgeOutline>{template.num_tasks}</BadgeOutline></Td>
                                <Td textAlign="right">
                                    <PrimaryButton onClick={ev => cloneProject(ev, template.id)} key={template.id}
                                        title="Clone" leftIcon={<IconPlus />}>Clone and edit</PrimaryButton>
                                    <LinkButton href={`/projects/${template.id}/edit`}>Edit</LinkButton>
                                    <DeleteIconButton onClick={ev => deleteTemplate(ev, template.id)} />
                                </Td>
                            </Tr>
                        )
                    }
                </Tbody>
            </Table>
        }
    </>
}
Example #16
Source File: Table.js    From web-client with Apache License 2.0 5 votes vote down vote up
ReportsTable = ({ reports, updateReports, includeProjectColumn = false }) => {

    const navigate = useNavigate();

    const deleteReport = useDelete('/reports/', updateReports);

    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 handleSendByEmail = (projectId) => {
        navigate(`/projects/${projectId}/report/send`);
    }

    return <Table>
        <Thead>
            <Tr>
                <Th>Name (Description)</Th>
                {includeProjectColumn && <Th>Project</Th>}
                <Th>Datetime</Th>
                <Th>Downloads</Th>
                <Th>&nbsp;</Th>
            </Tr>
        </Thead>
        <Tbody>
            {reports.length === 0 && <NoResultsTableRow numColumns={4} />}
            {reports.map((report, index) =>
                <Tr key={index}>
                    <Td>{report.version_name} ({report.version_description})</Td>
                    {includeProjectColumn && <Td><ProjectBadge project={{ id: report.project_id, name: report.project_name }} /></Td>}
                    <Td><RelativeDateFormatter date={report.insert_ts} /></Td>
                    <Td>
                        <SecondaryButton onClick={() => handleDownload(report.docx_attachment_id)}>
                            <IconDocument /> DOCX
                        </SecondaryButton>
                    </Td>
                    <Td textAlign="right">
                        <SecondaryButton onClick={() => handleSendByEmail(report.project_id)}>Send by email</SecondaryButton>

                        <DeleteIconButton onClick={() => deleteReport(report.id)} />
                    </Td>
                </Tr>
            )}
        </Tbody>
    </Table>
}
Example #17
Source File: TasksTable.js    From web-client with Apache License 2.0 5 votes vote down vote up
TasksTable = ({ tableModel, tableModelSetter: setTableModel, destroy, reloadCallback = null }) => {
    const showSelection = tableModel.columnsVisibility.selection;
    const showProjectColumn = tableModel.columnsVisibility.project;
    const numColumns = 6 + (showSelection ? 1 : 0) + (showProjectColumn ? 1 : 0);

    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) })
        }
    };

    return <Table>
        <Thead>
            <Tr>
                {showSelection && <Th style={{ width: "32px" }}>&nbsp;</Th>}
                <Th>Summary</Th>
                <Th className='only-desktop'>Description</Th>
                {showProjectColumn && <Th>Project</Th>}
                <Th>Priority</Th>
                <Th>Assignee</Th>
                <Th style={{ width: '100px' }}>Status</Th>
                <Th colSpan={reloadCallback ? 1 : 2}>Command</Th>
                {reloadCallback && <Th style={{ width: '15%', textAlign: 'right' }}><ReloadButton onClick={reloadCallback} /></Th>}
            </Tr>
        </Thead>
        <Tbody>
            {null === tableModel.tasks && <LoadingTableRow numColumns={numColumns} />}
            {null !== tableModel.tasks && 0 === tableModel.tasks.length && <NoResultsTableRow numColumns={numColumns} />}
            {null !== tableModel.tasks && tableModel.tasks.map(task =>
                <Tr key={task.id}>
                    {showSelection &&
                        <Td>
                            <input
                                type="checkbox"
                                value={task.id}
                                onChange={onSelectionChange}
                                checked={tableModel.selection.includes(task.id)}
                            />
                        </Td>
                    }
                    <Td><TaskBadge task={task} /></Td>
                    <Td className="only-desktop">{task.description ? task.description.substring(0, 100) + "..." : "-"}</Td>
                    {showProjectColumn && <Td><ProjectBadge project={{ id: task.project_id, name: task.project_name }} /></Td>}
                    <Td>{task.priority}</Td>
                    <Td  >{task.assignee_uid ?
                        <UserLink userId={task.assignee_uid}>{task.assignee_full_name}</UserLink> : '(nobody)'}</Td>
                    <Td><TaskStatusFormatter task={task} /></Td>
                    <Td>{task.command_name ? <BadgeOutline>{task.command_name}</BadgeOutline> : '-'}</Td>
                    <Td textAlign="right">
                        <RestrictedComponent roles={['administrator', 'superuser', 'user']}>
                            <LinkButton href={`/tasks/${task.id}/edit`}>Edit</LinkButton>
                            {destroy && <DeleteIconButton onClick={() => destroy(task.id)} />}
                        </RestrictedComponent>
                    </Td>
                </Tr>
            )}
        </Tbody>
    </Table>
}
Example #18
Source File: List.js    From web-client with Apache License 2.0 5 votes vote down vote up
VulnerabilityCategoriesPage = () => {
    const [categories, fetchParentCategories] = useFetch('/vulnerabilities/categories?parentsOnly=0')

    const destroy = useDelete('/vulnerabilities/categories/', fetchParentCategories);

    const [editCategory, setEditCategory] = useState({});

    const { isOpen: isAddCategoryDialogOpen, onOpen: openAddCategoryDialog, onClose: closeAddCategoryDialog } = useDisclosure();
    const { isOpen: isEditCategoryDialogOpen, onOpen: openEditCategoryDialog, onClose: closeEditCategoryDialog } = useDisclosure();

    const onCategoryDialogClosed = () => {
        fetchParentCategories();

        closeAddCategoryDialog();
        closeEditCategoryDialog();
    }

    const onAddClick = ev => {
        ev.preventDefault();

        openAddCategoryDialog();
    }

    const onEditClick = (ev, ccategory) => {
        ev.preventDefault();

        setEditCategory(ccategory);
        openEditCategoryDialog();
    }

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

        destroy(templateId);
    }

    return <>
        <PageTitle value="Vulnerability categories" />
        <div className='heading'>
            <Breadcrumb>
                <Link to="/vulnerabilities">Vulnerabilities</Link>
            </Breadcrumb>

            <VulnerabilityCategoryAddModalDialog isOpen={isAddCategoryDialogOpen} onClose={onCategoryDialogClosed} onCancel={closeAddCategoryDialog} />
            {isEditCategoryDialogOpen && <VulnerabilityCategoryEditModalDialog category={editCategory} isOpen={isEditCategoryDialogOpen} onClose={onCategoryDialogClosed} onCancel={closeEditCategoryDialog} />}
            <CreateButton onClick={onAddClick}>Add vulnerability category...</CreateButton>
        </div>
        <Title title='Vulnerability categories' icon={<IconDocumentDuplicate />} />
        {!categories ? <Loading /> :
            <Table>
                <Thead>
                    <Tr>
                        <Th style={{ width: '190px' }}>Name</Th>
                        <Th>Parent category</Th>
                        <Th colSpan={2}>Description</Th>
                    </Tr>
                </Thead>
                <Tbody>
                    {categories.length === 0 ?
                        <Tr><Td colSpan={3}><NoResults /></Td></Tr>
                        :
                        categories.map(category =>
                            <Tr key={category.id}>
                                <Td><strong>{category.name}</strong></Td>
                                <Td>{category.parent_name ?? '-'}</Td>
                                <Td>{category.description}</Td>
                                <Td textAlign="right">
                                    <LinkButton href="#" onClick={ev => onEditClick(ev, category)}>Edit</LinkButton>
                                    <DeleteIconButton onClick={ev => onDeleteClick(ev, category.id)} />
                                </Td>
                            </Tr>
                        )
                    }
                </Tbody>
            </Table>
        }
    </>
}
Example #19
Source File: List.js    From web-client with Apache License 2.0 5 votes vote down vote up
VulnerabilityTemplatesList = () => {
    const navigate = useNavigate();
    const [sortBy, setSortBy] = useState({ column: 'insert_ts', order: 'DESC' })
    const [templates, updateTemplates] = useFetch(`/vulnerabilities?isTemplate=1&orderColumn=${sortBy.column}&orderDirection=${sortBy.order}`)

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

        secureApiFetch(`/vulnerabilities/${templateId}/clone`, { method: 'POST' })
            .then(resp => resp.json())
            .then(data => {
                navigate(`/vulnerabilities/${data.vulnerabilityId}/edit`);
            });
    }

    const onSortChange = (ev, column, order) => {
        ev.preventDefault();

        setSortBy({ column: column, order: order });
    }

    const viewTemplate = (templateId) => {
        navigate(`/vulnerabilities/templates/${templateId}`);
    }

    const destroy = useDelete('/vulnerabilities/', updateTemplates);

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

        destroy(templateId);
    }

    const onAddVulnerabilityTemplateClick = () => {
        navigate(`/vulnerabilities/create?isTemplate=true`)
    }

    return (
        <>
            <PageTitle value="Vulnerability templates" />
            <div className='heading'>
                <Breadcrumb>
                    <Link to="/vulnerabilities">Vulnerabilities</Link>
                </Breadcrumb>

                <CreateButton onClick={onAddVulnerabilityTemplateClick}>Add vulnerability template</CreateButton>
            </div>
            <Title title='Vulnerability templates' icon={<IconDocumentDuplicate />} />
            {!templates ? <Loading /> :
                <Table>
                    <Thead>
                        <Tr>
                            <Th>Summary</Th>
                            <Th colSpan={2}><DescendingSortLink callback={onSortChange} property="category_name" /> Category <AscendingSortLink callback={onSortChange} property="category_name" /></Th>
                        </Tr>
                    </Thead>
                    <Tbody>
                        {templates.length === 0 ?
                            <Tr><Td colSpan={3}><NoResults /></Td></Tr>
                            :
                            templates.map((template) =>
                                <Tr key={template.id} onClick={() => viewTemplate(template.id)}>
                                    <Td><VulnerabilityBadge vulnerability={template} /></Td>
                                    <Td><VulnerabilityCategorySpan name={template.category_name} parentName={template.parent_category_name} /></Td>
                                    <Td textAlign="right">
                                        <PrimaryButton onClick={ev => cloneVulnerability(ev, template.id)} key={template.id}
                                            title="Clone" leftIcon={<IconPlus />}>Clone and edit</PrimaryButton>
                                        <LinkButton href={`/vulnerabilities/${template.id}/edit`}>Edit</LinkButton>
                                        <DeleteIconButton onClick={ev => deleteTemplate(ev, template.id)} />
                                    </Td>
                                </Tr>
                            )
                        }
                    </Tbody>
                </Table>
            }
        </>
    )
}
Example #20
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 #21
Source File: offers.js    From idena-web with MIT License 5 votes vote down vote up
export default function AdOfferList() {
  const {t} = useTranslation()

  const queryClient = useQueryClient()

  const {data: burntCoins, status: burntCoinsStatus} = useApprovedBurntCoins()

  const isFetched = burntCoinsStatus === 'success'

  const isEmpty = isFetched && burntCoins.length === 0

  const [selectedAd, setSelectedAd] = React.useState({})

  const burnDisclosure = useDisclosure()
  const {
    onOpen: onOpenBurnDisclosure,
    onClose: onCloseBurnDisclosure,
  } = burnDisclosure

  const handlePreviewBurn = React.useCallback(
    ad => {
      setSelectedAd(ad)
      onOpenBurnDisclosure()
    },
    [onOpenBurnDisclosure]
  )

  const handleBurn = React.useCallback(() => {
    onCloseBurnDisclosure()
    queryClient.invalidateQueries(['bcn_burntCoins', []])
  }, [onCloseBurnDisclosure, queryClient])

  return (
    <Layout skipBanner>
      <Page>
        <PageHeader>
          <PageTitle mb={4}>{t('All offers')}</PageTitle>
          <PageCloseButton href="/adn/list" />
        </PageHeader>
        <Table>
          <Thead>
            <Tr>
              <RoundedTh isLeft>{t('Banner/author')}</RoundedTh>
              <RoundedTh>{t('Website')}</RoundedTh>
              <RoundedTh>{t('Target')}</RoundedTh>
              <RoundedTh>{t('Burn')}</RoundedTh>
              <RoundedTh isRight />
            </Tr>
          </Thead>
          <Tbody>
            {isFetched &&
              burntCoins.map(burn => (
                <AdOfferListItem
                  key={burn.key}
                  burn={burn}
                  onBurn={handlePreviewBurn}
                />
              ))}
          </Tbody>
        </Table>

        {isEmpty && (
          <Center color="muted" mt="4" w="full">
            {t('No active offers')}
          </Center>
        )}

        <BurnDrawer ad={selectedAd} onBurn={handleBurn} {...burnDisclosure} />
      </Page>
    </Layout>
  )
}
Example #22
Source File: ActivityView.jsx    From scaffold-directory with MIT License 5 votes vote down vote up
export default function ActivityView() {
  const [eventsFeed, setEventFeeds] = useState([]);
  const [isLoadingEvents, setIsLoadingEvents] = useState(false);
  const { secondaryFontColor } = useCustomColorModes();

  useEffect(() => {
    const updateEvents = async () => {
      setIsLoadingEvents(true);
      const events = await getAllEvents(25);
      setEventFeeds(events);
      setIsLoadingEvents(false);
    };

    updateEvents();
  }, []);

  return (
    <Container maxW="container.md" centerContent>
      <Heading as="h1" mb="4">
        Activity feed
      </Heading>
      <Text color={secondaryFontColor} textAlign="center" mb={10}>
        Last 25 things happening at SRE.
      </Text>
      {isLoadingEvents ? (
        <Box w="100%" maxW="500px">
          <SkeletonText mt="4" noOfLines={10} spacing="4" />
        </Box>
      ) : (
        <Table>
          <Thead>
            <Tr>
              <Th>Builder</Th>
              <Th>Time</Th>
              <Th>Action</Th>
            </Tr>
          </Thead>
          <Tbody>
            {eventsFeed.map(event => (
              <EventRow key={`${event.timestamp}_${event.payload.userAddress}`} event={event} />
            ))}
          </Tbody>
        </Table>
      )}
    </Container>
  );
}
Example #23
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 #24
Source File: SubmissionReviewTableSkeleton.jsx    From scaffold-directory with MIT License 5 votes vote down vote up
BuildsTableSkeleton = () => (
  <Box overflowX="auto">
    <Table mb={4}>
      <Thead>
        <Tr>
          <Th>Builder</Th>
          <Th>Build Name</Th>
          <Th>Description</Th>
          <Th>Branch URL</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>
                <HStack spacing={3}>
                  <Skeleton startColor="red.100" endColor="red.500">
                    <Button type="button" size="xs">
                      Reject
                    </Button>
                  </Skeleton>
                  <Skeleton startColor="green.100" endColor="green.500">
                    <Button type="button" style={{ marginRight: 10 }} size="xs">
                      Approve
                    </Button>
                  </Skeleton>
                </HStack>
              </Td>
            </Tr>
          );
        })}
      </Tbody>
    </Table>
  </Box>
)
Example #25
Source File: BuilderProfileChallengesTableSkeleton.jsx    From scaffold-directory with MIT License 5 votes vote down vote up
BuilderProfileChallengesTableSkeleton = () => (
  <Box overflowX="auto">
    <Table>
      <Thead>
        <Tr>
          <Th w="30%">Name</Th>
          <Th>Contract</Th>
          <Th>Live Demo</Th>
          <Th>Updated</Th>
          <Th>Status</Th>
        </Tr>
      </Thead>
      <Tbody>
        {[1, 2].map(lineNumber => {
          return (
            <Tr key={lineNumber}>
              <Td>
                <SkeletonText noOfLines={1} py={2} />
              </Td>
              <Td>
                <SkeletonText noOfLines={1} w="50%" />
              </Td>
              <Td>
                <SkeletonText noOfLines={1} w="50%" />
              </Td>
              <Td>
                <SkeletonText noOfLines={1} />
              </Td>
              <Td>
                <Skeleton h={6} w={20} borderRadius="full">
                  Submitted
                </Skeleton>
              </Td>
            </Tr>
          );
        })}
      </Tbody>
    </Table>
  </Box>
)
Example #26
Source File: components.js    From idena-web with MIT License 4 votes vote down vote up
export function WalletTransactions({address}) {
  const LIMIT = 10
  const {t, i18n} = useTranslation()

  const toNumber = toLocaleNumber(i18n.language, {maximumFractionDigits: 4})

  const fetchTxs = ({pageParam = null}) =>
    getTxs(address, LIMIT, pageParam).then(result => {
      if (!result) {
        return {result: []}
      }
      const newResult = result.map(tx => {
        const fromWallet =
          lowerCase(address) === lowerCase(tx.from) ? address : null
        const toWallet =
          lowerCase(address) === lowerCase(tx.to) ? address : null

        const direction = fromWallet ? t('Sent') : t('Received')

        const typeName = tx.type === 'SendTx' ? direction : transactionType(tx)

        const sourceWallet = fromWallet || toWallet
        const signAmount = fromWallet ? -tx.amount : `+${tx.amount}`
        const counterParty = fromWallet ? tx.to : tx.from
        const counterPartyWallet = fromWallet ? toWallet : fromWallet
        const isMining = !tx.timestamp

        const nextTx = {
          ...tx,
          typeName,
          wallet: sourceWallet,
          direction,
          signAmount,
          counterParty,
          counterPartyWallet,
          isMining,
        }
        return nextTx
      })
      return {result: newResult, continuationToken: result.continuationToken}
    })

  const {
    data,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
    status,
  } = useInfiniteQuery(['transactions', address], fetchTxs, {
    getNextPageParam: lastPage => lastPage?.continuationToken,
    refetchInterval: 10 * 1000,
  })

  const isLoading = status === 'loading'

  return (
    <div>
      <Table
        sx={{
          '&': {
            tableLayout: 'fixed',
          },
          tr: {
            '&:last-of-type': {
              td: {borderBottomWidth: 0},
            },
          },
        }}
      >
        <Thead display={['none', 'table-header-group']}>
          <Tr>
            <RoundedTh isLeft>{t('Transaction')}</RoundedTh>
            <RoundedTh>{t('Address')}</RoundedTh>
            <RoundedTh textAlign="right">{t('Amount, iDNA')}</RoundedTh>
            <RoundedTh textAlign="right">{t('Fee, iDNA')}</RoundedTh>
            <RoundedTh>{t('Date')}</RoundedTh>
            <RoundedTh isRight>{t('Blockchain transaction ID')}</RoundedTh>
          </Tr>
        </Thead>
        <Tbody>
          {!isLoading &&
            data &&
            data.pages.map((group, i) => (
              <React.Fragment key={i}>
                {group.result.map((tx, k) => (
                  <Tr key={i + k}>
                    <TransactionsTd>
                      <RowStatus
                        isMining={tx.isMining}
                        direction={tx.direction}
                        type={tx.typeName}
                        walletName="Main"
                        tx={tx}
                      />
                    </TransactionsTd>

                    <TransactionsTd display={['none', 'table-cell']}>
                      {(!tx.to && '\u2013') || (
                        <Flex align="center">
                          <Avatar
                            address={lowerCase(tx.counterParty)}
                            size={8}
                          />
                          <Box ml={3}>
                            <div>
                              {tx.direction === 'Sent' ? t('To') : t('From')}{' '}
                              {tx.counterPartyWallet
                                ? `${t('wallet')} Main`
                                : t('address')}
                            </div>
                            <TableHint>
                              <Text isTruncated w="130px">
                                {tx.counterParty}
                              </Text>
                            </TableHint>
                          </Box>
                        </Flex>
                      )}
                    </TransactionsTd>

                    <TransactionsTd
                      display={['none', 'table-cell']}
                      textAlign="right"
                    >
                      <Box color={tx.signAmount < 0 ? 'red.500' : 'gray.500'}>
                        {(tx.type === 'kill' && t('See in Explorer...')) ||
                          (tx.amount === '0'
                            ? '\u2013'
                            : toNumber(tx.signAmount))}
                      </Box>
                    </TransactionsTd>

                    <TransactionsTd
                      display={['none', 'table-cell']}
                      textAlign="right"
                    >
                      {(!tx.isMining &&
                        (tx.fee === '0' ? '\u2013' : toNumber(tx.fee))) || (
                        <div>
                          <div> {tx.maxFee} </div>
                          <TableHint>{t('Fee limit')}</TableHint>
                        </div>
                      )}
                    </TransactionsTd>
                    <TransactionsTd display={['none', 'table-cell']}>
                      {!tx.timestamp
                        ? '\u2013'
                        : new Date(tx.timestamp).toLocaleString()}
                    </TransactionsTd>

                    <TransactionsTd display={['none', 'table-cell']}>
                      <div>
                        <div>
                          {tx.isMining ? t('Mining...') : t('Confirmed')}
                        </div>
                        <TableHint>
                          <Text isTruncated w="130px">
                            {tx.hash}
                          </Text>
                        </TableHint>
                      </div>
                    </TransactionsTd>
                  </Tr>
                ))}
              </React.Fragment>
            ))}
        </Tbody>
      </Table>
      {isLoading && (
        <Stack spacing={2} mt={2}>
          {new Array(10).fill(0).map((_, i) => (
            <Skeleton key={i} height={10} w="full"></Skeleton>
          ))}
        </Stack>
      )}
      {!isLoading && hasNextPage && (
        <Flex justify="center" mt={2}>
          <FlatButton
            mb={2.5}
            onClick={() => fetchNextPage()}
            disabled={isFetchingNextPage}
          >
            {isFetchingNextPage ? t('Loading more...') : t('Load More')}
          </FlatButton>
        </Flex>
      )}

      {!isLoading && data?.pages && data.pages[0].result?.length === 0 && (
        <Box color="muted" textAlign="center" lineHeight="40vh">
          {t(`You don't have any transactions yet`)}
        </Box>
      )}
    </div>
  )
}
Example #27
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 #28
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 #29
Source File: List.js    From web-client with Apache License 2.0 4 votes vote down vote up
UsersList = () => {
    const navigate = useNavigate();
    const loggedInUser = Auth.getLoggedInUser();
    const [users, updateUsers] = useFetch("/users");
    const deleteUser = useDelete("/users/", updateUsers);
    const handleCreate = () => {
        navigate("/users/create");
    };

    const [selectedUsers, setSelectedUsers] = useState([]);

    const onTaskCheckboxChange = (ev) => {
        const target = ev.target;
        const targetUserId = parseInt(target.value);
        if (target.checked) {
            setSelectedUsers([...selectedUsers, targetUserId]);
        } else {
            setSelectedUsers(
                selectedUsers.filter(value => value !== targetUserId)
            );
        }
    };

    const handleBulkDelete = () => {
        secureApiFetch(`/users`, {
            method: "PATCH",
            headers: {
                "Bulk-Operation": "DELETE",
            },
            body: JSON.stringify(selectedUsers),
        })
            .then(updateUsers)
            .then(() => {
                setSelectedUsers([]);
                actionCompletedToast("All selected users were deleted.");
            })
            .catch(err => console.error(err));
    };

    const handleDelete = (id) => {
        deleteUser(id);
        updateUsers();
    };

    return <>
        <PageTitle value="Users" />
        <div className="heading">
            <Breadcrumb />
            <ButtonGroup isAttached>
                <CreateButton onClick={handleCreate}>
                    Create user
                </CreateButton>
                <RestrictedComponent roles={['administrator']}>
                    <DeleteButton onClick={handleBulkDelete} disabled={selectedUsers.length === 0}>
                        Delete selected
                    </DeleteButton>
                </RestrictedComponent>
                <Menu>
                    <EllipsisMenuButton />
                    <MenuList>
                        <ExportMenuItem entity="users" />
                    </MenuList>
                </Menu>
            </ButtonGroup>
        </div>
        <Title title="Users and roles" icon={<IconUserGroup />} />
        <Table>
            <Thead>
                <Tr>
                    <Th style={{ width: "32px" }}>&nbsp;</Th>
                    <Th style={{ width: "64px" }}>&nbsp;</Th>
                    <Th>Full name</Th>
                    <Th>Username</Th>
                    <Th>Role</Th>
                    <Th>Active?</Th>
                    <Th>2FA enabled?</Th>
                    <Th>&nbsp;</Th>
                </Tr>
            </Thead>
            <Tbody>
                {null === users && <LoadingTableRow numColumns={8} />}
                {null !== users && 0 === users.length && <NoResultsTableRow numColumns={8} />}
                {null !== users && 0 !== users.length && users.map((user, index) => (
                    <Tr key={index}>
                        <Td>
                            <input
                                type="checkbox"
                                value={user.id}
                                onChange={onTaskCheckboxChange}
                                checked={selectedUsers.includes(user.id)}
                            />
                        </Td>
                        <Td>
                            <UserAvatar email={user.email} />
                        </Td>
                        <Td>
                            <Link to={`/users/${user.id}`}>
                                {user.full_name}
                            </Link>
                        </Td>
                        <Td>
                            <UserLink userId={user.id}>
                                {user.username}
                            </UserLink>
                        </Td>
                        <Td>
                            <UserRoleBadge role={user.role} />
                        </Td>
                        <Td><BooleanText value={user.active} /></Td>
                        <Td><BooleanText value={user.mfa_enabled} /></Td>
                        <Td textAlign="right">
                            <LinkButton href={`/users/${user.id}/edit`}>
                                Edit
                            </LinkButton>
                            <DeleteIconButton
                                onClick={() => handleDelete(user.id)}
                                disabled={
                                    parseInt(user.id) ===
                                        loggedInUser.id
                                        ? "disabled"
                                        : ""
                                }
                            />
                        </Td>
                    </Tr>
                ))}
            </Tbody>
        </Table>
    </>
}