frontend/app/ProjectEntryList/ProjectEntryList.tsx (145 lines of code) (raw):
import { Button, Paper, Grid } from "@material-ui/core";
import React, { useEffect, useState } from "react";
import { RouteComponentProps, useHistory, useLocation } from "react-router-dom";
import ProjectFilterComponent from "../filter/ProjectFilterComponent.jsx";
import { isLoggedIn } from "../utils/api";
import { getProjectsOnPage } from "./helpers";
import ProjectsTable from "./ProjectsTable";
import { Helmet } from "react-helmet";
import { buildFilterTerms, filterTermsToQuerystring } from "../filter/terms";
import { useGuardianStyles } from "~/misc/utils";
import { SortDirection } from "~/utils/lists";
const ProjectEntryList: React.FC<RouteComponentProps> = () => {
// React Router
const history = useHistory<Project>();
const { search } = useLocation();
// React state
const [user, setUser] = useState<PlutoUser | null>(null);
const [pageSize, setPageSize] = useState<number>(25);
const [page, setPage] = useState<number>(1);
const [order, setOrder] = useState<SortDirection>("desc");
const [orderBy, setOrderBy] = useState<keyof Project>("created");
const [projects, setProjects] = useState<Project[]>([]);
const [projectCount, setProjectCount] = useState<number>(0);
const [filterTerms, setFilterTerms] = useState<
ProjectFilterTerms | undefined
>(undefined);
// Material-UI
const classes = useGuardianStyles();
const fetchProjectsOnPage = async () => {
const mineOnly = new URLSearchParams(search).has("mine");
if (mineOnly && !user) {
console.log(
"Requested 'my' projects but no user set, waiting until it has been"
);
return;
}
const [projects, count] = await getProjectsOnPage({
page,
pageSize,
filterTerms: filterTerms,
order,
orderBy,
});
setProjects(projects);
setProjectCount(count);
};
useEffect(() => {
if (filterTerms) {
fetchProjectsOnPage();
}
}, [filterTerms, page, pageSize, order, orderBy]);
useEffect(() => {
const fetchWhoIsLoggedIn = async () => {
try {
let user = await isLoggedIn();
user.uid = generateUserName(user.uid);
setUser(user);
} catch (error) {
console.error("Could not login user:", error);
}
};
fetchWhoIsLoggedIn();
}, []);
useEffect(() => {
const currentURL = new URLSearchParams(search).toString();
const isMineInURL = currentURL.includes("mine");
let newFilters = buildFilterTerms(currentURL);
if (isMineInURL) {
newFilters = buildFilterTerms(currentURL, user);
}
if (newFilters.title) {
newFilters.match = "W_CONTAINS";
}
if (newFilters.user === "Mine" && user) {
newFilters.user = user.uid;
}
console.log("filter terms set: ", newFilters);
setFilterTerms(newFilters);
}, [user?.uid]);
const generateUserName = (inputString: string) => {
if (inputString.includes("@")) {
const splitString = inputString.split("@", 1)[0];
const userNameConst = splitString.replace(".", "_");
return userNameConst;
}
return inputString;
};
return (
<>
<Helmet>
<title>All Projects</title>
</Helmet>
<Grid container>
{filterTerms ? (
<Grid item>
<ProjectFilterComponent
filterTerms={filterTerms}
filterDidUpdate={(newFilters: ProjectFilterTerms) => {
console.log(
"ProjectFilterComponent filterDidUpdate ",
newFilters
);
const updatedUrlParams = filterTermsToQuerystring(newFilters);
if (newFilters.user === "Everyone") {
newFilters.user = undefined;
}
if (newFilters.user === "Mine" && user) {
newFilters.user = user.uid;
}
setFilterTerms(newFilters);
history.push("?" + updatedUrlParams);
}}
/>
</Grid>
) : null}
<Grid className={classes.buttonGrid}>
<Button
className={classes.createButton}
variant="contained"
color="primary"
onClick={() => {
history.push("/project/new");
}}
>
New
</Button>
</Grid>
</Grid>
<Paper elevation={3}>
<ProjectsTable
className={classes.table}
pageSizeOptions={[25, 50, 100]}
updateRequired={(page, pageSize, order, orderBy) => {
console.log("ProjectsTable updateRequired");
setPageSize(pageSize);
setPage(page);
setOrder(order);
setOrderBy(orderBy);
}}
projects={projects}
projectCount={projectCount}
user={user}
/>
</Paper>
</>
);
};
export default ProjectEntryList;