Skip to content

Commit

Permalink
Merge pull request #318 from cityofaustin/4375_mc_comments
Browse files Browse the repository at this point in the history
Adds ability to add Comments to project
  • Loading branch information
mateoclarke authored Jun 3, 2021
2 parents 3912c16 + 7d83519 commit 7aade0c
Show file tree
Hide file tree
Showing 8 changed files with 25,490 additions and 47 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE "public"."moped_proj_notes" ALTER COLUMN "comm_id" SET NOT NULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE "public"."moped_proj_notes" ALTER COLUMN "comm_id" DROP NOT NULL;
25,293 changes: 25,263 additions & 30 deletions moped-editor/package-lock.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions moped-editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,15 @@
"axios": "^0.21.1",
"chart.js": "^2.9.3",
"clsx": "^1.1.1",
"dompurify": "^2.2.8",
"env-cmd": "^10.1.0",
"filepond": "^3.6.0",
"filepond-plugin-file-validate-size": "^2.1.1",
"filepond-plugin-image-exif-orientation": "^1.0.3",
"filepond-plugin-image-preview": "^3.1.4",
"formik": "^2.1.5",
"history": "^5.0.0",
"html-react-parser": "^1.2.6",
"lodash.foreach": "^4.5.0",
"lodash.get": "^4.4.2",
"lodash.toarray": "^4.4.0",
Expand All @@ -75,6 +77,7 @@
"react-map-gl-draw": "^0.22.3",
"react-map-gl-geocoder": "^2.1.6",
"react-perfect-scrollbar": "^1.5.8",
"react-quill": "^1.3.5",
"react-router": "^6.0.0-beta.0",
"react-router-dom": "^6.0.0-beta.0",
"react-scripts": "^3.4.1",
Expand Down
3 changes: 3 additions & 0 deletions moped-editor/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ import {

const HASURA_ENDPOINT = process.env.REACT_APP_HASURA_ENDPOINT;

var pckg = require("../package.json");
console.log(`🛵 ${pckg.name} ${pckg.version}`);

const App = () => {
const restrictedRoutes = restrictRoutes(routes);
const routing = useRoutes(restrictedRoutes);
Expand Down
216 changes: 216 additions & 0 deletions moped-editor/src/views/projects/projectView/ProjectComments.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
import React, { useState } from "react";
import Page from "src/components/Page";
import {
Avatar,
Box,
Container,
Card,
CircularProgress,
Divider,
Grid,
List,
ListItem,
ListItemAvatar,
ListItemText,
Typography,
} from "@material-ui/core";
import AddBoxIcon from "@material-ui/icons/AddBox";

import { makeStyles } from "@material-ui/core/styles";
import { getSessionDatabaseData } from "src/auth/user";
import { useQuery, useMutation } from "@apollo/client";
import { gql } from "apollo-boost";
import { useParams } from "react-router-dom";
import parse from "html-react-parser";
import DOMPurify from "dompurify";
import ReactQuill from "react-quill";
import "react-quill/dist/quill.snow.css";
import ProjectSaveButton from "../newProjectView/ProjectSaveButton";

const COMMENTS_QUERY = gql`
query getProjectComments($projectId: Int!) {
moped_proj_notes(where: { project_id: { _eq: $projectId } }) {
added_by
project_note
project_id
date_created
project_note_id
}
}
`;

const ADD_PROJECT_COMMENT = gql`
mutation AddProjectComment($objects: [moped_proj_notes_insert_input!]!) {
insert_moped_proj_notes(objects: $objects) {
returning {
project_id
project_note
}
}
}
`;

const quillModules = {
toolbar: [
["bold", "italic", "underline", "strike"],
[{ list: "ordered" }, { list: "bullet" }],
["link"],
["clean"],
],
};

const useStyles = makeStyles(theme => ({
root: {
width: "100%",
backgroundColor: theme.palette.background.paper,
},
commentorText: {
display: "inline",
fontWeight: "bold",
},
noteText: {
marginTop: theme.spacing(1),
},
emptyState: {
margin: theme.spacing(3),
},
}));

const ProjectComments = () => {
const { projectId } = useParams();
const classes = useStyles();
const userSessionData = getSessionDatabaseData();
const [noteText, setNoteText] = useState("");
const [commentAddLoading, setCommentAddLoading] = useState(false);
const [commentAddSuccess, setCommentAddSuccess] = useState(false);

const { loading, error, data, refetch } = useQuery(COMMENTS_QUERY, {
variables: { projectId },
});

const [addNewComment] = useMutation(ADD_PROJECT_COMMENT, {
onCompleted() {
setNoteText("");
refetch();
setCommentAddSuccess(true);
setTimeout(() => {
setCommentAddLoading(false);
setCommentAddSuccess(false);
}, 350);
},
});

// If the query is loading or data object is undefined,
// stop here and just render the spinner.
if (loading || !data) return <CircularProgress />;

if (error) return console.log(error);

const submitNewComment = () => {
setCommentAddLoading(true);
addNewComment({
variables: {
objects: [
{
added_by: `${userSessionData.first_name} ${userSessionData.last_name}`,
project_note: DOMPurify.sanitize(noteText),
project_id: projectId,
},
],
},
});
};

return (
<Page title="Project Notes">
<Container>
<Grid container spacing={2}>
<Grid item xs={12}>
<Card>
{data.moped_proj_notes.length > 0 ? (
<List className={classes.root}>
{data.moped_proj_notes.map((item, i) => {
let isNotLastItem = i < data.moped_proj_notes.length - 1;
return (
<>
<ListItem alignItems="flex-start">
<ListItemAvatar>
<Avatar />
</ListItemAvatar>
<ListItemText
primary={
<>
<Typography className={classes.commentorText}>
{item.added_by}
</Typography>
<Typography variant="button">
{` - ${new Date(
item.date_created
).toLocaleDateString("en-US", {
year: "numeric",
month: "long",
day: "numeric",
})}`}
</Typography>
</>
}
secondary={
<Typography className={classes.noteText}>
{parse(item.project_note)}
</Typography>
}
/>
</ListItem>
{isNotLastItem && (
<Divider variant="inset" component="li" />
)}
</>
);
})}
</List>
) : (
<Typography className={classes.emptyState}>
No comments to display
</Typography>
)}
</Card>
</Grid>
<Grid item xs={12}>
<Card>
<Container>
<Grid xs={12} sm={10} container direction="column" spacing={1}>
<Grid item>
<Box pt={2}>
<ReactQuill
theme="snow"
value={noteText}
onChange={setNoteText}
modules={quillModules}
/>
</Box>
</Grid>
<Grid item>
<Box pb={2}>
<ProjectSaveButton
label={
<>
<AddBoxIcon /> <Box ml={1}>Add comment</Box>
</>
}
loading={commentAddLoading}
success={commentAddSuccess}
handleButtonClick={submitNewComment}
/>
</Box>
</Grid>
</Grid>
</Container>
</Card>
</Grid>
</Grid>
</Container>
</Page>
);
};

export default ProjectComments;

This file was deleted.

6 changes: 3 additions & 3 deletions moped-editor/src/views/projects/projectView/ProjectView.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import Page from "src/components/Page";
import ProjectSummary from "./ProjectSummary";
import ProjectTeam from "./ProjectTeam";
import ProjectTimeline from "./ProjectTimeline";
import ProjectTabPlaceholder from "./ProjectTabPlaceholder";
import ProjectComments from "./ProjectComments";
import ProjectFiles from "./ProjectFiles";
import TabPanel from "./TabPanel";
import { PROJECT_ARCHIVE, SUMMARY_QUERY } from "../../../queries/project";
Expand Down Expand Up @@ -98,7 +98,7 @@ const TABS = [
{ label: "Files", Component: ProjectFiles, param: "files" },
{ label: "Team", Component: ProjectTeam, param: "team" },
{ label: "Timeline", Component: ProjectTimeline, param: "timeline" },
{ label: "Notes", Component: ProjectTabPlaceholder, param: "notes" },
{ label: "Comments", Component: ProjectComments, param: "comments" },
{
label: "Activity Log",
Component: ProjectActivityLog,
Expand Down Expand Up @@ -380,7 +380,7 @@ const ProjectView = () => {
const TabComponent = tab.Component;
return (
<TabPanel key={tab.label} value={activeTab} index={i}>
<TabComponent
<TabComponent
loading={loading}
data={data}
error={error}
Expand Down

0 comments on commit 7aade0c

Please sign in to comment.