Skip to content
Open
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
1 change: 1 addition & 0 deletions pavement.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ def jslint():
"""Run linting on javascript
"""
files = recursive_glob('*.js', 'scripts', 'planner/static', 'test')
files.remove('planner/static/jquery.dform-1.1.0.min.js')
return sh('phantomjs scripts/jslintrunner.js ' + ' '.join(files))


Expand Down
78 changes: 69 additions & 9 deletions planner/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
from flask import Flask, abort, current_app, render_template, Blueprint
from flask import (Flask, abort, current_app, render_template,
Blueprint, request)

import datetime

import planner
from planner.model.connect import TransactionFactory
from planner.model.client import Client, Contact
from planner.model.iteration import Iteration
from planner.model.translate import to_dict, to_model
from planner.flags import Flag
from planner.config import HeadConfig
from planner.form_data.add_contact import convert_client_dict_form_json
from planner.form_data.add_iteration import convert_iteration_dict_form_json
import json


ui = Blueprint('views', __name__, template_folder="templates")
api = Blueprint('api', __name__, template_folder="templates")
ui = Blueprint('views', __name__, template_folder='templates')
api = Blueprint('api', __name__, template_folder='templates')
feature = Flag(lambda: abort(404), config=lambda: current_app.config)


Expand All @@ -30,7 +39,10 @@ def index():
@ui.route('/schedule')
@feature
def schedule():
return render_template('schedule.html')
with current_app.transaction() as transaction:
iterations = transaction.query(Iteration).all()
# engagements = transaction.query(Engagement).all()
return render_template('schedule.html', iterations=iterations)


@ui.route('/add-engagement')
Expand All @@ -42,7 +54,17 @@ def add_engagement():
@ui.route('/clients')
@feature
def clients():
return render_template("clients.html")
with current_app.transaction() as transaction:
clients = transaction.query(Client).all()
return render_template("clients.html", clients=clients)


@ui.route('/clients/<int:client_id>', methods=["GET"])
@feature
def client(client_id):
with current_app.transaction() as transaction:
client = transaction.query(Client).get(client_id)
return render_template("contacts.html", client=client)


@ui.route('/add-client')
Expand All @@ -51,10 +73,48 @@ def add_client():
return render_template("add-client.html")


@ui.route('/add-contact')
@ui.route('/add-iteration')
@feature
def add_iteration():
form_data = convert_iteration_dict_form_json()
with open("planner/static/add_iteration_form.json", 'w') as f:
json.dump(form_data, f)
return render_template("add-iteration.html")


@api.route('/iteration/new', methods=["POST"])
def save_new_iteration():
form_data = request.form
iteration = to_model(form_data, planner.model.iteration)
date_string = "".join(iteration.startdate.split("/"))
try:
iteration.startdate = datetime.datetime.strptime(date_string,
"%d%m%Y")
except ValueError:
return render_template("add_iteration_validation_error.html")
with current_app.transaction() as transaction:
transaction.add(iteration)
return schedule()


@ui.route('/clients/<int:client_id>/new')
@feature
def add_contact():
return render_template('add-contact.html')
def add_contact(client_id):
contact = to_dict(Contact(clientid=client_id))
form_data = convert_client_dict_form_json(contact)
filename = "planner/static/add_contact_form_%d.json" % (client_id)
with open(filename, 'w') as f:
json.dump(form_data, f)
return render_template('add-contact.html', clientid=client_id)


@api.route('/clients/<int:client_id>/add', methods=["POST"])
def save_new_contact(client_id):
form_data = request.form
contact = to_model(form_data, planner.model.client)
with current_app.transaction() as transaction:
transaction.add(contact)
return client(client_id)


@api.route('/api/schedule/iteration-for-engagement')
Expand Down
Empty file added planner/form_data/__init__.py
Empty file.
62 changes: 62 additions & 0 deletions planner/form_data/add_contact.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
def convert_client_dict_form_json(client_dict):
print 'function_called with id %s' % (client_dict["clientid"])
contact_keys = client_dict.keys()
form_data = {"action": "/clients/%d/add" % (client_dict["clientid"]),
"method": "post", "html": []}
keys_to_exclude = ["clientid", "entity", "id"]
for key in contact_keys:
if key not in keys_to_exclude:
key_formatted = format_key_for_form_caption(key)
key_upper_case = key_formatted.title()
form_data["html"].append({"type": "text",
"caption": key_upper_case,
"name": key})
form_data["html"] = order_html_elements(form_data["html"])
form_data["html"].append({"type": "submit",
"value": "Add Contact"})
form_data["html"].append({"type": "hidden",
"value": "Contact",
"name": "entity"})
form_data["html"].append({"type": "hidden",
"value": client_dict["clientid"],
"name": "clientid"})
return form_data


def format_key_for_form_caption(key):
splits = ["no", "number", "code"]
if any(string in key for string in splits):
split_on = [string for string in splits if string in key][0]
print key.split(split_on)
key = " ".join(key.split(split_on)) + split_on
if key == "streetname":
key = "Street Name"
return key


# this is basically hard coding, so very fragile
def order_html_elements(list_of_form_fields):
ordered_list = []
names = [entry for entry in list_of_form_fields
if "name" in entry["name"] and
"street" not in entry["name"]]
ordered_list.extend(names)
role = get_specific_entry(list_of_form_fields, "role")
ordered_list.extend(role)
email = get_specific_entry(list_of_form_fields, "email")
email[0]["placeholder"] = "name@example.com"
ordered_list.extend(email)
ordered_list.append({"type": "p", "html": "Telephone information"})
numbers = get_specific_entry(list_of_form_fields, "no")
ordered_list.extend(numbers)
ordered_list.append({"type": "p", "html": "Address information"})
street_info = get_specific_entry(list_of_form_fields, "street")
ordered_list.extend(street_info)
post_code = get_specific_entry(list_of_form_fields, "code")
ordered_list.extend(post_code)
return ordered_list


def get_specific_entry(list_of_form_fields, keyword):
return [entry for entry in list_of_form_fields
if keyword in entry["name"]]
12 changes: 12 additions & 0 deletions planner/form_data/add_iteration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
def convert_iteration_dict_form_json():
form_data = {"action": "/iteration/new",
"method": "post",
"html": [{"type": "text",
"caption": "Start Date",
"name": "startdate"},
{"type": "submit",
"value": "Add Iteration"}]}
form_data["html"].append({"type": "hidden",
"value": "Iteration",
"name": "entity"})
return form_data
23 changes: 0 additions & 23 deletions planner/model/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from sqlalchemy import Column, Integer, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base


Expand All @@ -8,24 +6,3 @@ class ValidationError(Exception):


Base = declarative_base()


class EngagementIteration(Base):
__tablename__ = 'EngagementIteration'
engagementid = Column(Integer, ForeignKey('Engagement.id'),
primary_key=True)
iterationid = Column(Integer, ForeignKey('Iteration.id'), primary_key=True)

engagement = relationship("Engagement")
iteration = relationship("Iteration")


class EstimatedEngagementIteration(Base):
__tablename__ = 'EstimatedEngagementIteration'
engagementid = Column(Integer, ForeignKey('Engagement.id'),
primary_key=True)
iterationid = Column(Integer, ForeignKey('Iteration.id'),
primary_key=True)

engagement = relationship("Engagement")
iteration = relationship("Iteration")
21 changes: 21 additions & 0 deletions planner/model/engagement.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,24 @@ def validate_value(self, key, address):
if address not in [0.1, 0.5, 1.0, 2.0]:
raise ValidationError(str(address) + ' is invalid')
return address


class EngagementIteration(Base):
__tablename__ = 'EngagementIteration'
engagementid = Column(Integer, ForeignKey('Engagement.id'),
primary_key=True)
iterationid = Column(Integer, ForeignKey('Iteration.id'), primary_key=True)

engagement = relationship("Engagement")
iteration = relationship("Iteration")


class EstimatedEngagementIteration(Base):
__tablename__ = 'EstimatedEngagementIteration'
engagementid = Column(Integer, ForeignKey('Engagement.id'),
primary_key=True)
iterationid = Column(Integer, ForeignKey('Iteration.id'),
primary_key=True)

engagement = relationship("Engagement")
iteration = relationship("Iteration")
2 changes: 1 addition & 1 deletion planner/model/team.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class TeamMember(Base):
def validate_title(self, key, address):
if address not in ['Mr', 'Miss', 'Dr', 'Mrs']:
raise ValidationError(
str(address) + " is not an appropriate title")
str(address) + " is not an appropriate title")
return address

@validates('gmail')
Expand Down
7 changes: 7 additions & 0 deletions planner/static/add_iteration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*global $, document
*/

$(document).ready(function () {
"use strict";
$("#add_iteration").dform("/static/add_iteration_form.json");
});
2 changes: 2 additions & 0 deletions planner/static/jquery.dform-1.1.0.min.js

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

6 changes: 6 additions & 0 deletions planner/static/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,9 @@ canvas {
textarea.form-control {
height: 150px;
}


label, input {
display: block;
margin-top: 10px;
}
9 changes: 7 additions & 2 deletions planner/templates/add-contact.html
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
{% extends "base.html" %}
{% from "macros.html" import render_form %}
{% block content %}
<div class="container">
<h3>Add Contact</h3>
{{ render_form(form, action_url=url_for('add_contact', client_id=client_id)) }}
{# removed action url as specified in javascript #}
{# {{ render_form("add_contact", client_id=client_id) }}#}
<script type="text/javascript">$(document).ready(function() {
$("#add_contact").dform("/static/add_contact_form_{{clientid}}.json")// if successful, render form
});
</script>
<form id="add_contact" client_id="{{clientid}}" enctype="application/json"></form>
</div>
{% endblock %}
7 changes: 7 additions & 0 deletions planner/templates/add-iteration.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{% extends "base.html" %}
{% block content %}
<div class="container">
<h3>Add Iteration</h3>
<form id="add_iteration" enctype="application/json"></form>
</div>
{% endblock %}
8 changes: 8 additions & 0 deletions planner/templates/add_iteration_validation_error.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{% extends "base.html" %}
{% block content %}
<div class="container">
<h3>Add Iteration</h3>
<p>Please give start date in format "dd/mm/yyyy" e.g. 01/01/2016</p>
<form id="add_iteration" enctype="application/json"></form>
</div>
{% endblock %}
10 changes: 8 additions & 2 deletions planner/templates/base.html
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,16 @@
<meta http-equiv="X-UA-COMPATIBLE" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
<link rel="stylesheet"
href="//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="/static/main.css">
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="//code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script
src="//netdna.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script
src="/static/jquery.dform-1.1.0.min.js"></script>
<script type="text/javascript" src="/static/add_iteration.js"></script>
<title>Planner</title>
</head>

Expand Down
2 changes: 1 addition & 1 deletion planner/templates/clients.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<tbody id="clients">
{% for client in clients %}
<tr>
<th scope="row">{{ client.client }}</th>
<th scope="row">{{ client.name }}</th>
<td id="iter{client.id}" client="{{ client.name }} ">
<a href="/clients/{{client.id}}">Contact List</a>
</td>
Expand Down
Loading