Commit dd7677cc authored by David Haynes's avatar David Haynes 🙆

Merge branch '188-crud-debug-page' into 'go-three'

Resolve "CRUD Debug Page"

Closes #188

See merge request !131
parents b1c61f3c eac06503
Pipeline #3821 passed with stage
in 1 minute and 17 seconds
......@@ -2,7 +2,6 @@
*.swp
*.pyc
.virtualenv
.vagrant/
venv
.venv
/provisioning/playbook.retry
......@@ -14,7 +13,122 @@ htmlcov/
.idea
__pycache__/
.vscode
go/sourceme.sh
.DS_STORE
node_modules/
go/static/
go/static/main.js
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
......@@ -8,7 +8,30 @@ in an open source repo.
**Note:**
You will need to be a member before making any contributions. Join the slack #go channel and ask nicely.
You will need to be **a member** before making any contributions. Join the slack #go channel and ask.
### Issues
Issues can be opened on gitlab and must adhere to the provided template:
```
# Summary
Here you should include two to three sentences explaining the thought process
about the current issue. Maybe a picture? Some details that could best help someone,
especially someone new, understand the goal of the issue and how they should best
approach the problem.
## Helpful Links
Here you should include a bullet point list of links to documentation, stack overflow,
whatever, that could help guide someone on what it is they are trying to do.
Essentially, a list of links to point them in the right direction.
```
Issues will be closed if they do not adhere to the standard.
You can claim issues by asking in the #go channel whether you can work on it. The project manager will then assign them to you in gitlab.
### Branches
......@@ -17,34 +40,39 @@ add, modify, or remove features/bugs from Go. Our list of tasks can be found on
the issues page.
If you decide to take on an issue for Go you will need to work in a branch off
of the current development branch (ie. `2.3-dev` with 2.3 being the version in
development).
of the current development branch (ie. `go-three`).
This can be done with the following chain of `git` commands within `go/`:
```sh
git pull
git checkout 2.3-dev
git checkout -B ##-shortdescription
```
**Note:**
Replace `##` with the issue number that you are working on, and replace
`shortdescription` with a few words (<=4) that in brief describe what the branch
`short-description` with a few words that in brief describe what the branch
does.
**Example:**
```sh
git pull
git checkout go-three
git checkout -B ##-short-description
```
**Example Workflow:**
```sh
git pull
git checkout 2.3-dev
git checkout -B 102-readmeUpdates
git checkout go-three
git checkout -B 102-readme-updates
```
If you are working on something that does not have an issue please open a new
issue before creating your branch.
Once you've written commits in a branch you will need to push your commits to gitlab.
git push origin ##-branchname
`origin` is gitlab.
### Commits & Their Messages
It is important to commit more often than not such that if we run into issues we
......@@ -54,7 +82,7 @@ Commit messages should follow the format:
#### Title -
Should fill in the blank:
Should fill in the blank (Don't actually write "This commit", just the part that comes after!):
This commit ______
......@@ -74,19 +102,13 @@ They don't have to be super serious (see any of my commits) though just a tad bi
Example commit description:
- mostly talk about how great SRCT (and :dhaynes:) is
- plus a short blurb on how we can ban you
- Composed a short blurb on how banning works
- Composed a description of SRCT
[Example full commit](https://git.gmu.edu/srct/go/commit/db89af2e4ffd06a6044d3301a3f7a45ced74799a)
### Merging to the current development branch
Once you've finished work in a branch you will need to push your commits to gitlab.
git push origin ##-branchname
`Origin` is gitlab.
Open a [merge request](https://git.gmu.edu/srct/go/merge_requests/new)
to start the process of getting your code into the repo. Your code wil be reviewed
by another member before being merged. Your code must pass our tests and include
......
......@@ -14,3 +14,9 @@ ADD . /go/
# Install pip dependecies
RUN pip install pipenv
RUN pipenv install --system --deploy
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash -
RUN apt-get install -y nodejs
RUN apt-get install -y build-essential
RUN npm install -g yarn
\ No newline at end of file
......@@ -22,3 +22,6 @@ mysqlclient = "*"
[requires]
python_version = "3.7"
[pipenv]
allow_prereleases = true
......@@ -32,19 +32,19 @@
},
"django": {
"hashes": [
"sha256:25df265e1fdb74f7e7305a1de620a84681bcc9c05e84a3ed97e4a1a63024f18d",
"sha256:d6d94554abc82ca37e447c3d28958f5ac39bd7d4adaa285543ae97fb1129fd69"
"sha256:0292a7ad7d8ffc9cfc6a77f043d2e81f5bbc360c0c4a1686e130ef3432437d23",
"sha256:e89f613e3c1f7ff245ffee3560472f9fa9c07060b11f65e1de3cb763f8dcd4b9"
],
"index": "pypi",
"version": "==2.0.9"
"version": "==2.0.10"
},
"django-cas-client": {
"hashes": [
"sha256:2a190c9e651df3a65840206b38a9fc1c2c404696fcaf66fc69a684591f56d978",
"sha256:4d941d58769437e56656464c91461e61eee27ff2dac3ed53766e0042bc33169a"
"sha256:6d71d59db35f8a7677ee654dc9d4eac5c8aea3205273710fb71e077d139f6f7d",
"sha256:f1b3106447c4e0920ffaf9a7d8fd63829c7105e88b89bbdc90fbf65112897131"
],
"index": "pypi",
"version": "==1.4.0"
"version": "==1.5.0"
},
"django-crispy-forms": {
"hashes": [
......@@ -100,10 +100,10 @@
},
"pytz": {
"hashes": [
"sha256:31cb35c89bd7d333cd32c5f278fca91b523b0834369e757f4c5641ea252236ca",
"sha256:8e0f8568c118d3077b46be7d654cc8167fa916092e28320cde048e54bfc9f1e6"
"sha256:32b0891edff07e28efe91284ed9c31e123d84bea3fd98e1f72be2508f43ef8d9",
"sha256:d5f05e487007e29e03409f9398d074e158d920d36eb82eaf66fb1136b0c5374c"
],
"version": "==2018.7"
"version": "==2018.9"
},
"redis": {
"hashes": [
......
......@@ -9,64 +9,97 @@ term maintenance. Additionally, since the core of the project is fairly simple,
2.0 functioned as a good introduction to open source development for new
members.
Go 3.0 is currently in production with the goal of modernizing the project with new functionality.
A project of [GMU SRCT](https://srct.gmu.edu).
## Architecture of the project
### `go_back`
`go_back` is the API backend of the project. It is built with the Django REST
Framework (python). It supports all CRUD (Create, Read, Update, Delete)
operations on Go links as well as RegisteredUser account management.
### `go_ahead`
### `go_ahead` | The react app
`go_ahead` is the ReactJS frontend of the project. It is built with the React
`go_ahead` is the react.js frontend of the project. It is built with the React
JavaScript framework to allow for rapid development and experimentation. There
is also a lot of interactivty that the framework allows that we can leverage
for a smooth user experience.
## Getting started with contributing
There's a workflow involved with getting started contributing but once you do
it once or twice it'll seem a lot less daunting.
1. Running `go_ahead` | React / Webpack
You'll need node installed.
```sh
npm install -g yarn
yarn
yarn dev
```
This starts a foreground process that will rebuild the React site whenever
there is a change.
2. Running `go_back` | Docker
### `go_back` | The django API
You'll need Docker and docker-compose installed.
In another terminal tab from the `yarn` one:
```sh
docker-compose up
```
3. Misc. | Actually coding
All JS changes will require a refresh (Webpack rebuilds the app in the background).
All Python changes will require a refresh.
To pull in python dependecies and work in a contained environment we use `pipenv`.
```
pipenv install
pipenv shell
```
4) Deployment of changes
See me.
`go_back` is the API backend of the project. It is built with the Django REST
Framework (python). It supports all CRUD (Create, Read, Update, Delete)
operations on Go links as well as account management.
## How to get up and running
As always, the first step is to get the project running on your local machine.
Consult the [docker documentation](https://docs.docker.com/install/) for instructions on how to install Docker CE and the [docker-compose documentation](https://docs.docker.com/compose/install/) on how to install Docker Compose.
Run:
```sh
docker-compose build
docker-compose up
```
Navigate to [127.0.0.1:8000](http://127.0.0.1:8000) after the compose process has finished running to access the app.
## How to contribute to the project
1. Go to [the issues page](https://git.gmu.edu/srct/go/issues) and look at what needs to be done, and have a cursory choice of something.
1. Review [CONTRIBUTING.md](https://git.gmu.edu/srct/go/blob/go-three/CONTRIBUTING.md)
1. Review the documentation for individual components:
1. [`go_ahead` documentation](https://git.gmu.edu/srct/go/blob/go-three/go/go_ahead/README.md)
1. [`go_back` documentation](https://git.gmu.edu/srct/go/blob/go-three/go/go_back/README.md)
1. Get to the #go channel in SRCT Slack and ask for assistance.
## Other
- Make sure to ask any questions you have in the #go channel in SRCT Slack
- Go 3 logo was created by <a href="https://www.youtube.com/watch?v=dQw4w9WgXcQ">Andres Villogas</a>
- Don't worry if nothing makes sense, we all start there.
- This project was made possible through the collective contributions of multiple Mason SRCT members:
<a href="https://git.gmu.edu/srct/go/milestones/3">Go 2.2</a>:
<br />
<a href="https://github.com/dhaynespls">David Haynes</a>,
<a href="https://github.com/ocelotsloth">Mark Stenglein</a>,
<a href="https://www.youtube.com/watch?v=dQw4w9WgXcQ">
Andres Villogas
</a>
,<a href="https://github.com/IAmEyad">Eyad Hasan</a>,
<a href="https://github.com/zosman1">Zach Osman</a>,
<a href="">Leo Grandinetti</a>,
<a href="https://mason.gmu.edu/~gmoran/">Grady Moran</a>,
<a href="https://github.com/zmknox">Zach Knox</a>,
<a href="https://github.com/mike-bailey">Michael Bailey</a>,
<a href="https://github.com/jrouly">Michel Rouly</a>,
<a href="https://github.com/nanderson94">Nicholas Anderson</a>,
<a href="">Kevin Mckigney</a>, and
<a href="https://github.com/dwbond">Daniel Bond</a>.<br />
<a href="https://git.gmu.edu/srct/go/milestones/2">Go 2.1</a>:
<br />
<a href="https://github.com/dhaynespls">David Haynes</a>,
<a href="https://github.com/zosman1">Zach Osman</a>,
<a href="https://github.com/roberthitt">Robert Hitt</a>,
<a href="https://github.com/nanderson94">Nicholas Anderson</a>,
<a href="https://github.com/zmknox">Zach Knox</a>,
<a href="https://github.com/mike-bailey">Michael Bailey</a>,
<a href="https://github.com/mdsecurity">Mattias Duffy</a>,
<a href="https://github.com/IAmEyad">Eyad Hasan</a>, and
<a href="https://github.com/danielkim1">Danny Kim</a>.<br />
<a href="https://git.gmu.edu/srct/go/milestones/1">Go 2.0</a>:
<br />
<a href="https://github.com/dhaynespls">David Haynes</a>,
<a href="">Matthew Rodgers</a>,
<a href="https://github.com/nanderson94">Nicholas Anderson</a>, and
<a href="https://github.com/dwbond">Daniel Bond</a>.<br />
Go 1.0:
<br />
<a href="https://github.com/jrouly">Michel Rouly</a>,
<a href="https://github.com/creffett">Chris Reffett</a>,
<a href="https://github.com/nanderson94">Nicholas Anderson</a>, and
<a href="https://github.com/akshaykarthik">Akshay Karthik</a>.
<br />
#! /bin/bash
export GO_SECRET_KEY
until nc -z db 3306; do
echo "waiting for database to start..."
sleep 1
done
export GO_SECRET_KEY
export GO_CREATE_SUPERUSER
GO_SECRET_KEY=$(dd if=/dev/urandom count=100 | tr -dc "A-Za-z0-9" | fold -w 60 | head -n1 2>/dev/null)
yarn build
python go/manage.py makemigrations
python go/manage.py makemigrations go_back
python go/manage.py makemigrations go_ahead
python go/manage.py migrate
python go/manage.py runserver 0.0.0.0:8000
\ No newline at end of file
# go_ahead
# go_ahead | The react app
Words on how to code in React.
[React is a JavaScript library for building user interfaces.](https://reactjs.org/) The focus of the library is on component design and implementation.
I'll be the first one to admit that it is very daunting to jump into a React project if you are unfamiliar with the library, javascript, and general modern web developemnt trends. To help with that learning curve I have two suggested resources:
1. [A re-introduction to JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript) | A great start to reviewing JS and how you can translate knowledge from other languages into it.
1. [React Main Concepts](https://reactjs.org/docs/hello-world.html) | A step by step walkthrough of React, component architecture, and how you can best utilize the React API.
## React project structure
Take a chance to review the layout of the app:
```
src/
├── App.jsx | The entry point for our React app.
├── Components
│   ├── Molecules | All reusable components that are individual.
│   │   └── index.js
│   ├── Organisms | Containers for molecule components.
│   │   └── index.js
│   ├── Pages | Containers for organisms.
│   │   └── index.js
│   ├── Templates | Containers for pages.
│   │   └── index.js
│   └── index.js
└── Utils | Misc. standalone JS functions.
└── index.js
```
## Dev work
Since we will need to rebuild our app on a regular basis as we edit the javascript we need to start a process that watches the code and rebuilds the app.
You'll need [node installed](https://nodejs.org/en/download/package-manager/).
```sh
npm install -g yarn
yarn
yarn dev
```
This starts a foreground process that will rebuild the React site whenever
there is a change.
Make sure you are running this alongside the docker-compose process so that you can visit the site at [127.0.0.1:8000](http://127.0.0.1:8000)
All react errors are printed to the webpack console stdout.
Make sure to check your web browser's JS console as well!
......@@ -7,6 +7,10 @@ import { Routes } from "Utils";
import "masonstrap/build/css/masonstrap.min.css";
import "masonstrap/build/js/masonstrap.min.js";
// Other
import "react-dates/initialize";
import "react-dates/lib/css/_datepicker.css";
ReactDOM.render(
<HashRouter>
<Routes />
......
......@@ -27,17 +27,21 @@ class AuthButton extends React.Component {
render() {
const { is_auth, error } = this.state;
if (error) {
return <div>Error: {error.message}</div>;
return (
<Button outline color="accent">
Error: {error.message}
</Button>
);
} else {
return (
<div>
{is_auth ? (
<Button color="info" href="/auth/logout">
Logout
<Button outline color="accent" href="/auth/logout">
Logout <i className="fas fa-sign-out-alt" />
</Button>
) : (
<Button color="info" href="/auth/login">
Login
<Button outline color="accent" href="/auth/login">
Login <i className="fas fa-sign-in-alt" />
</Button>
)}
</div>
......
import React from "react";
import * as Yup from "yup";
import { Formik, Field, Form, ErrorMessage } from "formik";
import { GetCSRFToken } from "../../Utils";
import { SingleDatePicker } from "react-dates";
import moment from "moment";
import { FormGroup, Button, Card, CardBody, CardTitle } from "reactstrap";
const DebugCreateYup = Yup.object().shape({
destination: Yup.string()
.url()
.max(1000, "Too Long!"),
short: Yup.string()
.required("Required")
.max(20, "Too Long!"),
expires: Yup.date()
.nullable()
.min(new Date())
});
class DebugCreate extends React.Component {
constructor(props) {
super(props);
this.state = {
focused: false
};
}
render() {
return (
<Card>
<CardBody>
<CardTitle>Create</CardTitle>
<Formik
initialValues={{
short: "",
destination: "",
expires: moment(new Date())
}}
validationSchema={DebugCreateYup}
onSubmit={({ destination, short, expires }, { setSubmitting }) => {
const newValues = {
destination: destination,
short: short,
date_expires: expires.format()
};
fetch("/api/golinks/", {
method: "post",
headers: {
"Content-Type": "application/json",
"X-CSRFToken": GetCSRFToken()
},
body: JSON.stringify(newValues)
})
.then(response => console.log(response))
.then(setSubmitting(false));
}}
render={({ values, isSubmitting, setFieldValue }) => (
<Form>
<FormGroup>
{"Destination: "}
<Field
className="form-control"
name="destination"
placeholder="https://longwebsitelink.com"
/>
<ErrorMessage name="destination" component="div" />
</FormGroup>
<FormGroup>
{"Short: "}
<Field className="form-control" name="short" />
<ErrorMessage name="short" />
</FormGroup>
<FormGroup>
{"Expires: "}
<br />
<SingleDatePicker
date={values["expires"]} // momentPropTypes.momentObj or null
onDateChange={date => setFieldValue("expires", date)} // PropTypes.func.isRequired
focused={this.state.focused} // PropTypes.bool
onFocusChange={({ focused }) => this.setState({ focused })} // PropTypes.func.isRequired
id="expires" // PropTypes.string.isRequired,
/>
<ErrorMessage name="expires" />
</FormGroup>
<Button
type="submit"
disabled={isSubmitting}
outline
color="primary"
>
Submit
</Button>
</Form>
)}
/>
</CardBody>
</Card>
);
}
}
export default DebugCreate;
import React from "react";
import * as Yup from "yup";
import { GetCSRFToken } from "../../Utils";
import { Formik, Field, Form, ErrorMessage } from "formik";
import { Button, Card, CardBody, CardTitle, FormGroup } from "reactstrap";
const DebugDeleteYup = Yup.object().shape({
short: Yup.string()
.required("Required")
.max(20, "Too Long!")
});
const DebugDelete = () => (
<div>
<Card>
<CardBody>
<CardTitle>Delete</CardTitle>
<Formik
initialValues={{ short: "" }}
validationSchema={DebugDeleteYup}
onSubmit={(values, { setSubmitting }) => {
const deleteURL = "/api/golinks/" + values.short;
fetch(deleteURL, {
method: "delete",
headers: {
"Content-Type": "application/json",
"X-CSRFToken": GetCSRFToken()
}
})
.then(response => console.log(response))
.then(setSubmitting(false));
}}
render={({ isSubmitting }) => (
<Form>
<FormGroup>
{"Short: "}
<Field className="form-control" name="short" />
<ErrorMessage name="short" />