commit ccc2a3b4a2474d821a087a8ec14c534301683cd5 parent 275b415b70215c43a808eaa6743b98ea9c153d1a Author: Brennen T. Mazur <brennen@madis.cool> Date: Wed, 22 Feb 2023 11:20:32 -0700 Merge branch 'auth' of git.brennen.work:stc into auth Diffstat:
19 files changed, 307 insertions(+), 73 deletions(-)
diff --git a/README b/README @@ -1,14 +1,13 @@ stc is a simple time card implementation for personal use or small to medium size businesses. -The goal of this project is to create an extensible tool for time and other asset management. +The goal of this project is to create an extensible tool for time and asset management. -Current plans are to use mongoDB as the backend to a simplistic dashboard for accessing management interfaces, overseeing and managing lower role's clocked in status, and requesting reports for not only current/past pay periods sorted by employee, but also by project code +Current plans are to use mongoDB as the backend to a simplistic dashboard for accessing management interfaces, overseeing and managing role's clocked in status, and requesting reports for not only current/past pay periods sorted by employee, but also by project code Project has potential to be renamed to scms (simple content management system) based on potential end-goals of multiple clients. -An option would be to create the base structure for the cms (as human resource management [ex. time tracking]) and allow patches to include additional functionality like equipment tracking etc. Allows no-nonsence approach to anti-bloat management software. +An option would be to create the base structure for the cms (as human resource management [ex. time tracking]) and allow patches to include additional functionality like equipment tracking etc. -db file will likely be /scms.db or whatever the appname resolves to templates holds each "component" either a standalone file, or a directory for a index.html(full page route) and widget.html(dashboard interactable view) -For organization specifics... it might be usefull to create diff files for specific additions etc? Possibly too costly to maintain over master version changes. +For organization specifics... it might be usefull to create diff files for specific additions etc? Possibly too costly to maintain over master version changes. This needs to be determined and refined. diff --git a/README.planfor b/README.planfor @@ -1,18 +0,0 @@ -#Plan for getting appropriate modules - -on successfull auth -> base.html utilizes successfulAuth() -> ?validUSR?[user-name(str), accessable modules[array], server-connection(bool)] - accessable modules and server-connection are used for navbar creation and to check if local-storage is necessary for temp operations - user-name used for welcome "prompt" - -each route checkAuth() -> directs to login if false, else - calls routeblock - -Routeblocks getRelevantData(not necessarily one fn, likely individual) -> relevantData[clocked-in,project,purdium,lunch] - used to populate ?MACRO? for displayed widget/page - should checkAuth() # We should be checking constantly for auth to verify and doubleverify before any exchange of data or operations -##### -I've overcomplicated this, the responses can be parsed as the raw JSON data returned from the db... Everything will request relatively small amounts of data until the reports which will likely need to make multiple calls? then return a txt/pdftex file - -##### - This implies you have db.users.$user.permission[val1,val2,...] - /admin.html should have 'preset' permissions per role and allow toggling individual level diff --git a/app/forms.py b/app/forms.py @@ -1,6 +1,6 @@ from flask_wtf import FlaskForm -from wtforms import StringField, SubmitField, PasswordField, BooleanField, SelectField -from wtforms.validators import DataRequired, optional +from wtforms import StringField, SubmitField, PasswordField, BooleanField, SelectField, DateField, TelField, EmailField, FloatField +from wtforms.validators import DataRequired, optional, length # Login class currently assumes mongodb collection(Users) with structure # { @@ -12,10 +12,74 @@ class LoginForm(FlaskForm): password = PasswordField('Password', validators=[DataRequired()]) login = SubmitField('Login') +class NewUserForm(FlaskForm): + fname = StringField('First Name', validators=[DataRequired()]) + mname = StringField('Middle Initial', validators=[DataRequired(),length(max=1)]) + lname = StringField('Last Name', validators=[DataRequired()]) + birthday = DateField('Birthday',validators=[DataRequired()])# Ought to change this to some validation for age range accepted + role = SelectField('Role',validators=[DataRequired()]) + address = StringField('Address',validators=[DataRequired()])# Require some sort of validator for check... + branch = SelectField('Branch',validators=[DataRequired(),length(max=200)]) + phonenumber = TelField('Phonenumber',validators=[DataRequired(),length(max=12)])# Require some sort of validator for check... + email = EmailField('Email',validators=[DataRequired()])# Require some sort of validator for check... + payPeriod = StringField('Pay Period Override',validators=[optional()])# May not need this at all? + payValue = FloatField('Pay Value Override',validators=[optional()])# Require some sort of validator for check... + setActive = BooleanField('Active',default="checked")# Require some sort of validator for check... + createNewUser = SubmitField('Create New User') + class PunchclockWidget(FlaskForm): - projectsSel = SelectField('Project', validators=[DataRequired()]) - #clockin = currenttime - lunchBox = BooleanField('Lunch') - perdiumBox = BooleanField('Perdium') - # IFF user.role is_in(trusted_role[]) then allow lunch minute definition - clockin = SubmitField('Clock In') + projectsSel = SelectField('Project', validators=[DataRequired()]) + #clockin = currenttime + lunchBox = BooleanField('Lunch') + perdiumBox = BooleanField('Perdium') + # IFF user.role is_in(trusted_role[]) then allow lunch minute definition + clockin = SubmitField('Clock In') + +class NewRoleForm(FlaskForm): + rolename = StringField('Role Name', validators=[DataRequired()]) + +class DashPermissionsForm(FlaskForm):# for each module make Boolean field. Gets passed to fn writing to permissions_collection SET MANUALLY CURRENTLY + punchclock = BooleanField('Punch Clock',default="checked") + activecrew = BooleanField('Active Crew List') + fleet = BooleanField('Fleet') + ###### End Modules ##### + updaterole = SubmitField('Update')#Update to take role name for pass to write fn + +class AdmnPermissionsForm(FlaskForm):# for each module make Boolean field. Gets passed to fn writing to permissions_collection SET MANUALLY CURRENTLY + agreements = BooleanField('Agreements') + reports = BooleanField('Reports') + manageusers = BooleanField('Manage Users') + ###### End Modules ##### + updaterole = SubmitField('Update')#Update to take role name for pass to write fn + +class FleetCheckoutForm(FlaskForm): + vehicle = SelectField('Vehicle', validators=[DataRequired()]) + startmilage = StringField('Starting Milage',validators=[DataRequired()])# Require some sort of validator for check... + horn = BooleanField('Horn') + signals = BooleanField('Signals') + tires = BooleanField('Tires') + mirrors = BooleanField('Mirrors') + enginefluid = BooleanField('Engine Fluids') + steeringfluid = BooleanField('Steering Fluid') + brakefluid = BooleanField('Brake Fluid') + transmissionfluid = BooleanField('Transmission Fluid') + windshield = BooleanField('Windshield') + wipers = BooleanField('Windshield Wipers') + towingequipment = BooleanField('Towing Equipment') + additionalnotes = StringField('Additional Notes',validators=[optional()])# May not need this at all? + checkout = SubmitField('Checkout')#Update to take role name for pass to write fn + +class FleetCheckinForm(FlaskForm): + horn = BooleanField('Horn') + signals = BooleanField('Signals') + tires = BooleanField('Tires') + mirrors = BooleanField('Mirrors') + enginefluid = BooleanField('Engine Fluids') + steeringfluid = BooleanField('Steering Fluid') + brakefluid = BooleanField('Brake Fluid') + transmissionfluid = BooleanField('Transmission Fluid') + windshield = BooleanField('Windshield') + wipers = BooleanField('Windshield Wipers') + towingequipment = BooleanField('Towing Equipment') + additionalnotes = StringField('Additional Notes',validators=[optional()])# May not need this at all? + checkin = SubmitField('Checkin')#Update to take role name for pass to write fn diff --git a/app/models.py b/app/models.py @@ -99,7 +99,7 @@ class User(): class Time: - def clockin(self): + def clockin(self, clockin): clockin = { '_id': int, 'clock_in': Optional[datetime.datetime.utcnow], @@ -110,7 +110,7 @@ class Time: return jsonify(clockin), 200 - def clockout(self): + def clockout(self, clockout): clockout = { '_id': int, 'clock_out': Optional[datetime.datetime.utcnow], @@ -146,7 +146,7 @@ class Time: class Fleet: - def vehicle_repair(self): + def vehicle_repair(self, vehicle_repair): vehicle_repair = { '_id': int, 'date': Optional[datetime.datetime.utcnow], @@ -172,7 +172,7 @@ class Fleet: class Agreement: - def document(self): + def document(self, document): document = { '_id': int, #forign key to user 'start_date': int, @@ -193,7 +193,7 @@ class Agreement: class Projects:#Projects references agreement - def project(self): + def project(self, project): project = { 'project_id': int, 'project_name': str, diff --git a/app/routes.py b/app/routes.py @@ -3,7 +3,7 @@ from app import app from flask_pymongo import PyMongo from flask_login import LoginManager from flask import render_template, url_for, request, flash, redirect -from app.forms import LoginForm, PunchclockWidget +from app.forms import LoginForm, PunchclockWidget, NewUserForm, AdmnPermissionsForm, DashPermissionsForm from flask import request from werkzeug.urls import url_parse from werkzeug.security import generate_password_hash, check_password_hash @@ -17,7 +17,7 @@ mongo = PyMongo(app) login_manager = LoginManager(app) login_manager.login_view = 'login' -# User Routes +# User Routes / Queries @app.route('/user/signup', methods=['GET']) def signup(): return User().signup() @@ -29,7 +29,34 @@ def loginModel(): @app.route('/user/signout') def signout(): return User().signout() -# User Routes +# User Routes / Queries + +# Time Routes / Queries +@app.route('/time/clockin', methods=['GET', 'POST']) +def clockin(): + return Time().clockin() + +@app.route('/time/clockout', methods=['GET', 'POST']) +def clockout(): + return Time().clockout() +# Time Routes / Queries + +# Fleet Routes / Queries +@app.route('/fleet/vehicle_repair', methods=['GET', 'POST', 'PUT']) +def vehicle_repair(): + return Fleet().vehicle_repair() +# Fleet Routes / Queries + +# Agreement Routes / Queries +@app.route('/agreement/document', methods=['GET', 'POST']) +def document(): + return Agreement().document() +# Agreement Routes / Queries + +# Projects Routes / Queries +@app.route('/projects/project', methods=['GET', 'POST', 'PUT']) +# Projects Routes / Queries + # Page Routes @app.route('/') @@ -76,7 +103,7 @@ def load_user(username): return user_obj @app.route("/dashboard") -@login_required +#@login_required def dashboard(): form=PunchclockWidget() currenttime=datetime.datetime.utcnow() @@ -86,12 +113,12 @@ def dashboard(): return render_template('dashboard/layout.html',currenttime=currenttime,projects=available_projects,form=form,ORGNAME=OrganizationName) @app.route("/admin") -@login_required +#@login_required def admin(): return render_template ('admin/layout.html',ORGNAME=OrganizationName) @app.route("/hours")#modify to take userid ex. /hours<userid> for "admin" currently pulls from current_user... simply always pass username to hours(if possible set a default to current_user) -@login_required +#@login_required def hours():#userid goes into call to db to get user[] -> then returns formatted table (punchclock/index.html return render_template ('dashboard/punchclock/index.html',ORGNAME=OrganizationName) @@ -101,9 +128,17 @@ def hours():#userid goes into call to db to get user[] -> then returns formatted # return render_template('dashboard/fleet/index.html',ORGNAME=OrganizationName) @app.route("/admin/roles") -@login_required +#@login_required def roles(): - return render_template('admin/roles/index.html',ORGNAME=OrganizationName) + admnform = AdmnPermissionsForm() + dashform = DashPermissionsForm() + return render_template('admin/roles/updateroles.html',dashform=dashform,admnform=admnform,ORGNAME=OrganizationName) + +@app.route("/admin/newuser") +#@login_required +def newuser(): + form = NewUserForm() + return render_template('admin/users/newuser.html',form=form,ORGNAME=OrganizationName) @app.route("/admin/agreement") @login_required diff --git a/app/static/css/main.css b/app/static/css/main.css @@ -20,7 +20,7 @@ html,body {margin:0;padding:0;background-color:var(--rootbg);} .appview {margin:0;padding:0;} - +/* min-height: 100vh; /**/ a,a.visited,a.hover { text-decoration:none; color:#000; @@ -73,7 +73,6 @@ header { /********** LOGIN PAGE **********/ .login-grid { display: grid; - grid-template-rows: repeat(3, 30vh); grid-template-columns: repeat(3, 1fr); } @@ -81,13 +80,14 @@ header { display: grid; align-items: center; justify-items: center; - grid-row-start: 2; - grid-row-end: 3; + grid-row-start: 1; + grid-row-end: 2; grid-column-start: 2; grid-column-end: 3; - padding-top:4rem; + padding-top:5rem; padding-bottom:4rem; - box-shadow: 0px 0px .1em .1em var(--accent);/* probably shouldn't have box-shadow for clean ui at intermediate page sizes (between laptop and phone off ratio) */ + background-color:var(--maincolor); +/* box-shadow: 0px 0px .1em .1em var(--accent);/* probably shouldn't have box-shadow for clean ui at intermediate page sizes (between laptop and phone off ratio) */ } /********** WIDGETS **********/ .permissions, .reportswidget, .activeusers, .agreements, .fleet, .punchclock { diff --git a/app/templates/admin/layout.html b/app/templates/admin/layout.html @@ -2,14 +2,15 @@ {% block title %}Management{% endblock %} -{% block navigation %}<a href="/dashboard"><div id="dashboard">Dashboard</div></a>{% endblock %} - {% block content %} <section class="admin-grid"> <!--functioncall checking role for admin. while loop return permissioned 'widgets' --> <!-- returned values from admin check is array of permissive ACCESS else return 'missing permissions response' --> - {%- for x in ['reports','agreements','roles'] %} + + +<!-- for x in db.get_collection('permissions_collection').find_one(current_user.role) --> + {%- for x in ['reports','agreements','roles','users'] %} {% include 'admin/'~x~'/widget.html' %} {%- else-%} {{ 'You do not have permission to access this page' }} diff --git a/app/templates/admin/roles/index.html b/app/templates/admin/roles/index.html @@ -2,8 +2,6 @@ {% block title %}Employees/Crew/Roles{% endblock %} -{% block navigation %}<a id="navi" href="/admin"><div id="back"><Back</div></a>{% endblock %} - {% block content %} <table> <tr><th>Name</th><th>Role</th><th>Active Employee</th></tr> <tr> diff --git a/app/templates/admin/roles/updateroles.html b/app/templates/admin/roles/updateroles.html @@ -0,0 +1,51 @@ +{% extends 'base.html' %} + +{% block title %}Current Activeated Users{% endblock %} + +{% block content %} + +<table> + <tr> + <th>User Role</th> + {% for field in dashform %} + <th>{{ field.label }}</th> + {% endfor %} + </tr> + <form action="" method="post" novalidate> + {{ dashform.hidden_tag() }} + {% for error in dashform.errors %} + <span style="color:red;">[{{ error }}]</span> + {% endfor %} + {% for role in ['Crew','Crew Lead','Project Manager','Developer','Accountant'] %} + <tr><td>{{ role }}</td> + {% for field in dashform %} + <td>{{ field }}</td> + {% endfor %} + </tr> + {% endfor %} + </form> +</table> + +<table> + <tr> + <th>User Role</th> + {% for field in admnform %} + <th>{{ field.label }}</th> + {% endfor %} + </tr> + <form action="" method="post" novalidate> + {{ admnform.hidden_tag() }} + {% for error in admnform.errors %} + <span style="color:red;">[{{ error }}]</span> + {% endfor %} + {% for role in ['Crew','Crew Lead','Project Manager','Developer','Accountant'] %} + <tr><td>{{ role }}</td> + {% for field in admnform %} + <td>{{ field }}</td> + {% endfor %} + </tr> + {% endfor %} + </form> +</table> + +{% endblock %} diff --git a/app/templates/admin/roles/widget.html b/app/templates/admin/roles/widget.html @@ -1,6 +1,6 @@ -<section class="permissions"> +<section class="admin-sidebar"><!-- did not change css tag yet... --> <h3>Permissions by</h3> - <input type="submit" value="Role"> + <input type="submit" value="Roles"> <input type="submit" value="Employee"> - <input type="submit" value="Page"><!-- may not be necessary with role above... --> + <!-- <input type="submit" value="Page"> --> </section> diff --git a/app/templates/admin/users/inactiveusers.html b/app/templates/admin/users/inactiveusers.html @@ -0,0 +1,27 @@ +{% extends 'base.html' %} + +{% block title %}Add new Employee{% endblock %} + +{% block navigation %}<a id="navi" href="/admin"><div id="back"><Back</div></a>{% endblock %} + +{% block content %} + <form action="" method="post" novalidate> + {{ form.hidden_tag() }} + {% for error in form.errors %} + <span style="color:red;">[{{ error }}]</span> + {% endfor %} + {{ form.fname.label }}{{ form.fname() }}<br> + {{ form.mname.label }}{{ form.mname(size=1) }}<br> + {{ form.lname.label }}{{ form.lname() }}<br> + {{ form.birthday.label }}{{ form.birthday() }}<br> + {{ form.role.label }}{{ form.role() }}<br> + {{ form.address.label }}{{ form.address() }}<br> + {{ form.branch.label }}{{ form.branch() }}<br> + {{ form.phonenumber.label }}{{ form.phonenumber() }}<br> + {{ form.email.label }}{{ form.email() }}<br> + {{ form.payPeriod.label }}{{ form.payPeriod() }}<br> + {{ form.payValue.label }}{{ form.payValue() }}<br> + {{ form.setActive() }}{{ form.setActive.label }}<br> + {{ form.createNewUser() }} + </form> +{% endblock %} diff --git a/app/templates/admin/users/newuser.html b/app/templates/admin/users/newuser.html @@ -0,0 +1,27 @@ +{% extends 'base.html' %} + +{% block title %}Add new Employee{% endblock %} + +{% block navigation %}<a id="navi" href="/admin"><div id="back"><Back</div></a>{% endblock %} + +{% block content %} + <form action="" method="post" novalidate> + {{ form.hidden_tag() }} + {% for error in form.errors %} + <span style="color:red;">[{{ error }}]</span> + {% endfor %} + {{ form.fname.label }}{{ form.fname() }}<br> + {{ form.mname.label }}{{ form.mname(size=1) }}<br> + {{ form.lname.label }}{{ form.lname() }}<br> + {{ form.birthday.label }}{{ form.birthday() }}<br> + {{ form.role.label }}{{ form.role() }}<br> + {{ form.address.label }}{{ form.address() }}<br> + {{ form.branch.label }}{{ form.branch() }}<br> + {{ form.phonenumber.label }}{{ form.phonenumber() }}<br> + {{ form.email.label }}{{ form.email() }}<br> + {{ form.payPeriod.label }}{{ form.payPeriod() }}<br> + {{ form.payValue.label }}{{ form.payValue() }}<br> + {{ form.setActive() }}{{ form.setActive.label }}<br> + {{ form.createNewUser() }} + </form> +{% endblock %} diff --git a/app/templates/admin/users/widget.html b/app/templates/admin/users/widget.html @@ -0,0 +1,6 @@ +<section class="admin-sidebar"> + <h3>Users</h3> + <input type="submit" value="Active"> <!--sends active tag to route changes available users in dropdown --> + <input type="submit" value="Inactive"> <!-- sends inactive tag to route for available users dropdown --> + <a href="{{ url_for('newuser') }}"><input type="submit" value="New"></a> <!-- separate newuser.html pg? --> +</section> diff --git a/app/templates/base.html b/app/templates/base.html @@ -10,12 +10,34 @@ <link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}"> </head> <body onload="startTime()"> - <header> <!-- logo , if userHasPermission(current_user.role) [admin] | if route is admin [dashboard] else [empty space], if current_user.is_anonymous [login] else [logout] --> +<!-- BEGIN NAVIGATION BAR --> + <header> + <!-- BEGIN logo --> <div id="logo"><a href="{{ url_for('dashboard') }}"><img src="{{ url_for('static', filename='imgs/logo.svg') }}" /></a></div> - {% block navigation %}{% endblock %} <!-- remove from here and template pgs after nav logic above finished --> + <!-- END logo --> + <!-- BEGIN navigation/navi logic --> + {% if current_user.is_authenticated %} + <!-- if userHasPermission(current_user.role) [admin] | if route is admin [dashboard] else [empty space]-->{% if current_user.role == "admin" %}<!-- Need to check for page location --> + <a href="{{ url_for('admin') }}"><div id="navi">Admin</div></a> + {% else %} + <a href="{{ url_for('dashboard') }}"><div id="navi">Dashboard</div></a> + {% endif %} + {% else %} + <div id="navi"></div> + {% endif %} + <!-- END navigation/navi logic --> + <!-- BEGIN login/logout logic --> + {% if current_user.is_anonymous %} + <a href="{{ url_for('login') }}"><div id="logout">Login</div></a> + {% else %} + <a href="{{ url_for('logout') }}"><div id="logout">Logout</div></a> + {% endif %} + <!-- END login/logout logic --> </header> +<!-- END NAVIGATION BAR --> +<!-- BEGIN DOCUMENTATION BUTTON --> <div id="doc"><a href="/docs"><svg fill="var(--accent)" height="2rem" width="2rem" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 29.536 29.536" xml:space="preserve"><g stroke-linecap="round" stroke-linejoin="round"/><path d="M14.768,0C6.611,0,0,6.609,0,14.768c0,8.155,6.611,14.767,14.768,14.767s14.768-6.612,14.768-14.767 C29.535,6.609,22.924,0,14.768,0z M14.768,27.126c-6.828,0-12.361-5.532-12.361-12.359c0-6.828,5.533-12.362,12.361-12.362 c6.826,0,12.359,5.535,12.359,12.362C27.127,21.594,21.594,27.126,14.768,27.126z"/> <path d="M14.385,19.337c-1.338,0-2.289,0.951-2.289,2.34c0,1.336,0.926,2.339,2.289,2.339c1.414,0,2.314-1.003,2.314-2.339 C16.672,20.288,15.771,19.337,14.385,19.337z"/> <path d="M14.742,6.092c-1.824,0-3.34,0.513-4.293,1.053l0.875,2.804c0.668-0.462,1.697-0.772,2.545-0.772 c1.285,0.027,1.879,0.644,1.879,1.543c0,0.85-0.67,1.697-1.494,2.701c-1.156,1.364-1.594,2.701-1.516,4.012l0.025,0.669h3.42 v-0.463c-0.025-1.158,0.387-2.162,1.311-3.215c0.979-1.08,2.211-2.366,2.211-4.321C19.705,7.968,18.139,6.092,14.742,6.092z"/></svg></a></div> - +<!-- END DOCUMENTATION BUTTON --> <section class="appview"> {% block content %} {% endblock %} <!-- functioncall for checking role IF logged in route /dashboard else LOGIN(templates/index.html) --> diff --git a/app/templates/dashboard/layout.html b/app/templates/dashboard/layout.html @@ -2,8 +2,6 @@ {% block title %}Dashboard{% endblock %} -{% block navigation %}<div id="navi"><a href="{{ url_for('admin') }}">Admin</a></div><a href="{{ url_for('logout') }}"><div id="logout">Logout</div></a>{% endblock %} - {% block content %} <section class="base-grid"> <!-- TODO: function call for permissive ACCESS, returns array of strings --> diff --git a/app/templates/dashboard/punchclock/index.html b/app/templates/dashboard/punchclock/index.html @@ -2,8 +2,6 @@ {% block title %}Hours{% endblock %} -{% block navigation %}<a href="/dashboard"><div id="back">< Back</div></a>{% endblock %} - {% block content %} <section class="hours-grid"> <h3>{{ current_user.fname }} {{ current_user.lname }}</h3><!-- IF logged in user has permission allow this username section to be a dropdown for modifying user time sheets. --> diff --git a/app/templates/index.html b/app/templates/index.html @@ -2,8 +2,6 @@ {% block title %} Resource Management System {% endblock %} -{% block navigation %}<div id="nav" href="{{ url_for('logout') }}"></div><div id="logout"></div>{% endblock %} - {% block content %} <section class="singlepage"> <h2>Welcome to YEP!</h2><h6>Call to action! Motto or Mission Statement</h6> diff --git a/app/templates/login.html b/app/templates/login.html @@ -2,9 +2,8 @@ {% block title %}Login{% endblock %} -{% block navigation %}<div id="nav" href="#"></div><div id="logout"></div>{% endblock %} - {% block content %} +<section class="login-grid"> {% with messages = get_flashed_messages() %} {% if messages %} <ul> @@ -14,7 +13,7 @@ </ul> {% endif %} {% endwith %} - <form action="" method="post" novalidate> + <form class="login" action="" method="post" novalidate> {{ form.hidden_tag() }} <p> {{ form.username.label }}<br> @@ -32,6 +31,7 @@ </p> <p>{{ form.login() }}</p> </form> +</section> <!-- old version before structure change --> <!-- <section class="login-grid"> <form class="login"> diff --git a/seeds.py b/seeds.py @@ -152,10 +152,38 @@ projects2 = { # Permissions documents (only needs array list of str for each 'service') roles = { - 'punchclock': ['Crew','Crew Lead', 'Project Manager','Developer'], - 'fleet': ['Crew Lead', 'Project Manager'], - 'admin': ['Project Manager', 'Developer'] + 'crew': { + 'label': 'Crew', + 'dashboard': ['punchclock'], + 'admin': [] + }, + 'asistcrewlead': { + 'label': 'Assistant Lead', + 'dashboard': ['punchclock','fleet'], + 'admin': [] + }, + 'crewlead': { + 'label': 'Crew Lead', + 'dashboard': ['punchclock','fleet','activecrew'], + 'admin': [] + }, + 'developer': { + 'label': 'Web Developer', + 'dashboard': ['punchclock','fleet','activecrew'], + 'admin': ['agreements','reports','users'] + }, + 'projectmanager': { + 'label': 'Project Manager', + 'dashboard': ['punchclock','fleet','activecrew'], + 'admin': ['agreements','reports','users'] + }, + 'accounting': { + 'label': 'Accountant', + 'dashboard': ['punchclock','fleet','activecrew'], + 'admin': ['agreements','reports','users'] + } } + # Insert documents user_collection.insert_many([user1, user2]) time_collection.insert_many([time1, time2])