From c03a3cef69449e703cb906bd3bc97ba4fd216c92 Mon Sep 17 00:00:00 2001 From: aranzaiger Date: Thu, 18 Jun 2015 21:30:25 +0300 Subject: [PATCH 01/14] small fix --- SE_API/CampusRoutes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SE_API/CampusRoutes.py b/SE_API/CampusRoutes.py index 11af4b3..7e83635 100644 --- a/SE_API/CampusRoutes.py +++ b/SE_API/CampusRoutes.py @@ -66,7 +66,7 @@ def create_campus(token): #check if name already exists try: query = Campus.all() - query.filter("title = ", payload['title']) + query.filter("title =", payload['title']) for c in query.run(limit=1): return forbidden("Campus with same name already exists") except Exception as e: From fa12024197a08ff6b319baf43d87d6227d194508 Mon Sep 17 00:00:00 2001 From: aranzaiger Date: Sun, 21 Jun 2015 22:18:48 +0300 Subject: [PATCH 02/14] Added messages functions --- SE_API/CourseRoutes.py | 247 ++++++++++++++++++++++++++++++++++++++++- models/Message.py | 23 ++++ 2 files changed, 267 insertions(+), 3 deletions(-) create mode 100644 models/Message.py diff --git a/SE_API/CourseRoutes.py b/SE_API/CourseRoutes.py index 51a54a4..93c2db6 100644 --- a/SE_API/CourseRoutes.py +++ b/SE_API/CourseRoutes.py @@ -7,6 +7,8 @@ from GithubAPI.GithubAPI import GitHubAPI_Keys from google.appengine.ext import db import requests import datetime +from operator import itemgetter + from flask import Flask, request, render_template, redirect, abort, Response @@ -16,6 +18,8 @@ from flask.ext.autodoc import Autodoc # DB Models from models.Course import Course +from models.Campus import Campus +from models.Message import Message #Validation Utils Libs from SE_API.Validation_Utils import * @@ -27,6 +31,10 @@ course_routes = Blueprint("course_routes", __name__) auto = Autodoc() + +#---------------------------------------------------------- +# POST +#---------------------------------------------------------- @course_routes.route('/api/courses/create/', methods=['POST']) @auto.doc() def create_course(token): @@ -92,8 +100,6 @@ def create_course(token): print e return bad_request() - - db.put(course) db.save return Response(response=course.to_JSON(), @@ -102,6 +108,63 @@ def create_course(token): + +@course_routes.route('/api/courses/createMessage/', methods=['POST']) +@auto.doc() +def createMessage(token): + """ + This call will create a new Message in the DB +
+ Route Parameters
+ - seToken: 'seToken' +
+
+ Payload
+ - JSON Object, Example:
+ {
+ 'courseName': 'Advance Math',
+ 'message': 'The lecture today is canceled'
+ }
+
+
+ Response +
+ 201 - Created +
+ 400 - Bad Request +
+ 403 - Invalid token or not a lecturer + """ + if not request.data: + return bad_request("no data") + if not is_lecturer(token): #todo: change to lecturer id + return forbidden("Invalid token or not a lecturer!") + + user = get_user_by_token(token) + + #try to parse payload + try: + payload = json.loads(request.data) + except Exception as e: + return bad_request("here") + + try: + msg = Message(courseName=payload['courseName'], message=payload['message'], msgDate=datetime.datetime.now()) + except Exception as e: + print e + return bad_request("there") + + db.save(msg) + db.save + return created() + + + +#---------------------------------------------------------- +# GET +#---------------------------------------------------------- + + @course_routes.route('/api/courses/getCourseByCampusName/', methods=["GET"]) @auto.doc() def getCourseByCampusName(name): @@ -132,7 +195,7 @@ def getCourseByCampusName(name): """ arr = [] query = Course.all() - query.filter("campusName = ", name) + query.filter("campusName=", name) for c in query.run(): arr.append(dict(json.loads(c.to_JSON()))) @@ -146,6 +209,184 @@ def getCourseByCampusName(name): status=200, mimetype="application/json") +@course_routes.route('/api/courses/getMessagesByCourseName/', methods=["GET"]) +@auto.doc() +def getMessagesByCourseName(name): + """ + >This Call will return an array of all courses in a given campus +
+ Route Parameters
+ - name: 'campus name' +
+
+ Payload
+ - NONE +
+
+ Response +
+ 200 - JSON Example:
+ + {
+ 'courseName': 'Advance Math',
+ 'campusName': 'JCE',
+ 'startDate': '2015-14-3'
+ 'endDate': '2015-29-6'
+ 'taskFlag': 'False'
+ } +
+
+ """ + arr = [] + query = Message.all() + query.filter("courseName = ", name) + + for m in query.run(): + msgDic = dict(json.loads(m.to_JSON())) + #add a key 'forSortDate' for sorting dates + msgTime = datetime.datetime(msgDic['date']['year'], msgDic['date']['month'], msgDic['date']['day'], msgDic['date']['hour'], msgDic['date']['minute']) + msgDic['forSortDate'] = msgTime + arr.append(msgDic) + + arr = sorted(arr, key=itemgetter('forSortDate'), reverse=False) + for i in arr: + del i['forSortDate'] + print arr + + if len(arr) != 0: + return Response(response=json.dumps(arr), + status=200, + mimetype="application/json") + else: + return Response(response=[], + status=200, + mimetype="application/json") + +#---------------------------------------------------------- +# PUT +#---------------------------------------------------------- + + + + +#---------------------------------------------------------- +# DELETE +#---------------------------------------------------------- +@course_routes.route('/api/courses/deleteCourse//', methods=['DELETE']) +@auto.doc() +def deleteCourse(token,courseName): + """ + This Call will delete a specific course +
+ Route Parameters
+ - seToken: 'seToken' + - title: 'courseName' +
+
+ Payload
+ - NONE
+
+
+ Response +
+ 202 - Deleted campus +
+ 204 - No Matching Campus Found +
+ ....
+ {
+ ...
+ }req
+ + ]
+ 400 - Bad Request +
+ 403 - Invalid token or not a lecturer!
+ """ + + if not is_lecturer(token): #todo: change to lecturer id + return forbidden("Invalid token or not a lecturer!") + + + user = get_user_by_token(token) + query = Course.all() + query.filter('master_id =',user.key().id()) + + try: + query.filter('courseName =', courseName) + except Exception as e: + print e + return bad_request("invalid course title attribute") + + + for c in query.run(): + db.delete(c) + db.save + return accepted("course deleted") + + + return bad_request("no such course or not owner of course") + + +@course_routes.route('/api/courses/deleteCoursesByCampus//', methods=['DELETE']) +@auto.doc() +def deleteCoursesByCampus(token,campusName): + """ + This Call will delete a specific campus's courses +
+ Route Parameters
+ - seToken: 'seToken' + - title: 'campusName' +
+
+ Payload
+ - NONE
+
+
+ Response +
+ 202 - Deleted campus +
+ 204 - No Matching Campus Found +
+ ....
+ {
+ ...
+ }req
+ + ]
+ 400 - Bad Request +
+ 403 - Invalid token or not a lecturer!
+ """ + + if not is_lecturer(token): #todo: change to lecturer id + return forbidden("Invalid token or not a lecturer!") + + + user = get_user_by_token(token) + campus = get_campus_by_campusName(campusName) + if campus is None: + return bad_request("Not a campus!") + + #check user is owner of campus + if campus.master_user_id != user.key().id(): + return forbidden("lecturer is not owner of campus!") + + query = Course.all() + + try: + query.filter('campusName =', campusName) + except Exception as e: + print e + return bad_request("invalid course title attribute") + + for c in query.run(): + db.delete(c) + db.save + + return no_content() + @course_routes.route('/api/courses/help') def documentation(): diff --git a/models/Message.py b/models/Message.py new file mode 100644 index 0000000..fa1a456 --- /dev/null +++ b/models/Message.py @@ -0,0 +1,23 @@ +import json + +__author__ = 'Aran' +from google.appengine.ext import db + +class Message(db.Model): + courseName = db.StringProperty(required=True) + message = db.StringProperty(required=True) + msgDate = db.DateTimeProperty(required=True) + + def to_JSON(self): + data = { + 'courseName' : self.courseName, + 'message' : self.message, + 'date' : { + 'year': self.msgDate.year, + 'month': self.msgDate.month, + 'day': self.msgDate.day, + 'hour': self.msgDate.hour, + 'minute': self.msgDate.minute + } + } + return json.dumps(data) From 5678fa7a9b07e176c50503f88e746b1b1a68b7d9 Mon Sep 17 00:00:00 2001 From: aranzaiger Date: Sun, 21 Jun 2015 22:19:24 +0300 Subject: [PATCH 03/14] Added Task module and functions --- SE_API/API.py | 6 +- SE_API/TaskRoutes.py | 238 +++++++++++++++++++++++++++++++++++++++++++ models/Task.py | 18 ++-- 3 files changed, 252 insertions(+), 10 deletions(-) create mode 100644 SE_API/TaskRoutes.py diff --git a/SE_API/API.py b/SE_API/API.py index 972c39e..136e6b0 100644 --- a/SE_API/API.py +++ b/SE_API/API.py @@ -29,6 +29,7 @@ from SE_API.UserRoutes import user_routes from SE_API.CampusRoutes import campus_routes from SE_API.CourseRoutes import course_routes from SE_API.ProjectRoutes import project_routes +from SE_API.TaskRoutes import task_routes @@ -49,13 +50,10 @@ app.register_blueprint(user_routes) app.register_blueprint(campus_routes) app.register_blueprint(course_routes) app.register_blueprint(project_routes) +app.register_blueprint(task_routes) auto = Autodoc(app) -@app.errorhandler(404) -def page_not_found(e): - return app.send_static_file('views/404/index.html') - @app.route('/') def wellcomePage(): return app.send_static_file('index.html') diff --git a/SE_API/TaskRoutes.py b/SE_API/TaskRoutes.py new file mode 100644 index 0000000..de1ebff --- /dev/null +++ b/SE_API/TaskRoutes.py @@ -0,0 +1,238 @@ +__author__ = 'Aran' + +from flask import Blueprint +import json +from GithubAPI.GithubAPI import GitHubAPI_Keys + +from google.appengine.ext import db +import requests +import datetime +from operator import itemgetter + +from flask import Flask, request, render_template, redirect, abort, Response + +from flask.ext.github import GitHub +from flask.ext.cors import CORS, cross_origin +from flask.ext.autodoc import Autodoc + +# DB Models +from models.Task import Task +from models.Course import Course + +#Validation Utils Libs +from SE_API.Validation_Utils import * +from SE_API.Respones_Utils import * + + + + +task_routes = Blueprint("task_routes", __name__) +auto = Autodoc() + +@task_routes.route('/api/tasks/create/', methods=['POST']) +@auto.doc() +def create_task(token): + """ + This call will create a new Task in the DB +
+ Route Parameters
+ - seToken: 'seToken' +
+
+ Payload
+ - JSON Object, Example:
+ {
+ 'title' : self.title,
+ 'courseName' : self.course,
+ 'description' : self.description,
+ 'dueDate' : self.dueDate,
+ 'isClose' : self.membersId,
+ 'isDone' : self.isDone,
+ 'taskGrade' : self.taskGrade
+ }
+
+
+ Response +
+ 201 - Created +
+ 400 - Bad Request +
+ 403 - Invalid token or not a lecturer + """ + if not request.data: + return bad_request() + payload = json.loads(request.data) + if not is_lecturer(token): #todo: change to lecturer id + return forbidden("Invalid token or not a lecturer!") + + user = get_user_by_token(token) + #TODO: add seconds and minutes + #check the user(lecturer) is owner of the course + # try: + # arr = [] + # query = Course.all() + # query.filter('courseName =',payload['courseName']) + # for t in query.run(): + # arr.append(dict(json.loads(t.to_JSON()))) + # if len(arr) == 0: + # return bad_request("No such course") + # except Exception as e: + # print e + # return bad_request("Missing courseName") + + + #todo: check legality + #create Task object + try: + #parse dueDate + try: + date = datetime.date(payload['dueDate']['year'],payload['dueDate']['month'],payload['dueDate']['day']) + except Exception: + return bad_request("invalid dueDate format") + #TODO: add time. now, its only date + + task = Task(title=payload['title'], courseName=payload['courseName'], description=payload['description'], dueDate=date) + + #parse isClose + try: + task.isClose = payload['isClose'] + except Exception: + pass + + #parse isDone + try: + task.isDone = payload['isDone'] + except Exception: + pass + + #parse taskGrade + try: + task.taskGrade = payload['taskGrade'] + except Exception: + pass + + except Exception as e: + print e + return bad_request() + + db.put(task) + db.save + return created() + + + +@task_routes.route('/api/tasks/getClosestTask/', methods=["GET"]) +@auto.doc() +def getClosestTask(courseName): + """ + >This Call will return an array of all projects in a given course +
+ Route Parameters
+ - name: 'course name' +
+
+ Payload
+ - NONE +
+
+ Response +
+ 200 - JSON Example:
+ + {
+ 'projectName': 'Advance Math',
+ 'courseName': 'JCE',
+ 'grade': 98,
+ 'logo_url': 'http://location.domain.com/image.jpg',
+ 'gitRepository': 'http://location.git.com/somthing',
+ 'membersId': ['bob', 'dylan', 'quentin', 'terentino']
+ } +
+
+ """ + #get all tasks for a specific course + arr = [] + query = Task.all() + query.filter("courseName =", courseName) + index = -1 + count = -1 + closestDate = datetime.date(3000,1,1) + for t in query.run(): + count+=1 + if t.dueDate < closestDate: + closestDate = t.dueDate + index = count + arr.append(dict(json.loads(t.to_JSON()))) + + print arr + if len(arr) != 0: + return Response(response=json.dumps(arr[index]), + status=200, + mimetype="application/json") + else: + return no_content("no Tasks") + + + + +@task_routes.route('/api/tasks/getAllTasks/', methods=["GET"]) +@auto.doc() +def getAllTasks(courseName): + """ + >This Call will return an array of all projects in a given course +
+ Route Parameters
+ - name: 'course name' +
+
+ Payload
+ - NONE +
+
+ Response +
+ 200 - JSON Example:
+ + {
+ 'projectName': 'Advance Math',
+ 'courseName': 'JCE',
+ 'grade': 98,
+ 'logo_url': 'http://location.domain.com/image.jpg',
+ 'gitRepository': 'http://location.git.com/somthing',
+ 'membersId': ['bob', 'dylan', 'quentin', 'terentino']
+ } +
+
+ """ + + arr = [] + query = Task.all() + query.filter("courseName = ", courseName) + + for t in query.run(): + taskDic =dict(json.loads(t.to_JSON())) + #add a key 'forSortDate' for sorting dates + taskTime = datetime.datetime(taskDic['dueDate']['year'], taskDic['dueDate']['month'], taskDic['dueDate']['day']) + taskDic['forSortDate'] = taskTime + arr.append(taskDic) + + #sort array by date, and remove added key + arr = sorted(arr, key=itemgetter('forSortDate'), reverse=False) + for i in arr: + del i['forSortDate'] + + if len(arr) != 0: + return Response(response=json.dumps(arr), + status=200, + mimetype="application/json") + else: + return Response(response=[], + status=200, + mimetype="application/json") + + + +@task_routes.route('/api/tasks/help') +def documentation(): + return auto.html() \ No newline at end of file diff --git a/models/Task.py b/models/Task.py index 659e8b7..e51ac40 100644 --- a/models/Task.py +++ b/models/Task.py @@ -1,26 +1,32 @@ import json - +import time __author__ = 'Aran' from google.appengine.ext import db + class Task(db.Model): title = db.StringProperty(required=True) courseName = db.StringProperty(required=True) description = db.StringProperty(required=True,default=" ") dueDate = db.DateProperty(required=True) - isProject = db.BooleanProperty(required=True) + #isProject = db.BooleanProperty(required=False) isClose = db.BooleanProperty(required=True, default=False) isDone = db.BooleanProperty(required=True, default=False) taskGrade = db.IntegerProperty(required=True, default=0) def to_JSON(self): data = {'title' : self.title, - 'courseName' : self.course, + 'courseName' : self.courseName, 'description' : self.description, - 'dueDate' : self.dueDate, - 'isProject' : self.isProject, - 'isClose' : self.membersId, + 'dueDate' : { + 'year': self.dueDate.year, + 'month': self.dueDate.month, + 'day': self.dueDate.day + }, + #'isProject' : self.isProject, + 'isClose' : self.isClose, 'isDone' : self.isDone, 'taskGrade' : self.taskGrade, } return json.dumps(data) + From 7bb9bb9bfbe0e9de8571970866d11294a0d3aa90 Mon Sep 17 00:00:00 2001 From: aranzaiger Date: Sun, 21 Jun 2015 22:19:49 +0300 Subject: [PATCH 04/14] Added get_campus_by_campusName function --- SE_API/Validation_Utils.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/SE_API/Validation_Utils.py b/SE_API/Validation_Utils.py index 90df681..56da380 100644 --- a/SE_API/Validation_Utils.py +++ b/SE_API/Validation_Utils.py @@ -13,6 +13,14 @@ def get_user_by_token(token): return u return None +def get_campus_by_campusName(campusName): + query = Campus.all() + query.filter("title = ", campusName) + + for u in query.run(limit = 1): + return u + return None + def get_campus_by_suffix(suffix): query = Campus.all() query.filter("email_ending = ", suffix) From 3f272dc304864e7155938fce2d0a4817e5f1fbe0 Mon Sep 17 00:00:00 2001 From: aranzaiger Date: Sun, 21 Jun 2015 22:22:13 +0300 Subject: [PATCH 05/14] garbage commit --- SE_API/CampusRoutes.py | 63 +++++- SE_API/ProjectRoutes.py | 8 +- SE_API/UserRoutes.py | 5 +- models/User.py | 2 +- templates/css/theme.css | 199 ++++++++++++++---- templates/js/app.js | 4 + templates/js/controllers/homeController.js | 68 +++++- templates/js/controllers/mainController.js | 146 +++++++------ .../js/controllers/registerController.js | 75 ++++--- .../js/controllers/settingsController.js | 78 +++++++ templates/js/services/apiService.js | 15 +- templates/js/services/dataService.js | 21 ++ templates/views/home.html | 50 ++++- templates/views/index.html | 42 ++-- templates/views/register.html | 6 +- templates/views/settings.html | 114 ++++++++++ 16 files changed, 712 insertions(+), 184 deletions(-) create mode 100644 templates/js/controllers/settingsController.js create mode 100644 templates/js/services/dataService.js create mode 100644 templates/views/settings.html diff --git a/SE_API/CampusRoutes.py b/SE_API/CampusRoutes.py index 7e83635..67dd8b2 100644 --- a/SE_API/CampusRoutes.py +++ b/SE_API/CampusRoutes.py @@ -79,7 +79,6 @@ def create_campus(token): except Exception: return bad_request() - send_create_campus_request(user.email, user.name, campus.title) notify_se_hub_campus_request(campus, campus.title) return ok() @@ -87,7 +86,6 @@ def create_campus(token): - @campus_routes.route('/api/campuses/getAll/', methods=['GET']) @auto.doc() def get_campuses(token): @@ -125,7 +123,11 @@ def get_campuses(token): query = Campus.all() for c in query.run(): arr.append(dict(json.loads(c.to_JSON()))) + print "ARR:" print arr + for c in arr: + print"c:" + print c if len(arr) != 0: return Response(response=json.dumps(arr), status=200, @@ -138,6 +140,63 @@ def get_campuses(token): return forbidden("Invalid Token") +@campus_routes.route('/api/campuses/deleteCampus//', methods=['DELETE']) +@auto.doc() +def deleteCampus(token,campusName): + """ + This Call will delete a specific campus +
+ Route Parameters
+ - seToken: 'seToken' + - title: 'campusName' +
+
+ Payload
+ - NONE
+
+
+ Response +
+ 202 - Deleted campus +
+ 204 - No Matching Campus Found +
+ ....
+ {
+ ...
+ }req
+ + ]
+ 400 - Bad Request +
+ 403 - Invalid token or not a lecturer!
+ """ + + if not is_lecturer(token): #todo: change to lecturer id + return forbidden("Invalid token or not a lecturer!") + + + user = get_user_by_token(token) + query = Campus.all() + query.filter('master_user_id =',user.key().id()) + + try: + query.filter('title =', campusName) + except Exception as e: + print e + return bad_request("invalid campus title attribute") + + + for c in query.run(): + db.delete(c) + db.save + return accepted("campus deleted") + + + return bad_request("no such campus found") + + + @campus_routes.route('/api/campuses/help') def documentation(): diff --git a/SE_API/ProjectRoutes.py b/SE_API/ProjectRoutes.py index 18d2fb1..57afe8d 100644 --- a/SE_API/ProjectRoutes.py +++ b/SE_API/ProjectRoutes.py @@ -41,7 +41,7 @@ def create_project(token): {
'projectName': 'Advance Math',
'courseName': 'JCE',
- 'logo_url': 'http://location.domain.com/image.jpg'
+ 'logo_url': 'http://location.domain.com/image.jpg',
'gitRepository': 'http://location.git.com/somthing'
}

@@ -57,10 +57,12 @@ def create_project(token): if not request.data: return bad_request() payload = json.loads(request.data) - if not is_lecturer(token): #todo: change to lecturer id - return forbidden("Invalid token or not a lecturer!") + #if not is_lecturer(token): #todo: change to lecturer id + # return forbidden("Invalid token or not a lecturer!") user = get_user_by_token(token) + if user is None: + return bad_request("Wrong user Token") #todo: check legality diff --git a/SE_API/UserRoutes.py b/SE_API/UserRoutes.py index 0bc26d1..d66fdea 100644 --- a/SE_API/UserRoutes.py +++ b/SE_API/UserRoutes.py @@ -25,7 +25,7 @@ from SE_API.Respones_Utils import * user_routes = Blueprint("user_routes", __name__) auto = Autodoc() - +@user_routes.route('/api/users/getUserByToken/', defaults={'token': None}) @user_routes.route('/api/users/getUserByToken/', methods=["GET"]) @auto.doc() def getUserByToken(token): @@ -59,6 +59,9 @@ def getUserByToken(token):
403 - No User Found """ + if token is None: + return no_content("Token Is Empty, No User Found") + query = User.all() query.filter("seToken =", token) diff --git a/models/User.py b/models/User.py index e1edb87..348266c 100644 --- a/models/User.py +++ b/models/User.py @@ -12,7 +12,7 @@ class User(db.Model): seToken = db.StringProperty(required=True) avatar_url = db.StringProperty(required=True) isFirstLogin = db.BooleanProperty(default=True) - campusName = db.StringProperty(default="") + campusName = db.StringProperty(required=True, default=" ") campuses_id_list = db.StringListProperty(default=[]) classes_id_list = db.StringListProperty(default=[]) diff --git a/templates/css/theme.css b/templates/css/theme.css index 8835d90..00e4f28 100644 --- a/templates/css/theme.css +++ b/templates/css/theme.css @@ -2,10 +2,10 @@ body{ font-family: "Alef Hebrew", - “Helvetica Neue”, - Helvetica, - Arial, - sans-serif; + “Helvetica Neue”, + Helvetica, + Arial, + sans-serif; } .menuBtn { @@ -114,34 +114,36 @@ body.noscroll .campusAvatar img { /* - margin-top: 1em; - margin-right: 1em; - position: center; - */ + margin-top: 1em; + margin-right: 1em; + position: center; + */ - border-radius: 40px; - position:center; - width: 80px; - height: 80px; - margin: 6px; - -webkit-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); - -moz-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); - box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); - } + border-radius: 40px; + position:center; + width: 80px; + height: 80px; + margin: 6px; + -webkit-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); + -moz-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); + box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); +} - .spacer{ - margin-right: auto; - margin-left: auto; - } +.spacer{ + margin-right: auto; + margin-left: auto; +} - .port_spacer{ - margin-top: auto; - margin-bottom: auto; - } +.port_spacer +{ + margin-top: auto; + margin-bottom: auto; +} - .mail_suffix{ - margin-top: auto; - } +.mail_suffix +{ + margin-top: auto; +} .createCampus @@ -149,13 +151,41 @@ body.noscroll position:relative; } - -/*div.img campusAvatar +.listdemoBasicUsage md-divider { - border: 1px solid #0000ff; - padding-right: 10px; - float:right; - }*/ + margin-top: 10px; + margin-bottom: 10px; +} + +.md-avatar img +{ + /*TODO*/ +} + +.feedContent +{ + padding-left: 6%; + font-size: 15px; + display:table; +} + +.md-no-sticky +{ + background-color: blue; +} + +.roundUserAvatar +{ + width: 6%; + height: auto; + border-radius: 150px; + -webkit-border-radius: 150px; + -moz-border-radius: 150px; + /*background: url(http://i61.tinypic.com/v86f7.png) no-repeat;*/ + box-shadow: 0 0 8px rgba(0, 0, 0, .8); + -webkit-box-shadow: 0 0 8px rgba(0, 0, 0, .8); + -moz-box-shadow: 0 0 8px rgba(0, 0, 0, .8); +} /*.dropDown /* TODO * { @@ -166,10 +196,47 @@ body.noscroll border-radius: 1px black solid; }*/ - .gray-font{ + .gray-font + { color: #7f7f7f; font-size: 300%; text-shadow:#e0e0e0 1px 1px 0; + opacity: 0; + -webkit-animation-duration: 8s; + animation-duration: 8s; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; + overflow: hidden; + height: 100%; + } + + @-webkit-keyframes fadeOutUp { + 0% { + opacity: 1; + -webkit-transform: translateY(0); + } + 100% { + opacity: 0; + -webkit-transform: translateY(-200px); + /*-webkit-transform: scale(0,0); */ + height: 0px; + } + } + @keyframes fadeOutUp { + 0% { + opacity: 1; + transform: translateY(0); + } + 100% { + opacity: 0; + transform: translateY(-200px); + /*transform: scale(0,0); */ + height: 0px; + } + } + .fadeOutUp { + -webkit-animation-name: fadeOutUp; + animation-name: fadeOutUp; } .user-pane-menu{ @@ -213,6 +280,7 @@ body.noscroll .se-menu li:hover{ background-color: #E2E2E2; font-weight: bold; + cursor: pointer; } .se-menu li .selected{ background-color: #E2E2E2; @@ -237,4 +305,63 @@ body.noscroll .se-menu ul a{ text-decoration: none !important; color: #7f7f7f; - } \ No newline at end of file + } + + /*Settings Style*/ + + .settingList .settingListItem:hover{ + background-color: #E2E2E2; + font-weight: bold; + } + + .settingList .settingListItemRoot{ + list-style: none; + padding: 0; + padding-left: 0; + } + + .settingList .settingListItem{ + width: 100%; + padding: 15px 0px auto 15px; + } + + + /*End Settings*/ + + + /*md Effects*/ + + .md-avatar{ + width: 40px; + height: 40px; + margin-top: 8px; + margin-bottom: 8px; + margin-right: 16px; + border-radius: 50%; + box-sizing: content-box; + } + + +/* md-list-item .md-no-style.md-button, md-list-item.md-no-proxy.md-button { + font-size: inherit; + height: inherit; + text-align: left; + text-transform: none; + width: 100%; + white-space: normal; +} + +md-list-item, md-list-item .md-list-item-inner { + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-justify-content: flex-start; + -ms-flex-pack: start; + justify-content: flex-start; + -webkit-align-items: center; + -ms-flex-align: center; + align-items: center; + min-height: 48px; + }*/ + +/*End Effects for MD*/ diff --git a/templates/js/app.js b/templates/js/app.js index 76bba8f..86cbcc1 100644 --- a/templates/js/app.js +++ b/templates/js/app.js @@ -37,6 +37,10 @@ app.config(['$routeProvider', '$locationProvider', .when('/home', { templateUrl: 'templates/views/home.html', controller: 'homeController' + }) + .when('/Settings', { + templateUrl: 'templates/views/settings.html', + controller: 'settingsController' }); } diff --git a/templates/js/controllers/homeController.js b/templates/js/controllers/homeController.js index 46395cb..009a4f5 100644 --- a/templates/js/controllers/homeController.js +++ b/templates/js/controllers/homeController.js @@ -1,9 +1,71 @@ -/** - * Created by sagi on 6/16/15. - */ angular.module('SeHub') .controller('homeController', ['$scope', '$cookies', '$cookieStore', '$window', '$location', '$mdToast', '$mdDialog', 'apiService', '$rootScope', function ($scope, $cookies, $cookieStore, $window, $location, $mdToast, $mdDialog, apiService ,$rootScope) { + var imagePath = $scope.user.avatar_url; + $scope.phones = [ + { type: 'Home', number: '(972) 865-82861' }, + { type: 'Cell', number: '(972) 5251-32309' }, + ]; + + $scope.messages = [ + { + face : imagePath, + what: 'I need to go to luna-park', + who: 'Matan Bar Yosef', + when: '3:08PM', + notes: " Lets do something" + }, + { + face : imagePath, + what: 'Lets Lets Lets', + who: 'Matan Bar Yosef', + when: '4:33PM', + notes: " Lets go drink something" + }, + { + face : imagePath, + what: 'Let me tell you a secret', + who: 'Sagi Dayan', + when: '4:15PM', + notes: " I am S'ein" + }, + { + face : imagePath, + what: 'Listen to this!', + who: 'Aran Zaiger', + when: '6:15PM', + notes: " I am gaylord ultima!!" + }, + { + face : imagePath, + what: 'Hi?', + who: 'Etye Meyer', + when: '7:45AM', + notes: " I am mega gaylord ultima" + } + ]; + + $scope.tasks = [ + { + ExNum: '1', + dueDate: '23/06/15', + notes: " Build A Game: Scrabble" + }, + { + ExNum: '3', + dueDate: '30/06/15', + notes: " Static Array" + }, + { + ExNum: '4', + dueDate: '07/07/15', + notes: " Dynamic Array" + }, + ]; + + + // animation + $scope.isEnterd = top.setIsEnterd; }]); \ No newline at end of file diff --git a/templates/js/controllers/mainController.js b/templates/js/controllers/mainController.js index c0ba8ce..1f175ab 100644 --- a/templates/js/controllers/mainController.js +++ b/templates/js/controllers/mainController.js @@ -1,76 +1,90 @@ angular.module('SeHub') - .controller('mainController', ['$scope', '$rootScope', 'apiService', '$cookies', '$location', function($scope, $rootScope, apiService, $cookies, $location) { + .controller('mainController', ['$scope', '$rootScope', 'dataService','apiService', '$cookies', '$cookieStore', '$location', '$window', - var token = $cookies['com.sehub.www']; + function($scope, $rootScope, dataService, apiService, $cookies, $cookieStore, $location, $window) { + top.setIsEnterd = true; + var token = $cookies['com.sehub.www']; - $scope.loadingData = true; - $scope.isInRegisterMode = false; + $scope.loadingData = true; + $scope.isInRegisterMode = false; - apiService.getUserByToken(token).success(function(data) { - if (data.message == 'No User Found') { - console.error("No User Found!"); - } - - $scope.user = data; - if ($scope.user.isFirstLogin) { - $scope.menuObj = {}; - $scope.isInRegisterMode = true; + apiService.getUserByToken(token).success(function(data) { + if (data.message == 'No User Found') { + console.error("No User Found!"); + } $scope.loadingData = false; - $location.path('/register') - } else { - $location.path('/home') - } - - }) - - apiService.getUserByToken(token).success(function(data) // Get user token - { $scope.user = data; - $scope.loadingData = false; + dataService.initService($scope); //Start Data Sync Service (For User) + console.log(data); + if ($scope.user.isFirstLogin) { + $scope.menuObj = {}; + $scope.isInRegisterMode = true; + $scope.loadingData = false; + $location.path('/register') + } else { + $location.path('/home') + } - apiService.getAllCampuses($scope.user.seToken).success(function(data) // Get all the campuses - { - $scope.campuses = data; - }).error(function() { - - }); }); - $scope.menuItems = [{ - "title": "Home", - "icon": "fa fa-home", - "style": "selected", - "route": "/home" - }, { - "title": "My Campuses", - "icon": "fa fa-university", - "style": "selected", - "route": "/campuses" - }, { - "title": "My Classes", - "icon": "fa fa-graduation-cap", - "style": "selected", - "route": "/campuses" - }, { - "title": "My Projects", - "icon": "fa fa-cube", - "style": "selected", - "route": "/campuses" - }, { - "title": "Tasks", - "icon": "fa fa-clipboard", - "style": "selected", - "route": "/campuses" - }, { - "title": "Settings", - "icon": "fa fa-cogs", - "style": "selected", - "route": "/campuses" - }, { - "title": "Log Out", - "icon": "fa fa-power-off", - "style": "selected", - "route": "/campuses" - }]; + - }]); \ No newline at end of file + $scope.menuItems = [{ + "title": "Dash Board", + "icon": "fa fa-tachometer", + "style": "selected", + "route": "/home" + }, { + "title": "My Campuses", + "icon": "fa fa-university", + "style": "", + "route": "/campuses" + }, { + "title": "My Classes", + "icon": "fa fa-graduation-cap", + "style": "", + "route": "/campuses" + }, { + "title": "My Projects", + "icon": "fa fa-cube", + "style": "", + "route": "/campuses" + }, { + "title": "Tasks", + "icon": "fa fa-clipboard", + "style": "", + "route": "/campuses" + }, { + "title": "Settings", + "icon": "fa fa-cogs", + "style": "", + "route": "/Settings" + }, { + "title": "Log Out", + "icon": "fa fa-power-off", + "style": "", + "route": "/logout" + }]; + + $scope.menuClicked = function(item) { + var route = "" + if (item.title == "Log Out") { + console.info('Logging Out!'); + $cookieStore.remove('com.sehub.www'); + $window.location.href = 'http://se-hub.appspot.com'; // Reference to 'welcome' page + } + for (var i = $scope.menuItems.length - 1; i >= 0; i--) { + if ($scope.menuItems[i].title === item.title) { + $scope.menuItems[i].style = "selected"; + route = $scope.menuItems[i].route; + } else { + $scope.menuItems[i].style = ""; + } + }; + top.setIsEnterd = false; + $location.path(route); + } + + + } + ]); \ No newline at end of file diff --git a/templates/js/controllers/registerController.js b/templates/js/controllers/registerController.js index 346f731..071096c 100644 --- a/templates/js/controllers/registerController.js +++ b/templates/js/controllers/registerController.js @@ -6,11 +6,11 @@ angular.module('SeHub') $scope.createCampusClicked = false; $scope.isEmpty = true; // if the academic email line is empty $scope.jsonCreateCampus = - { - "title": "Create Campus", - "email": "email_ending", - "avatar": "self.avatar.url" - } + { + "title": "Create Campus", + "email": "email_ending", + "avatar": "self.avatar.url" + } $rootScope.seToken = $cookies['com.sehub.www']; var token = $rootScope.seToken; @@ -56,9 +56,28 @@ angular.module('SeHub') $scope.submitClicked = function(ev) { + var emailValid = false; + var jsonUpdateUser = + { + "lecturerStat": "$scope.user.isLecturer", + "campName": "$scope.campusName" + } + if($scope.user.AcMail != null) { var fullMail = $scope.user.AcMail + $scope.campusObj.email_ending; // Holds the full academic email of the user + + apiService.updateUser($scope.user.seToken, jsonUpdateUser).success(function(data) + { + + }).error(function() + { + // TODO Error + console.log("Error occured on updateUser"); + }); + + console.log("Mail: " + fullMail); + apiService.sendValidationMail($scope.user.seToken, fullMail).success(function(data) { console.log("DONE - 200"); @@ -72,36 +91,38 @@ angular.module('SeHub') $mdDialog.show($mdDialog.alert().title('Error - E-mail Verification').content('An error has occured in your e-mail address.') .ariaLabel('Email verification error alert dialog').ok('Got it!').targetEvent(ev)); }); + } + else // TODO Fix when success to show mdDialog until 'Got it' clicked + { + $mdDialog.show($mdDialog.alert().title('Error - E-mail Verification').content('An error has occured in your e-mail address.') + .ariaLabel('Email verification error alert dialog').ok('Got it!').targetEvent(ev)); }; }; - $scope.createCampus = function(ev) { $scope.createCampusClicked = true; if(!$scope.isLecturer) // "!isLecturer" Means => I Am Lecturer; if i am a lecturer (when pressing -> getting last data value before pressing) { - if($scope.user.campusSuffixMail != null) + if($scope.user.campusMail != null) { - validateEmail($scope.user.campusSuffixMail); + validateEmail($scope.user.campusMail); // Verify the email according to "xxx@name.suffix" } } } - validateEmail = function(email) // TODO ADD IT + validateEmail = function(email) { var result = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i; - - console.log("Email: " + email); - - if (!result.test(email)) + if (!result.test(email)) // TODO Fix when success to show mdDialog until 'Got it' clicked { console.log(email + ", Error in email, should alert"); - alert('Please provide a valid e-mail address'); + // alert('Please provide a valid e-mail address'); + $mdDialog.show($mdDialog.alert().title('Error - E-mail Verification').content('An error has occured in your e-mail address.') + .ariaLabel('Email verification error alert dialog').ok('Got it!').targetEvent(email)); } - - if(result.test(email)) + if(result.test(email)) // TODO Fix when success to show mdDialog until 'Got it' clicked { console.log("Im good"); apiService.sendValidationMail($scope.user.seToken, email).success(function(data) @@ -119,26 +140,4 @@ angular.module('SeHub') }); } } - - // TODO FOR LATER - toast - // TODO FOR LATER - - // $scope.getPopWindowPosition = function() - // { - // return Object.keys($scope.toastPosition).filter(function(pos) - // { - // return $scope.toastPosition[pos]; - // }).join(' '); - // }; - - // $scope.toastPosition = - // { - // bottom: false, - // top: true, - // left: false, - // right: true - // }; - - // TODO FOR LATER - // TODO FOR LATER }]); diff --git a/templates/js/controllers/settingsController.js b/templates/js/controllers/settingsController.js new file mode 100644 index 0000000..81a4a98 --- /dev/null +++ b/templates/js/controllers/settingsController.js @@ -0,0 +1,78 @@ +angular.module('SeHub') + .controller('settingsController', ['$scope', '$rootScope', 'dataService', 'apiService', '$cookies', '$location', + function($scope, $rootScope, dataService, apiService, $cookies, $location) { + + var token = $cookies['com.sehub.www']; + + $scope.loadingData = true; + $scope.isInRegisterMode = false; + + $scope.title = "Settings" + + apiService.getUserByToken(token).success(function(data) { + if (data.message == 'No User Found') { + console.error("No User Found!"); + } + $scope.loadingData = false; + $scope.user = data; + console.log(data); + if ($scope.user.isFirstLogin) { + $scope.menuObj = {}; + $scope.isInRegisterMode = true; + $scope.loadingData = false; + $location.path('/register') + } + + }); + + $scope.isEditMode = false; + $scope.profileMode = "Edit Profile"; + $scope.profileModeIcon = "fa fa-pencil"; + + $scope.changeProfileMode = function() { + $scope.isEditMode = !$scope.isEditMode; + if ($scope.isEditMode) { + $scope.profileMode = "Save Profile"; + $scope.profileModeIcon = "fa fa-floppy-o"; + } else { + dataService.userBrodcast($scope.user); + $scope.profileMode = "Edit Profile"; + $scope.profileModeIcon = "fa fa-pencil"; + } + } + + /** + * DEBUG DATA + */ + $scope.courses = [{ + "courseName": "Advance Math", + "campusName": "JCE", + "startDate": { + "year": 2015, + "month": 4, + "day": 3 + }, + "endDate": { + "year": 2016, + "month": 5, + "day": 14 + }, + "taskFlag": false, + "campus_avatar": "https://yt3.ggpht.com/--ZkWxybWGOM/AAAAAAAAAAI/AAAAAAAAAAA/_nAICC_kzzI/s88-c-k-no/photo.jpg" + }]; + + $scope.campuses = [{ + 'title': 'JCE', + 'email_ending': '@post.jce.ac.il', + 'master_user_id': 123453433341, + 'avatar_url': 'https://yt3.ggpht.com/--ZkWxybWGOM/AAAAAAAAAAI/AAAAAAAAAAA/_nAICC_kzzI/s88-c-k-no/photo.jpg' + }, { + 'title': 'Stanford', + 'email_ending': '@post.jce.ac.il', + 'master_user_id': 123453433341, + 'avatar_url': 'https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcR9M4uQgaJP1zyiCGw-dK31hU8buWqeuOi9vTXBd4Y8hQcFTZqA' + }]; + + + } + ]); \ No newline at end of file diff --git a/templates/js/services/apiService.js b/templates/js/services/apiService.js index 108b309..d07e1f1 100644 --- a/templates/js/services/apiService.js +++ b/templates/js/services/apiService.js @@ -3,15 +3,12 @@ var DEBUG = true; var service = angular.module('seHub.services', []); service.factory('apiService', ['$http', function($http) { - - return { getUserByToken: function(token){ var url = (DEBUG ? "http://localhost:8080" : "http://se-hub.appspot.com") + "/api/users/getUserByToken/" + token; req = { method : "GET", url : url - }; return $http(req); }, @@ -36,9 +33,17 @@ service.factory('apiService', ['$http', function($http) { data: payload }; + return $http(req); + }, + updateUser: function(token, payLoad){ + var url = (DEBUG ? "http://localhost:8080" : "http://se-hub.appspot.com") + "/api/users/updateUser/" + token; + + req = { + method: "POST", + url: url, + data: payLoad + }; return $http(req); } - - }; }]); \ No newline at end of file diff --git a/templates/js/services/dataService.js b/templates/js/services/dataService.js new file mode 100644 index 0000000..af915c7 --- /dev/null +++ b/templates/js/services/dataService.js @@ -0,0 +1,21 @@ +var DEBUG = true; + +angular.module('seHub.services'). + +factory('dataService', ['$http', function($http) { + var scope = null; + + + return { + initService: function(mainScope) { + // this.token = user.seToken; + // this.user = user; + scope = mainScope; + }, + userBrodcast: function(user) { + scope.user = JSON.parse(JSON.stringify(user)); + } + + + }; +}]); \ No newline at end of file diff --git a/templates/views/home.html b/templates/views/home.html index 881bf23..7b2fc30 100644 --- a/templates/views/home.html +++ b/templates/views/home.html @@ -3,7 +3,7 @@ - +
@@ -15,12 +15,54 @@

Welcome To SE-Hub

-

- This Is your Home Page -

+

Software Engineering Course Made Easy

+ v1.0
+ + +
+
+ Messages + +
+ {{item.who}} + + +
+

+ +

{{ item.who }}

+
{{ item.what }}
+
{{ item.notes }}
+
{{ item.when }}
+
+
+
+
+ + +
+
+ + + + Tasks + + +
+ +
Ex: {{ item.ExNum }}
+
Task Title: {{ item.notes }}
+
Due Date: {{ item.dueDate }}
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/templates/views/index.html b/templates/views/index.html index 3abfe58..c683489 100644 --- a/templates/views/index.html +++ b/templates/views/index.html @@ -21,32 +21,28 @@
- -
-
- -
-
-
- {{user.name}} +
+
+
+
-
- {{user.email}} +
+
+ {{user.name}} +
+
+ {{user.email}} +
-
- - -
@@ -85,10 +81,12 @@ + + diff --git a/templates/views/register.html b/templates/views/register.html index f25b61a..7d4d967 100644 --- a/templates/views/register.html +++ b/templates/views/register.html @@ -12,7 +12,7 @@
- +


@@ -29,7 +29,7 @@
- + @@ -65,7 +65,7 @@
- +
diff --git a/templates/views/settings.html b/templates/views/settings.html new file mode 100644 index 0000000..7f07403 --- /dev/null +++ b/templates/views/settings.html @@ -0,0 +1,114 @@ +
+
+ +
+ + +

{{title}}

+
+
+ +
+ +
+
+ +
+
+ + {{profileMode}} + +
+
+
+ +
+
+

{{user.name}}

+
+
+ Email: {{user.email}} +
+
+ I Am a: {{(user.isLecturer) ? "Lecturer" : "Student"}} +
+
+ + +
+
+ + + + +
+
+ + + + +
+
+ + I Am a: {{(user.isLecturer) ? "Lecturer" : "Student"}} + +
+
+ +
+
+ +
+ +

My Classes

+
+
+
+
+ {{ person.name }} +
+
+ {{ course.courseName }} - IN {{course.campusName}} +
+
+
+ + X + +
+ +
+
+
+ +

My Campuses

+ +
+
+
+
+ {{ person.name }} +
+
+ {{ campus.title }} - +
+
+
+ + X + +
+ +
+
+
+
+
+ +
+
+ + + +
+
\ No newline at end of file From 94a9c3dbb0f4d5a18cd1522810f57ada29adfaaf Mon Sep 17 00:00:00 2001 From: Sagi Dayan Date: Sun, 21 Jun 2015 22:27:48 +0300 Subject: [PATCH 06/14] Begining of add new tesk --- templates/js/app.js | 4 ++ .../js/controllers/newTasksController.js | 23 +++++++++ templates/views/index.html | 1 + templates/views/newTask.html | 48 +++++++++++++++++++ templates/views/settings.html | 4 ++ 5 files changed, 80 insertions(+) create mode 100644 templates/js/controllers/newTasksController.js create mode 100644 templates/views/newTask.html diff --git a/templates/js/app.js b/templates/js/app.js index 3a9b514..4511b58 100644 --- a/templates/js/app.js +++ b/templates/js/app.js @@ -45,6 +45,10 @@ app.config(['$routeProvider', '$locationProvider', .when('/tasks', { templateUrl: 'templates/views/tasks.html', controller: 'tasksController' + }) + .when('/tasks/new', { + templateUrl: 'templates/views/newTask.html', + controller: 'newTasksController' }); } ]); diff --git a/templates/js/controllers/newTasksController.js b/templates/js/controllers/newTasksController.js new file mode 100644 index 0000000..3766a2f --- /dev/null +++ b/templates/js/controllers/newTasksController.js @@ -0,0 +1,23 @@ +angular.module('SeHub').controller('newTasksController', ['$scope', + function($scope) { + + + + $scope.componentTypes = [{ + "type": "textbox" + }, { + "type": "textarea" + }, { + "type": "checkbox" + }]; + + + + $scope.task = []; + + $scope.addComponent = function(){ + $scope.task.push($scope.newComp); + $scope.newComp = {}; + } + } +]); \ No newline at end of file diff --git a/templates/views/index.html b/templates/views/index.html index f1fef9e..9599164 100644 --- a/templates/views/index.html +++ b/templates/views/index.html @@ -100,6 +100,7 @@ + \ No newline at end of file diff --git a/templates/views/newTask.html b/templates/views/newTask.html new file mode 100644 index 0000000..434eeca --- /dev/null +++ b/templates/views/newTask.html @@ -0,0 +1,48 @@ +
+
+
+

+ Task Info: +

+
+ +
+ +
+

+ Add A component: +

+
+
+ Select Type: + + {{component.type}} + +
+
+ + + + +
+
+ + Mandatory?: {{ newComp.isMandatory}} + +
+
+
+ Add Component +
+ +
+ +

+ Task Preview: +

+

{{task.toString()}}

+
+ +
\ No newline at end of file diff --git a/templates/views/settings.html b/templates/views/settings.html index 8121fb4..c90b019 100644 --- a/templates/views/settings.html +++ b/templates/views/settings.html @@ -55,6 +55,10 @@
+ +

+ Statistics: +

From 7729b3d884a42f8ae1bf290c1c03752695096afe Mon Sep 17 00:00:00 2001 From: aranzaiger Date: Sun, 21 Jun 2015 22:34:07 +0300 Subject: [PATCH 07/14] taskComponents --- models/TaskComponent.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 models/TaskComponent.py diff --git a/models/TaskComponent.py b/models/TaskComponent.py new file mode 100644 index 0000000..f2130b2 --- /dev/null +++ b/models/TaskComponent.py @@ -0,0 +1,32 @@ +__author__ = 'Aran' + + +import json +from google.appengine.ext import db + + +class TaskComponent(db.Model): + taskId = db.StringProperty(required=True) + courseName = db.StringProperty(required=True) + description = db.StringProperty(required=True,default=" ") + dueDate = db.DateProperty(required=True) + #isProject = db.BooleanProperty(required=False) + isClose = db.BooleanProperty(required=True, default=False) + isDone = db.BooleanProperty(required=True, default=False) + taskGrade = db.IntegerProperty(required=True, default=0) + + def to_JSON(self): + data = {'title' : self.title, + 'courseName' : self.courseName, + 'description' : self.description, + 'dueDate' : { + 'year': self.dueDate.year, + 'month': self.dueDate.month, + 'day': self.dueDate.day + }, + #'isProject' : self.isProject, + 'isClose' : self.isClose, + 'isDone' : self.isDone, + 'taskGrade' : self.taskGrade, + } + return json.dumps(data) From cd0fb3cf4fc76835077f30fc607ee3027a9f7ca6 Mon Sep 17 00:00:00 2001 From: aranzaiger Date: Sun, 21 Jun 2015 23:53:39 +0300 Subject: [PATCH 08/14] Task Rework - chaged parameters added components module and creation in create task added getTaskComponents function --- SE_API/TaskRoutes.py | 262 +++++++++++++++++++++++++++------------- models/Task.py | 10 +- models/TaskComponent.py | 32 ++--- 3 files changed, 190 insertions(+), 114 deletions(-) diff --git a/SE_API/TaskRoutes.py b/SE_API/TaskRoutes.py index de1ebff..4c50468 100644 --- a/SE_API/TaskRoutes.py +++ b/SE_API/TaskRoutes.py @@ -18,6 +18,7 @@ from flask.ext.autodoc import Autodoc # DB Models from models.Task import Task from models.Course import Course +from models.TaskComponent import TaskComponent #Validation Utils Libs from SE_API.Validation_Utils import * @@ -42,14 +43,35 @@ def create_task(token): Payload
- JSON Object, Example:
{
- 'title' : self.title,
- 'courseName' : self.course,
- 'description' : self.description,
- 'dueDate' : self.dueDate,
- 'isClose' : self.membersId,
- 'isDone' : self.isDone,
- 'taskGrade' : self.taskGrade
- }
+ "title":"task1",
+ "courseName":"aran",
+ "description":"pls fddfsdfdsk",
+ "dueDate":{"year":2010,
+ "month":2,
+ "day":4
+ }, + "isPersonal":true,
+ "components":[
+ {
+ "type" : "should be type1",
+ "label" : "should be label1",
+ "isMandatory" : true,
+ "order" : 1
+ },
+ {
+ "type" : "should be type2",
+ "label" : "should be label2",
+ "isMandatory" : true,
+ "order" : 2
+ },
+ {
+ "type" : "should be type3",
+ "label" : "should be label3",
+ "isMandatory" : false,
+ "order" : 3
+ }
+ ]
+}

Response @@ -90,89 +112,37 @@ def create_task(token): date = datetime.date(payload['dueDate']['year'],payload['dueDate']['month'],payload['dueDate']['day']) except Exception: return bad_request("invalid dueDate format") - #TODO: add time. now, its only date task = Task(title=payload['title'], courseName=payload['courseName'], description=payload['description'], dueDate=date) - #parse isClose + # print "id: ",task.key().id() + #parse isPersonal try: - task.isClose = payload['isClose'] + task.isPersonal = payload['isPersonal'] except Exception: pass - - #parse isDone - try: - task.isDone = payload['isDone'] - except Exception: - pass - - #parse taskGrade - try: - task.taskGrade = payload['taskGrade'] - except Exception: - pass - except Exception as e: print e return bad_request() - db.put(task) db.save + + #create components + for c in payload['components']: + try: + component = TaskComponent(taskId=task.key().id(), userId=-1, type=c['type'], label=c['label'], isMandatory=c['isMandatory'], order=c['order']) + except Exception as e: + print e + return bad_request("Bad component") + db.put(component) + db.save + + + return created() -@task_routes.route('/api/tasks/getClosestTask/', methods=["GET"]) -@auto.doc() -def getClosestTask(courseName): - """ - >This Call will return an array of all projects in a given course -
- Route Parameters
- - name: 'course name' -
-
- Payload
- - NONE -
-
- Response -
- 200 - JSON Example:
- - {
- 'projectName': 'Advance Math',
- 'courseName': 'JCE',
- 'grade': 98,
- 'logo_url': 'http://location.domain.com/image.jpg',
- 'gitRepository': 'http://location.git.com/somthing',
- 'membersId': ['bob', 'dylan', 'quentin', 'terentino']
- } -
-
- """ - #get all tasks for a specific course - arr = [] - query = Task.all() - query.filter("courseName =", courseName) - index = -1 - count = -1 - closestDate = datetime.date(3000,1,1) - for t in query.run(): - count+=1 - if t.dueDate < closestDate: - closestDate = t.dueDate - index = count - arr.append(dict(json.loads(t.to_JSON()))) - - print arr - if len(arr) != 0: - return Response(response=json.dumps(arr[index]), - status=200, - mimetype="application/json") - else: - return no_content("no Tasks") - @@ -180,7 +150,7 @@ def getClosestTask(courseName): @auto.doc() def getAllTasks(courseName): """ - >This Call will return an array of all projects in a given course + >This Call will return an array of all Tasks in a course by date
Route Parameters
- name: 'course name' @@ -195,13 +165,17 @@ def getAllTasks(courseName): 200 - JSON Example:
{
- 'projectName': 'Advance Math',
- 'courseName': 'JCE',
- 'grade': 98,
- 'logo_url': 'http://location.domain.com/image.jpg',
- 'gitRepository': 'http://location.git.com/somthing',
- 'membersId': ['bob', 'dylan', 'quentin', 'terentino']
- } + 'title' : 'Task1',
+ 'courseName' : 'advance Math',
+ 'description' : 'prepare by sunday',
+ 'dueDate' : { + 'year' : 2015, + 'month' : 12, + 'day' : 23 + }
+ 'isPersonal' : true,
+ 'task_id' : 589689456894
+ }

""" @@ -227,12 +201,128 @@ def getAllTasks(courseName): status=200, mimetype="application/json") else: - return Response(response=[], + return no_content() + + +@task_routes.route('/api/tasks/getTaskComponents/', methods=["GET"]) +@auto.doc() +def getTaskComponents(taskId): + """ + >This Call will return an array of all components for a given task +
+ Route Parameters
+ - taskId: integer +
+
+ Payload
+ - NONE +
+
+ Response +
+ 200 - JSON Example:
+ + [ + {
+ 'taskId' : 7589454894, + 'userId' : -1, + 'type' : 'kindOfType', + 'label' : 'kindOfLabel', + 'isMandatory' : true, + 'order' : 2 + }
+ {
+ 'taskId' : 7589454894, + 'userId' : yossi, + 'type' : 'otherKindOfType', + 'label' : 'otherKindOfLabel', + 'isMandatory' : false, + 'order' : 4 + }
+ ] +
+
+ """ + + arr = [] + query = TaskComponent.all() + query.filter("taskId = ", taskId) + + for tc in query.run(): + arr.append(dict(json.loads(tc.to_JSON()))) + + #sort array by order, and remove added key + arr = sorted(arr, key=itemgetter('order'), reverse=False) + + if len(arr) != 0: + return Response(response=json.dumps(arr), status=200, mimetype="application/json") + else: + return no_content() @task_routes.route('/api/tasks/help') def documentation(): - return auto.html() \ No newline at end of file + return auto.html() + + + +@task_routes.route('/api/tasks/help') +def documentation(): + return auto.html() + + + + + + +# @task_routes.route('/api/tasks/getClosestTask/', methods=["GET"]) +# @auto.doc() +# def getClosestTask(courseName): +# """ +# >This Call will return an array of all projects in a given course +#
+# Route Parameters
+# - name: 'course name' +#
+#
+# Payload
+# - NONE +#
+#
+# Response +#
+# 200 - JSON Example:
+# +# {
+# 'projectName': 'Advance Math',
+# 'courseName': 'JCE',
+# 'grade': 98,
+# 'logo_url': 'http://location.domain.com/image.jpg',
+# 'gitRepository': 'http://location.git.com/somthing',
+# 'membersId': ['bob', 'dylan', 'quentin', 'terentino']
+# } +#
+#
+# """ +# #get all tasks for a specific course +# arr = [] +# query = Task.all() +# query.filter("courseName =", courseName) +# for t in query.run(): +# count+=1 +# if t.dueDate < closestDate: +# closestDate = t.dueDate +# index = count +# arr.append(dict(json.loads(t.to_JSON()))) +# +# print arr +# if len(arr) != 0: +# return Response(response=json.dumps(arr[index]), +# status=200, +# mimetype="application/json") +# else: +# return no_content("no Tasks") +# diff --git a/models/Task.py b/models/Task.py index e51ac40..292ac0d 100644 --- a/models/Task.py +++ b/models/Task.py @@ -9,10 +9,7 @@ class Task(db.Model): courseName = db.StringProperty(required=True) description = db.StringProperty(required=True,default=" ") dueDate = db.DateProperty(required=True) - #isProject = db.BooleanProperty(required=False) - isClose = db.BooleanProperty(required=True, default=False) - isDone = db.BooleanProperty(required=True, default=False) - taskGrade = db.IntegerProperty(required=True, default=0) + isPersonal = db.BooleanProperty(required=True, default=True) def to_JSON(self): data = {'title' : self.title, @@ -23,10 +20,7 @@ class Task(db.Model): 'month': self.dueDate.month, 'day': self.dueDate.day }, - #'isProject' : self.isProject, - 'isClose' : self.isClose, - 'isDone' : self.isDone, - 'taskGrade' : self.taskGrade, + 'isPersonal' : self.isPersonal, } return json.dumps(data) diff --git a/models/TaskComponent.py b/models/TaskComponent.py index f2130b2..db84efb 100644 --- a/models/TaskComponent.py +++ b/models/TaskComponent.py @@ -6,27 +6,19 @@ from google.appengine.ext import db class TaskComponent(db.Model): - taskId = db.StringProperty(required=True) - courseName = db.StringProperty(required=True) - description = db.StringProperty(required=True,default=" ") - dueDate = db.DateProperty(required=True) - #isProject = db.BooleanProperty(required=False) - isClose = db.BooleanProperty(required=True, default=False) - isDone = db.BooleanProperty(required=True, default=False) - taskGrade = db.IntegerProperty(required=True, default=0) + taskId = db.IntegerProperty(required=True) + userId = db.IntegerProperty(required=True, default = -1) + type = db.StringProperty(required=True,default=" ") + label = db.StringProperty(required=True,default=" ") + isMandatory = db.BooleanProperty(required=True, default=True) + order = db.IntegerProperty(required=True) def to_JSON(self): - data = {'title' : self.title, - 'courseName' : self.courseName, - 'description' : self.description, - 'dueDate' : { - 'year': self.dueDate.year, - 'month': self.dueDate.month, - 'day': self.dueDate.day - }, - #'isProject' : self.isProject, - 'isClose' : self.isClose, - 'isDone' : self.isDone, - 'taskGrade' : self.taskGrade, + data = {'taskId' : self.taskId, + 'userId' : self.userId, + 'type' : self.type, + 'label' : self.label, + 'isMandatory' : self.isMandatory, + 'order' : self.order } return json.dumps(data) From c6c175ca294cfd055d48283d6c1205ff2fcb32bd Mon Sep 17 00:00:00 2001 From: aranzaiger Date: Sun, 21 Jun 2015 23:56:49 +0300 Subject: [PATCH 09/14] #52 bug fix. change in documentation --- SE_API/CampusRoutes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SE_API/CampusRoutes.py b/SE_API/CampusRoutes.py index 67dd8b2..e6a2781 100644 --- a/SE_API/CampusRoutes.py +++ b/SE_API/CampusRoutes.py @@ -48,7 +48,7 @@ def create_campus(token):
Response
- 201 - Created + 200 - OK
403 - Invalid Token/Forbidden """ From 431a36760d65f77dd0ecdd5fe5c0c0ca92a148cd Mon Sep 17 00:00:00 2001 From: aranzaiger Date: Mon, 22 Jun 2015 01:25:35 +0300 Subject: [PATCH 10/14] fix auto.doc bug --- SE_API/TaskRoutes.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/SE_API/TaskRoutes.py b/SE_API/TaskRoutes.py index 4c50468..769e25b 100644 --- a/SE_API/TaskRoutes.py +++ b/SE_API/TaskRoutes.py @@ -269,10 +269,6 @@ def documentation(): -@task_routes.route('/api/tasks/help') -def documentation(): - return auto.html() - From e9e10bd980c9ea194fcf24d991e63cff92528332 Mon Sep 17 00:00:00 2001 From: aranzaiger Date: Mon, 22 Jun 2015 01:26:23 +0300 Subject: [PATCH 11/14] added delete functions + doc to campus, course, project --- SE_API/CampusRoutes.py | 32 +++++++++++----------------- SE_API/CourseRoutes.py | 38 ++++++++++++++++----------------- SE_API/ProjectRoutes.py | 47 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 40 deletions(-) diff --git a/SE_API/CampusRoutes.py b/SE_API/CampusRoutes.py index e6a2781..66a262a 100644 --- a/SE_API/CampusRoutes.py +++ b/SE_API/CampusRoutes.py @@ -140,15 +140,16 @@ def get_campuses(token): return forbidden("Invalid Token") -@campus_routes.route('/api/campuses/deleteCampus//', methods=['DELETE']) + +@campus_routes.route('/api/campuses/deleteCampus//', methods=['DELETE']) @auto.doc() -def deleteCampus(token,campusName): +def deleteCampus(token,campusid): """ This Call will delete a specific campus
Route Parameters
- seToken: 'seToken' - - title: 'campusName' + - campusid: 'campusid'

Payload
@@ -159,42 +160,33 @@ def deleteCampus(token,campusName):
202 - Deleted campus
- 204 - No Matching Campus Found -
....
{
...
}req
]
- 400 - Bad Request + 400 - no such campus
- 403 - Invalid token or not a lecturer!
+ 403 - Invalid token or not a lecturer or lecturer is not owner of campus!
""" if not is_lecturer(token): #todo: change to lecturer id return forbidden("Invalid token or not a lecturer!") - user = get_user_by_token(token) - query = Campus.all() - query.filter('master_user_id =',user.key().id()) + camp = Campus.get_by_id(int(campusid)) - try: - query.filter('title =', campusName) - except Exception as e: - print e - return bad_request("invalid campus title attribute") + if camp is None: + return bad_request("no such campus") - for c in query.run(): - db.delete(c) + if camp.master_user_id == user.key().id(): + db.delete(camp) db.save return accepted("campus deleted") - - return bad_request("no such campus found") - + return forbidden("lecturer is not owner of campus") diff --git a/SE_API/CourseRoutes.py b/SE_API/CourseRoutes.py index 93c2db6..fe27f61 100644 --- a/SE_API/CourseRoutes.py +++ b/SE_API/CourseRoutes.py @@ -272,15 +272,21 @@ def getMessagesByCourseName(name): #---------------------------------------------------------- # DELETE #---------------------------------------------------------- -@course_routes.route('/api/courses/deleteCourse//', methods=['DELETE']) + + + + + + +@course_routes.route('/api/courses/deleteCourse//', methods=['DELETE']) @auto.doc() -def deleteCourse(token,courseName): +def deleteCourse(token,courseid): """ - This Call will delete a specific course + This Call will delete a specific Course
Route Parameters
- seToken: 'seToken' - - title: 'courseName' + - courseid: 'courseid'

Payload
@@ -289,9 +295,7 @@ def deleteCourse(token,courseName):
Response
- 202 - Deleted campus -
- 204 - No Matching Campus Found + 202 - Deleted Course
....
{
@@ -299,33 +303,27 @@ def deleteCourse(token,courseName): }req
]
- 400 - Bad Request + 400 - no such Course
- 403 - Invalid token or not a lecturer!
+ 403 - Invalid token or not a lecturer or lecturer is not owner of Course!
""" if not is_lecturer(token): #todo: change to lecturer id return forbidden("Invalid token or not a lecturer!") - user = get_user_by_token(token) - query = Course.all() - query.filter('master_id =',user.key().id()) + c = Course.get_by_id(int(courseid)) - try: - query.filter('courseName =', courseName) - except Exception as e: - print e - return bad_request("invalid course title attribute") + if c is None: + return bad_request("no such course") - for c in query.run(): + if c.master_id == user.key().id(): db.delete(c) db.save return accepted("course deleted") - - return bad_request("no such course or not owner of course") + return forbidden("lecturer is not owner of course") @course_routes.route('/api/courses/deleteCoursesByCampus//', methods=['DELETE']) diff --git a/SE_API/ProjectRoutes.py b/SE_API/ProjectRoutes.py index 57afe8d..1bd3c23 100644 --- a/SE_API/ProjectRoutes.py +++ b/SE_API/ProjectRoutes.py @@ -130,6 +130,53 @@ def getProjectsByCourseName(name): +@project_routes.route('/api/projects/deleteProject//', methods=['DELETE']) +@auto.doc() +def deleteProject(token,projectid): + """ + This Call will delete a specific Project +
+ Route Parameters
+ - seToken: 'seToken' + - courseid: 'projectid' +
+
+ Payload
+ - NONE
+
+
+ Response +
+ 202 - Deleted Project +
+ ....
+ {
+ ...
+ }req
+ + ]
+ 400 - no such Project +
+ 403 - Invalid token or not the owner of Project!
+ """ + + # if not is_lecturer(token): #todo: change to lecturer id + # return forbidden("Invalid token or not a lecturer!") + + user = get_user_by_token(token) + p = Project.get_by_id(int(projectid)) + + if p is None: + return bad_request("no such Project") + + if p.master_id == user.key().id(): + db.delete(p) + db.save + return accepted("Project deleted") + + return forbidden("user is not owner of Project") + + @project_routes.route('/api/projects/help') def documentation(): From 346d5b4aaae10f81cb45c67330a2f52a2292a762 Mon Sep 17 00:00:00 2001 From: aranzaiger Date: Mon, 22 Jun 2015 01:38:01 +0300 Subject: [PATCH 12/14] added 'id' key in JSON response --- models/Campus.py | 3 ++- models/Course.py | 5 +++-- models/Message.py | 3 ++- models/Project.py | 1 + models/Task.py | 1 + models/TaskComponent.py | 3 ++- 6 files changed, 11 insertions(+), 5 deletions(-) diff --git a/models/Campus.py b/models/Campus.py index f4e9cef..dd910de 100644 --- a/models/Campus.py +++ b/models/Campus.py @@ -14,7 +14,8 @@ class Campus(db.Model): data = {'title': self.title, 'email_ending': self.email_ending, 'master_user_id': self.master_user_id, - 'avatar_url': self.avatar_url + 'avatar_url': self.avatar_url, + 'id' : self.key().id() } return json.dumps(data) diff --git a/models/Course.py b/models/Course.py index fd2dc08..e2a6b7c 100644 --- a/models/Course.py +++ b/models/Course.py @@ -25,6 +25,7 @@ class Course(db.Model): 'year': self.endDate.year, 'month': self.endDate.month, 'day': self.endDate.day, - } - } + }, + 'id' : self.key().id() + } return json.dumps(data) diff --git a/models/Message.py b/models/Message.py index fa1a456..a5dc29f 100644 --- a/models/Message.py +++ b/models/Message.py @@ -18,6 +18,7 @@ class Message(db.Model): 'day': self.msgDate.day, 'hour': self.msgDate.hour, 'minute': self.msgDate.minute - } + }, + 'id' : self.key().id() } return json.dumps(data) diff --git a/models/Project.py b/models/Project.py index 579ecdd..4e6cacb 100644 --- a/models/Project.py +++ b/models/Project.py @@ -20,5 +20,6 @@ class Project(db.Model): 'logo_url' : self.logo_url, 'gitRepository' : self.gitRepository, 'membersId' : self.membersId, + 'id' : self.key().id() } return json.dumps(data) diff --git a/models/Task.py b/models/Task.py index 292ac0d..cdbaae9 100644 --- a/models/Task.py +++ b/models/Task.py @@ -21,6 +21,7 @@ class Task(db.Model): 'day': self.dueDate.day }, 'isPersonal' : self.isPersonal, + 'id' : self.key().id() } return json.dumps(data) diff --git a/models/TaskComponent.py b/models/TaskComponent.py index db84efb..161cfcc 100644 --- a/models/TaskComponent.py +++ b/models/TaskComponent.py @@ -19,6 +19,7 @@ class TaskComponent(db.Model): 'type' : self.type, 'label' : self.label, 'isMandatory' : self.isMandatory, - 'order' : self.order + 'order' : self.order, + 'id' : self.key().id() } return json.dumps(data) From f1d73aab644b7946654377af90ac782640dbddaf Mon Sep 17 00:00:00 2001 From: aranzaiger Date: Mon, 22 Jun 2015 01:38:14 +0300 Subject: [PATCH 13/14] some doc --- SE_API/CampusRoutes.py | 3 ++- SE_API/CourseRoutes.py | 6 +++++- SE_API/ProjectRoutes.py | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/SE_API/CampusRoutes.py b/SE_API/CampusRoutes.py index 66a262a..ebfa72a 100644 --- a/SE_API/CampusRoutes.py +++ b/SE_API/CampusRoutes.py @@ -108,7 +108,8 @@ def get_campuses(token): 'title': 'JCE',
'email_ending': '@post.jce.ac.il',
'master_user_id': 123453433341, (User that created the campus)
- 'avatar_url': 'http://some.domain.com/imagefile.jpg'
+ 'avatar_url': 'http://some.domain.com/imagefile.jpg',
+ 'id' : 1234567890
},
....
{
diff --git a/SE_API/CourseRoutes.py b/SE_API/CourseRoutes.py index fe27f61..b7af470 100644 --- a/SE_API/CourseRoutes.py +++ b/SE_API/CourseRoutes.py @@ -189,6 +189,8 @@ def getCourseByCampusName(name): 'startDate': '2015-14-3'
'endDate': '2015-29-6'
'taskFlag': 'False'
+ 'id' : 1234567890
+ }
@@ -232,7 +234,9 @@ def getMessagesByCourseName(name): 'campusName': 'JCE',
'startDate': '2015-14-3'
'endDate': '2015-29-6'
- 'taskFlag': 'False'
+ 'taskFlag': false,
+ 'id' : 1234567890
+ }
diff --git a/SE_API/ProjectRoutes.py b/SE_API/ProjectRoutes.py index 1bd3c23..175a3a7 100644 --- a/SE_API/ProjectRoutes.py +++ b/SE_API/ProjectRoutes.py @@ -106,7 +106,8 @@ def getProjectsByCourseName(name): 'grade': 98,
'logo_url': 'http://location.domain.com/image.jpg',
'gitRepository': 'http://location.git.com/somthing',
- 'membersId': ['bob', 'dylan', 'quentin', 'terentino']
+ 'membersId': ['bob', 'dylan', 'quentin', 'terentino'],
+ 'id' : 1234567890
}
From 44aaa5c08f24674e2aaad4454e93256d33b279cd Mon Sep 17 00:00:00 2001 From: Sagi Dayan Date: Mon, 22 Jun 2015 13:04:21 +0300 Subject: [PATCH 14/14] Fixing A BAAAD Commit --- templates/css/theme.css | 162 ++++++++++++------ templates/js/app.js | 11 +- templates/js/controllers/homeController.js | 102 +++++------ templates/js/controllers/mainController.js | 2 +- .../js/controllers/registerController.js | 4 +- .../js/controllers/settingsController.js | 17 +- templates/views/home.html | 130 +++++++++----- templates/views/index.html | 13 ++ templates/views/settings.html | 6 + 9 files changed, 282 insertions(+), 165 deletions(-) diff --git a/templates/css/theme.css b/templates/css/theme.css index 00e4f28..45b271e 100644 --- a/templates/css/theme.css +++ b/templates/css/theme.css @@ -33,9 +33,9 @@ md-list .md-button { https://github.com/google/material-design-icons */ -p { +/*p { margin-left: 2em; -} +}*/ .menuBtn { background: transparent url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMjRweCIgaGVpZ2h0PSIyNHB4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDI0IDI0IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPGcgaWQ9IkhlYWRlciI+CiAgICA8Zz4KICAgICAgICA8cmVjdCB4PSItNjE4IiB5PSItMjIzMiIgZmlsbD0ibm9uZSIgd2lkdGg9IjE0MDAiIGhlaWdodD0iMzYwMCIvPgogICAgPC9nPgo8L2c+CjxnIGlkPSJMYWJlbCI+CjwvZz4KPGcgaWQ9Ikljb24iPgogICAgPGc+CiAgICAgICAgPHJlY3QgZmlsbD0ibm9uZSIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0Ii8+CiAgICAgICAgPHBhdGggZD0iTTMsMThoMTh2LTJIM1YxOHogTTMsMTNoMTh2LTJIM1YxM3ogTTMsNnYyaDE4VjZIM3oiIHN0eWxlPSJmaWxsOiNmM2YzZjM7Ii8+CiAgICA8L2c+CjwvZz4KPGcgaWQ9IkdyaWQiIGRpc3BsYXk9Im5vbmUiPgogICAgPGcgZGlzcGxheT0iaW5saW5lIj4KICAgIDwvZz4KPC9nPgo8L3N2Zz4=) no-repeat center center; @@ -76,28 +76,21 @@ body.noscroll margin-top: 1em; margin-right: 1em; position: center; - -webkit-border-radius: 30%; -moz-border-radius: 30%; border-radius: 30%; - - } -/*.avatar { - background: rgba(0, 0, 0, 0.2); - }*/ - - .avatar img { - border-radius: 40px; - position:center; - width: 80px; - height: 80px; - margin: 6px; /*centers the image in the parent element */ - -webkit-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); - -moz-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); - box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); - } +.avatar img { + border-radius: 40px; + position:center; + width: 80px; + height: 80px; + margin: 6px; + -webkit-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); + -moz-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); + box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); +} /* Added BY devMatan */ @@ -111,14 +104,8 @@ body.noscroll }*/ - .campusAvatar img - { -/* - margin-top: 1em; - margin-right: 1em; - position: center; - */ - +.campusAvatar img +{ border-radius: 40px; position:center; width: 80px; @@ -157,9 +144,24 @@ body.noscroll margin-bottom: 10px; } -.md-avatar img +.feed { - /*TODO*/ + overflow-y: scroll; + height: 350px; + /*width: 100%;*/ +} + +/*.feedMessages +{ + overflow: scroll; + height: 300px; + width: 100%; +} +.feedTasks +{ + overflow: scroll; + height: 300px; + width: 100%; } .feedContent @@ -167,7 +169,7 @@ body.noscroll padding-left: 6%; font-size: 15px; display:table; -} +}*/ .md-no-sticky { @@ -181,7 +183,6 @@ body.noscroll border-radius: 150px; -webkit-border-radius: 150px; -moz-border-radius: 150px; - /*background: url(http://i61.tinypic.com/v86f7.png) no-repeat;*/ box-shadow: 0 0 8px rgba(0, 0, 0, .8); -webkit-box-shadow: 0 0 8px rgba(0, 0, 0, .8); -moz-box-shadow: 0 0 8px rgba(0, 0, 0, .8); @@ -256,7 +257,6 @@ body.noscroll -moz-border-radius: 100px; border-radius: 50px; width: 30%; - /*top: -40px;*/ position: relative; z-index: 50; } @@ -282,8 +282,17 @@ body.noscroll font-weight: bold; cursor: pointer; } - .se-menu li .selected{ + + .se-menu li:active{ + background-color: #B2B2B2; + text-shadow:#e0e0e0 1px 1px 0; + font-weight: bold; + } + + .se-menu .selected{ background-color: #E2E2E2; + text-shadow:#e0e0e0 1px 1px 0; + font-weight: bold; } .user-box{ @@ -293,7 +302,6 @@ body.noscroll .user-box img{ width: 100%; border: 4px #7f7f7f solid; - -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; @@ -342,26 +350,70 @@ body.noscroll } -/* md-list-item .md-no-style.md-button, md-list-item.md-no-proxy.md-button { - font-size: inherit; - height: inherit; - text-align: left; - text-transform: none; - width: 100%; - white-space: normal; +/* Colors*/ +.gray{ + background:#f5f5f5; +} +.aliceblue { + background: aliceblue; +} + .green { + background: #b9f6ca; +} + .yellow { + background: #ffff8d; +} + .blue { + background: #84ffff; +} + .purple { + background: #b388ff; +} + .red { + background: #ff8a80; +} +/* End Colors */ + +.whiteframedemoBasicUsage md-whiteframe { + background: #fff; + margin: 20px; + padding: 20px; } -md-list-item, md-list-item .md-list-item-inner { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-justify-content: flex-start; - -ms-flex-pack: start; - justify-content: flex-start; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - min-height: 48px; - }*/ - -/*End Effects for MD*/ +.tasksContent +{ + padding-left: 4px; + padding-right: 4px; + margin: 5px; + background-color: aliceblue; + overflow: scroll; + height:250; + width:500; +} +.messagesContent +{ + padding-left: 4px; + padding-right: 4px; + margin: 5px; + background-color: #f5f5f5; + overflow: scroll; + height:250; + width:500; +} +p.tasksFeed +{ + padding-left: 4px; + margin: 5px; + width:500; + height: auto; + background-color: aliceblue; + +} +p.messagesFeed +{ + padding-left: 4px; + margin: 5px; + width:500; + height: auto; + background-color: #f5f5f5; +} \ No newline at end of file diff --git a/templates/js/app.js b/templates/js/app.js index 86cbcc1..4511b58 100644 --- a/templates/js/app.js +++ b/templates/js/app.js @@ -2,7 +2,7 @@ var DEBUG = true; var welcome = angular.module('welcome', ['ngMaterial', 'seHub.services', 'ngRoute' , 'ngCookies']); -var app = angular.module('SeHub', ['ngMaterial', 'ngRoute', 'seHub.services', 'ngCookies']); +var app = angular.module('SeHub', ['ngMaterial', 'ngRoute', 'seHub.services', 'ngCookies', 'chart.js']); welcome.config(function($mdThemingProvider) { @@ -41,8 +41,15 @@ app.config(['$routeProvider', '$locationProvider', .when('/Settings', { templateUrl: 'templates/views/settings.html', controller: 'settingsController' + }) + .when('/tasks', { + templateUrl: 'templates/views/tasks.html', + controller: 'tasksController' + }) + .when('/tasks/new', { + templateUrl: 'templates/views/newTask.html', + controller: 'newTasksController' }); - } ]); diff --git a/templates/js/controllers/homeController.js b/templates/js/controllers/homeController.js index 009a4f5..2e1b19d 100644 --- a/templates/js/controllers/homeController.js +++ b/templates/js/controllers/homeController.js @@ -1,71 +1,51 @@ angular.module('SeHub') .controller('homeController', ['$scope', '$cookies', '$cookieStore', '$window', '$location', '$mdToast', '$mdDialog', 'apiService', '$rootScope', function ($scope, $cookies, $cookieStore, $window, $location, $mdToast, $mdDialog, apiService ,$rootScope) { - var imagePath = $scope.user.avatar_url; - $scope.phones = [ - { type: 'Home', number: '(972) 865-82861' }, - { type: 'Cell', number: '(972) 5251-32309' }, - ]; + $scope.isStudent = false; + $scope.addMsg = false; + $scope.msgToPost = ""; + $scope.oldText = ""; - $scope.messages = [ - { - face : imagePath, - what: 'I need to go to luna-park', - who: 'Matan Bar Yosef', - when: '3:08PM', - notes: " Lets do something" - }, - { - face : imagePath, - what: 'Lets Lets Lets', - who: 'Matan Bar Yosef', - when: '4:33PM', - notes: " Lets go drink something" - }, - { - face : imagePath, - what: 'Let me tell you a secret', - who: 'Sagi Dayan', - when: '4:15PM', - notes: " I am S'ein" - }, - { - face : imagePath, - what: 'Listen to this!', - who: 'Aran Zaiger', - when: '6:15PM', - notes: " I am gaylord ultima!!" - }, - { - face : imagePath, - what: 'Hi?', - who: 'Etye Meyer', - when: '7:45AM', - notes: " I am mega gaylord ultima" - } - ]; + var imagePath = $scope.user.avatar_url; + $scope.phones = [ + { type: 'Home', number: '(972) 865-82861' }, + { type: 'Cell', number: '(972) 5251-32309' }, + ]; - $scope.tasks = [ - { - ExNum: '1', - dueDate: '23/06/15', - notes: " Build A Game: Scrabble" - }, - { - ExNum: '3', - dueDate: '30/06/15', - notes: " Static Array" - }, - { - ExNum: '4', - dueDate: '07/07/15', - notes: " Dynamic Array" - }, - ]; + if($scope.user.isLecturer) + { + $scope.isStudent = false; + console.log("Lecturer Mode!"); + } + else + { + $scope.isStudent = true; + console.log("Student Mode!"); + } + $scope.addMessageClicked = function() + { + $scope.addMsg = true; // Reveal the "POST" Button + } + $scope.postMessageClicked = function(msg) // Posting the message itself + { + if(msg != null) + { + $scope.prevText = "- " + msg; + implementText = document.getElementById("msg").value; + $scope.prevText += "

"; + document.getElementById("bindText").innerHTML += $scope.prevText; + } + document.getElementById("msg").value = ''; + $scope.prevText = ''; + } + $scope.clearAllClicked = function() // Clear Screen from text + { + document.getElementById("bindText").innerHTML = ""; + } - // animation - $scope.isEnterd = top.setIsEnterd; + // animation + $scope.isEnterd = top.setIsEnterd; }]); \ No newline at end of file diff --git a/templates/js/controllers/mainController.js b/templates/js/controllers/mainController.js index 1f175ab..f2eb0b4 100644 --- a/templates/js/controllers/mainController.js +++ b/templates/js/controllers/mainController.js @@ -53,7 +53,7 @@ angular.module('SeHub') "title": "Tasks", "icon": "fa fa-clipboard", "style": "", - "route": "/campuses" + "route": "/tasks" }, { "title": "Settings", "icon": "fa fa-cogs", diff --git a/templates/js/controllers/registerController.js b/templates/js/controllers/registerController.js index 071096c..6ce4d08 100644 --- a/templates/js/controllers/registerController.js +++ b/templates/js/controllers/registerController.js @@ -83,7 +83,7 @@ angular.module('SeHub') console.log("DONE - 200"); $mdDialog.show($mdDialog.alert().title('E-mail Verification').content('A verification e-mail has been sent to your email address.') .ariaLabel('Email verification alert dialog').ok('Got it!').targetEvent(ev)); // Pop-up alert for e-mail verification - // TODO ADD delete cookies and redirect only after pressed 'Got it' + // TODO ADD- delete cookies and redirect only after pressed 'Got it' $cookieStore.remove("com.sehub.www"); // Removing the cookies $window.location.href = 'http://se-hub.appspot.com'; // Reference to 'welcome' page }).error(function() @@ -117,8 +117,6 @@ angular.module('SeHub') var result = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i; if (!result.test(email)) // TODO Fix when success to show mdDialog until 'Got it' clicked { - console.log(email + ", Error in email, should alert"); - // alert('Please provide a valid e-mail address'); $mdDialog.show($mdDialog.alert().title('Error - E-mail Verification').content('An error has occured in your e-mail address.') .ariaLabel('Email verification error alert dialog').ok('Got it!').targetEvent(email)); } diff --git a/templates/js/controllers/settingsController.js b/templates/js/controllers/settingsController.js index 81a4a98..35c9531 100644 --- a/templates/js/controllers/settingsController.js +++ b/templates/js/controllers/settingsController.js @@ -35,7 +35,13 @@ angular.module('SeHub') $scope.profileMode = "Save Profile"; $scope.profileModeIcon = "fa fa-floppy-o"; } else { - dataService.userBrodcast($scope.user); + apiService.updateUser(token, $scope.user).success(function(data) { + console.info('User Saved'); + dataService.userBrodcast($scope.user); + + }).error(function(e) { + console.error('Fail To Save User'); + }); $scope.profileMode = "Edit Profile"; $scope.profileModeIcon = "fa fa-pencil"; } @@ -74,5 +80,14 @@ angular.module('SeHub') }]; + $scope.labels = ['Commits', 'Issues Assigned', 'Messages', 'Open Tasks']; + $scope.series = ['Project A', 'Project B']; + + $scope.data = [ + [54, 3, 15, 3], + [28, 48, 40, 3] + ]; + + } ]); \ No newline at end of file diff --git a/templates/views/home.html b/templates/views/home.html index 7b2fc30..cd2fc49 100644 --- a/templates/views/home.html +++ b/templates/views/home.html @@ -22,47 +22,93 @@
- - -
-
- Messages - -
- {{item.who}} - - -
-

- -

{{ item.who }}

-
{{ item.what }}
-
{{ item.notes }}
-
{{ item.when }}
-
-
-
+
+ +
+
+ +

Messages

+
+
+
+ +

Tasks

+
+
- -
-
-
- - - - Tasks - - -
- -
Ex: {{ item.ExNum }}
-
Task Title: {{ item.notes }}
-
Due Date: {{ item.dueDate }}
-
-
-
-
-
-
- +
+
+ +

+
+
+
+ +

+ For Task 3 Press: Task #3 +

+ For Task 4 Press: Task #4 +

+ For Task 5 Press: Task #5 +

+ For Task 6 Press: Task #6 +

+ For Task 7 Press: Task #7 +

+ For Task 8 Press: Task #8 +

+
+
+
+
+ Add Message +
+
+
+ Post + Clear All +
+
+ + + + +
+ +
+
+ +
+
+ +

Messages

+
+
+
+ +

Tasks

+
+
+
+
+
+ +

+
+
+
+ +

+ For Task 3 Press: Task #3 +

+ For Task 4 Press: Task #4 +

+ For Task 5 Press: Task #5 +

+ +
+
+
+
+
\ No newline at end of file diff --git a/templates/views/index.html b/templates/views/index.html index c683489..9599164 100644 --- a/templates/views/index.html +++ b/templates/views/index.html @@ -6,6 +6,10 @@ + + + + @@ -79,6 +83,14 @@ + + + + + + + + @@ -88,6 +100,7 @@ + \ No newline at end of file diff --git a/templates/views/settings.html b/templates/views/settings.html index 7f07403..c90b019 100644 --- a/templates/views/settings.html +++ b/templates/views/settings.html @@ -55,6 +55,12 @@
+ +

+ Statistics: +

+