Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

88 table view #104

Merged
merged 7 commits into from
Aug 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
"react-i18next": "11.3.5",
"react-mapbox-gl": "^4.8.6",
"react-scripts": "^3.4.1",
"ts-react-json-table": "^0.1.2",
"twilio": "3.42.1"
},
"devDependencies": {
Expand Down
5 changes: 4 additions & 1 deletion src/api/delivery-needed/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ const {
const makeFeature = async (r) => {
let metaJSON = {};
let slackPermalink = {};
let timestamp;

const location = await fetchCoordFromCrossStreets(
`
${r.fields[crossStreetFirst]},
Expand All @@ -42,7 +44,7 @@ const makeFeature = async (r) => {

try {
const channel = metaJSON.slack_channel;
const timestamp = metaJSON.slack_ts;
timestamp = metaJSON.slack_ts;
slackPermalink = await slackapi.chat.getPermalink({
channel,
message_ts: timestamp,
Expand All @@ -69,6 +71,7 @@ const makeFeature = async (r) => {
[forDrivingClusters]: Boolean(r.fields[forDrivingClusters]),
[householdSize]: r.fields[householdSize],
slackPermalink: slackPermalink.ok ? slackPermalink.permalink : "",
timestamp,
slackTs: metaJSON.slack_ts || "",
},
},
Expand Down
6 changes: 5 additions & 1 deletion src/lib/strings/locales/en/webapp.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@
"crossStreetSecond": "Cross Street #2",
"neighborhoodLabel": "Neighborhood",
"neighborhoodError": "If both this and zone are unavailable, double check the map: https://bit.ly/2UrZPkA",
"zone": "{{neighborhood}} Volunteer Zone"
"zone": "{{neighborhood}} Volunteer Zone",
"firstName": "First Name",
"slackLink": "Slack Link",
"timestamp": "Timestamp",
"code": "Code"
},
"geoError": {
"message": "Error loading. Please try again. If it fails again, let us know in"
Expand Down
10 changes: 9 additions & 1 deletion src/webapp/DEVELOPING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,12 @@ Running the React app locally is easy since we use Create React App

`npm run local:react`

You can see the app at `localhost:3000`. Some pages will likely require the API. See `/src/api/DEVELOPING.md` for how to spin that up locally!
You can see the app at `localhost:3000`. Some pages will likely require the API. See `/src/api/DEVELOPING.md` for how to spin that up locally!

## Dependencies

It's easy to run the app, but some features require additional configuration.

## Environment

Starting the app requires a few environment variables. Folks can reach out for access to those variables in #wg_tech.
85 changes: 85 additions & 0 deletions src/webapp/components/DeliveryTable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import React from "react";
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableContainer from "@material-ui/core/TableContainer";
import TableHead from "@material-ui/core/TableHead";
import TableRow from "@material-ui/core/TableRow";
import Paper from "@material-ui/core/Paper";
import { makeStyles } from "@material-ui/core/styles";
import { useTranslation } from "react-i18next";

const useStyles = makeStyles({
container: {
maxHeight: 440,
},
});

const DeliveryTable = ({ rows }) => {
const { t: str } = useTranslation();
const classes = useStyles();

// sort happens in-place
rows.sort((rowA, rowB) => rowB.timestamp - rowA.timestamp);

// format data for presentation
const formattedRows = rows.map((row) => {
const timestamp = new Date(row.timestamp * 1000);

return {
...row,
timestamp: `${timestamp.toLocaleDateString()}: ${timestamp.toLocaleTimeString()}`,
};
});

return (
<TableContainer className={classes.container} component={Paper}>
<Table aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>{str("webapp:zoneFinder.label.code")}</TableCell>
<TableCell align="right">
{str("webapp:zoneFinder.label.crossStreetFirst")}
</TableCell>
<TableCell align="right">
{str("webapp:zoneFinder.label.crossStreetSecond")}
</TableCell>
<TableCell align="right">
{str("webapp:zoneFinder.label.firstName")}
</TableCell>
<TableCell align="right">
{str("webapp:zoneFinder.label.slackLink")}
</TableCell>
<TableCell align="right">
{str("webapp:zoneFinder.label.timestamp")}
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{formattedRows.map((row) => (
<TableRow key={row.Code}>
<TableCell component="th" scope="row">
{row.Code}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you replace these row field strings with those in lib/airtable/tables/requests?

Copy link
Contributor Author

@allthesignals allthesignals Jul 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mjmaurer sure! But how do I import ~airtable/tables/requests into the react app?

If I follow, we're using these row field strings to avoid weird property names ("Cross Street #1").

import Requests from "~airtable/tables/requests"; throws

Module not found: Can't resolve '~airtable/tables/requests' in '/Users/wmattgardner/mutual-aid-app/src/webapp/components'

Importing with relative path throws errors about the dependencies of the thing being imported.

Any ideas? Am I totally missing something? Thanks!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hey @alllthesignals! Michael is out atm, Sherminn here. I think we probably don't have path aliasing set up for the react app, so you might just have to use relative path e.g. ../../lib/airtable. Since this is non-blocking, plus we have other places in the webapp where we need to fix this, im going to go ahead and merge this first and follow up with a new issue to handle hardcoding of airtable field keys.

This table view will be important for the upcoming work for #122, where volunteers can pick up delivery straight from the map. thank you for your contribution!

</TableCell>
<TableCell align="right">{row["Cross Street #1"]}</TableCell>
<TableCell align="right">{row["Cross Street #2"]}</TableCell>
<TableCell align="right">{row["First Name"]}</TableCell>
<TableCell align="right">
<a
href={row.slackPermalink}
target="_blank"
rel="noopener noreferrer"
>
Slack
</a>
</TableCell>
<TableCell align="right">{row.timestamp}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
};

export default DeliveryTable;
100 changes: 57 additions & 43 deletions src/webapp/pages/DeliveryNeeded.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import ListItem from "@material-ui/core/ListItem";
import { useTranslation } from "react-i18next";
import sharedStylesFn from "webapp/style/sharedStyles";
import ClusterMap from "webapp/components/ClusterMap";
import Grid from "@material-ui/core/Grid";
import DeliveryTable from "../components/DeliveryTable";

const useStyles = makeStyles((theme) => ({
...sharedStylesFn(theme),
Expand Down Expand Up @@ -39,6 +41,7 @@ export default function DeliveryNeeded() {
if (error) {
return <Box>{`${error}`}</Box>;
}

return (
<Box className={classes.root}>
<Box className={classes.heading}>
Expand All @@ -55,49 +58,60 @@ export default function DeliveryNeeded() {
geoJsonData={data}
/>
</Box>
<Box className={classes.description}>
<Typography variant="body1">
{str("webapp:deliveryNeeded.mapDesc", {
defaultValue:
'Above is a map of all open requests marked "Delivery Needed"',
})}
</Typography>
<List>
<ListItem>
{str("webapp:deliveryNeeded.description.dot", {
defaultValue: `Each dot represents a location with one or more requests. This
location is only representative of the cross street data. We do not
store full addresses.`,
})}
</ListItem>
<ListItem>
{str("webapp:deliveryNeeded.description.clickDot", {
defaultValue: `Click on each cluster (large circle with a number) to zoom into
individual request.`,
})}
</ListItem>
<ListItem>
{str("webapp:deliveryNeeded.description.popUp", {
defaultValue: `Click on a dot to pop up details. There is a link to the Slack post
for more details, where you can also claim the delivery.`,
})}
</ListItem>
<ListItem>
{str("webapp:deliveryNeeded.description.multipleRequests", {
defaultValue: `Some dots may represent multiple requests at the same cross-streets.
Clicking on them will display all of the requests.`,
})}
</ListItem>
<ListItem>
{str("webapp:deliveryNeeded.description.questions", {
defaultValue: `Questions or concerns? Please let us know in`,
})}
<a href={str("webapp:slack.techChannelUrl")}>
{str("webapp:slack.techChannel")}
</a>
</ListItem>
</List>
</Box>
<Grid container spacing={3}>
<Grid item xs={6}>
<Box className={classes.description}>
<Typography variant="body1">
{str("webapp:deliveryNeeded.mapDesc", {
defaultValue:
'Above is a map of all open requests marked "Delivery Needed"',
})}
</Typography>
<List>
<ListItem>
{str("webapp:deliveryNeeded.description.dot", {
defaultValue: `Each dot represents a location with one or more requests. This
location is only representative of the cross street data. We do not
store full addresses.`,
})}
</ListItem>
<ListItem>
{str("webapp:deliveryNeeded.description.clickDot", {
defaultValue: `Click on each cluster (large circle with a number) to zoom into
individual request.`,
})}
</ListItem>
<ListItem>
{str("webapp:deliveryNeeded.description.popUp", {
defaultValue: `Click on a dot to pop up details. There is a link to the Slack post
for more details, where you can also claim the delivery.`,
})}
</ListItem>
<ListItem>
{str("webapp:deliveryNeeded.description.multipleRequests", {
defaultValue: `Some dots may represent multiple requests at the same cross-streets.
Clicking on them will display all of the requests.`,
})}
</ListItem>
<ListItem>
{str("webapp:deliveryNeeded.description.questions", {
defaultValue: `Questions or concerns? Please let us know in`,
})}
<a href={str("webapp:slack.techChannelUrl")}>
{str("webapp:slack.techChannel")}
</a>
</ListItem>
</List>
</Box>
</Grid>
<Grid item xs={6}>
<Box>
<DeliveryTable
rows={data.requests.features.map((f) => f.properties.meta)}
/>
</Box>
</Grid>
</Grid>
</Box>
);
}