coder/site/pages/projects/index.tsx

96 lines
2.8 KiB
TypeScript

import React from "react"
import { makeStyles } from "@material-ui/core/styles"
import Paper from "@material-ui/core/Paper"
import { Link } from "react-router-dom"
import { EmptyState } from "../../components"
import { ErrorSummary } from "../../components/ErrorSummary"
import { Navbar } from "../../components/Navbar"
import { Header } from "../../components/Header"
import { Footer } from "../../components/Page"
import { Column, Table } from "../../components/Table"
import { useUser } from "../../contexts/UserContext"
import { FullScreenLoader } from "../../components/Loader/FullScreenLoader"
import { Organization, Project } from "./../../api"
import useSWR from "swr"
import { CodeExample } from "../../components/CodeExample/CodeExample"
export const ProjectsPage: React.FC = () => {
const styles = useStyles()
const { me, signOut } = useUser(true)
const { data: orgs, error: orgsError } = useSWR<Organization[], Error>("/api/v2/users/me/organizations")
const { data: projects, error } = useSWR<Project[] | null, Error>(
orgs ? `/api/v2/organizations/${orgs[0].id}/projects` : null,
)
if (error) {
return <ErrorSummary error={error} />
}
if (orgsError) {
return <ErrorSummary error={error} />
}
if (!me || !projects || !orgs) {
return <FullScreenLoader />
}
// Create a dictionary of organization ID -> organization Name
// Needed to properly construct links to dive into a project
const orgDictionary = orgs.reduce((acc: Record<string, string>, curr: Organization) => {
return {
...acc,
[curr.id]: curr.name,
}
}, {})
const columns: Column<Project>[] = [
{
key: "name",
name: "Name",
renderer: (nameField: string, data: Project) => {
return <Link to={`/projects/${orgDictionary[data.organization_id]}/${nameField}`}>{nameField}</Link>
},
},
]
const description = (
<div>
<div className={styles.descriptionLabel}>Run the following command to get started:</div>
<CodeExample code="coder projects create" />
</div>
)
const emptyState = <EmptyState message="No projects have been created yet" description={description} />
const tableProps = {
title: "All Projects",
columns: columns,
emptyState: emptyState,
data: projects,
}
const subTitle = `${projects.length} total`
return (
<div className={styles.root}>
<Navbar user={me} onSignOut={signOut} />
<Header title="Projects" subTitle={subTitle} />
<Paper style={{ maxWidth: "1380px", margin: "1em auto", width: "100%" }}>
<Table {...tableProps} />
</Paper>
<Footer />
</div>
)
}
const useStyles = makeStyles((theme) => ({
root: {
display: "flex",
flexDirection: "column",
},
descriptionLabel: {
marginBottom: theme.spacing(1),
},
}))