Refactor schedule / timesheet views for better separation of concerns
This was needed to support a "late clock-ins" view which included both scheduled *and* worked shift data..
This commit is contained in:
parent
bd6d2d2e11
commit
1e4612bcbe
8 changed files with 258 additions and 193 deletions
|
@ -1,5 +1,6 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
<%inherit file="/base.mako" />
|
||||
<%namespace file="/autocomplete.mako" import="autocomplete" />
|
||||
|
||||
<%def name="title()">${page_title}</%def>
|
||||
|
||||
|
@ -132,8 +133,165 @@
|
|||
|
||||
<%def name="context_menu()"></%def>
|
||||
|
||||
<%def name="render_day(day)">
|
||||
% for shift in day['shifts']:
|
||||
<p class="shift">${render_shift(shift)}</p>
|
||||
% endfor
|
||||
<%def name="timesheet_wrapper(with_edit_form=False, change_employee=None)">
|
||||
<div class="timesheet-wrapper">
|
||||
|
||||
${form.begin(id='filter-form')}
|
||||
${form.csrf_token()}
|
||||
|
||||
<table class="timesheet-header">
|
||||
<tbody>
|
||||
<tr>
|
||||
|
||||
<td class="filters" rowspan="2">
|
||||
|
||||
% if employee is not Undefined:
|
||||
<div class="field-wrapper employee">
|
||||
<label>Employee</label>
|
||||
<div class="field">
|
||||
% if request.has_perm('{}.viewall'.format(permission_prefix)):
|
||||
${autocomplete('employee', url('employees.autocomplete'),
|
||||
field_value=employee.uuid if employee else None,
|
||||
field_display=unicode(employee or ''),
|
||||
selected='employee_selected',
|
||||
change_clicked=change_employee)}
|
||||
% else:
|
||||
${form.hidden('employee', value=employee.uuid)}
|
||||
${employee}
|
||||
% endif
|
||||
</div>
|
||||
</div>
|
||||
% endif
|
||||
|
||||
% if store_options is not Undefined:
|
||||
${form.field_div('store', h.select('store', store.uuid if store else None, store_options))}
|
||||
% endif
|
||||
|
||||
% if department_options is not Undefined:
|
||||
${form.field_div('department', h.select('department', department.uuid if department else None, department_options))}
|
||||
% endif
|
||||
|
||||
<div class="field-wrapper week">
|
||||
<label>Week of</label>
|
||||
<div class="field">
|
||||
${week_of}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
${self.edit_tools()}
|
||||
|
||||
</td><!-- filters -->
|
||||
|
||||
<td class="menu">
|
||||
<ul id="context-menu">
|
||||
${self.context_menu()}
|
||||
</ul>
|
||||
</td><!-- menu -->
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="tools">
|
||||
<div class="grid-tools">
|
||||
<div class="week-picker">
|
||||
<button type="button" class="nav" data-date="${prev_sunday.strftime('%m/%d/%Y')}">« Previous</button>
|
||||
<button type="button" class="nav" data-date="${next_sunday.strftime('%m/%d/%Y')}">Next »</button>
|
||||
<label>Jump to week:</label>
|
||||
${form.text('date', value=sunday.strftime('%m/%d/%Y'))}
|
||||
</div>
|
||||
</div><!-- grid-tools -->
|
||||
</td><!-- tools -->
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table><!-- timesheet-header -->
|
||||
|
||||
${form.end()}
|
||||
|
||||
% if with_edit_form:
|
||||
${self.edit_form()}
|
||||
% endif
|
||||
|
||||
${self.timesheet()}
|
||||
|
||||
% if with_edit_form:
|
||||
${h.end_form()}
|
||||
% endif
|
||||
|
||||
</div><!-- timesheet-wrapper -->
|
||||
</%def>
|
||||
|
||||
<%def name="timesheet(render_day=None)">
|
||||
<style type="text/css">
|
||||
.timesheet thead th {
|
||||
width: ${'{:0.2f}'.format(100.0 / 9)}%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<table class="timesheet">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Employee</th>
|
||||
% for day in weekdays:
|
||||
<th>${day.strftime('%A')}<br />${day.strftime('%b %d')}</th>
|
||||
% endfor
|
||||
<th>Total<br />Hours</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
% for emp in sorted(employees, key=unicode):
|
||||
<tr data-employee-uuid="${emp.uuid}">
|
||||
<td class="employee">
|
||||
## TODO: add link to single employee schedule / timesheet here...
|
||||
${emp}
|
||||
</td>
|
||||
% for day in emp.weekdays:
|
||||
<td class="day">
|
||||
% if render_day:
|
||||
${render_day(day)}
|
||||
% else:
|
||||
${self.render_day(day)}
|
||||
% endif
|
||||
</td>
|
||||
% endfor
|
||||
<td class="total">
|
||||
${self.render_employee_total(emp)}
|
||||
</td>
|
||||
</tr>
|
||||
% endfor
|
||||
% if employee is Undefined:
|
||||
<tr class="total">
|
||||
<td class="employee">${len(employees)} employees</td>
|
||||
% for day in weekdays:
|
||||
<td></td>
|
||||
% endfor
|
||||
<td></td>
|
||||
</tr>
|
||||
% else:
|
||||
<tr>
|
||||
<td> </td>
|
||||
% for day in employee.weekdays:
|
||||
<td>
|
||||
${self.render_employee_day_total(day)}
|
||||
</td>
|
||||
% endfor
|
||||
<td>
|
||||
${self.render_employee_total(employee)}
|
||||
</td>
|
||||
</tr>
|
||||
% endif
|
||||
</tbody>
|
||||
</table>
|
||||
</%def>
|
||||
|
||||
<%def name="edit_form()"></%def>
|
||||
|
||||
<%def name="edit_tools()"></%def>
|
||||
|
||||
<%def name="render_day(day)"></%def>
|
||||
|
||||
<%def name="render_employee_total(employee)"></%def>
|
||||
|
||||
<%def name="render_employee_day_total(day)"></%def>
|
||||
|
||||
|
||||
${self.timesheet_wrapper()}
|
||||
|
|
|
@ -1,148 +0,0 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
<%namespace file="/autocomplete.mako" import="autocomplete" />
|
||||
|
||||
<%def name="timesheet_wrapper(edit_form=None, edit_tools=None, context_menu=None, render_day=None, change_employee=None)">
|
||||
<div class="timesheet-wrapper">
|
||||
|
||||
${form.begin(id='filter-form')}
|
||||
${form.csrf_token()}
|
||||
|
||||
<table class="timesheet-header">
|
||||
<tbody>
|
||||
<tr>
|
||||
|
||||
<td class="filters" rowspan="2">
|
||||
|
||||
% if employee is not UNDEFINED:
|
||||
<div class="field-wrapper employee">
|
||||
<label>Employee</label>
|
||||
<div class="field">
|
||||
% if request.has_perm('{}.viewall'.format(permission_prefix)):
|
||||
${autocomplete('employee', url('employees.autocomplete'),
|
||||
field_value=employee.uuid if employee else None,
|
||||
field_display=unicode(employee or ''),
|
||||
selected='employee_selected',
|
||||
change_clicked=change_employee)}
|
||||
% else:
|
||||
${form.hidden('employee', value=employee.uuid)}
|
||||
${employee}
|
||||
% endif
|
||||
</div>
|
||||
</div>
|
||||
% endif
|
||||
|
||||
% if store_options is not UNDEFINED:
|
||||
${form.field_div('store', h.select('store', store.uuid if store else None, store_options))}
|
||||
% endif
|
||||
|
||||
% if department_options is not UNDEFINED:
|
||||
${form.field_div('department', h.select('department', department.uuid if department else None, department_options))}
|
||||
% endif
|
||||
|
||||
<div class="field-wrapper week">
|
||||
<label>Week of</label>
|
||||
<div class="field">
|
||||
${week_of}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
% if edit_tools:
|
||||
${edit_tools()}
|
||||
% endif
|
||||
|
||||
</td><!-- filters -->
|
||||
|
||||
<td class="menu">
|
||||
<ul id="context-menu">
|
||||
% if context_menu:
|
||||
${context_menu()}
|
||||
% endif
|
||||
</ul>
|
||||
</td><!-- menu -->
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="tools">
|
||||
<div class="grid-tools">
|
||||
<div class="week-picker">
|
||||
<button type="button" class="nav" data-date="${prev_sunday.strftime('%m/%d/%Y')}">« Previous</button>
|
||||
<button type="button" class="nav" data-date="${next_sunday.strftime('%m/%d/%Y')}">Next »</button>
|
||||
<label>Jump to week:</label>
|
||||
${form.text('date', value=sunday.strftime('%m/%d/%Y'))}
|
||||
</div>
|
||||
</div><!-- grid-tools -->
|
||||
</td><!-- tools -->
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table><!-- timesheet-header -->
|
||||
|
||||
${form.end()}
|
||||
|
||||
% if edit_form:
|
||||
${edit_form()}
|
||||
% endif
|
||||
|
||||
${timesheet(render_day=render_day)}
|
||||
|
||||
% if edit_form:
|
||||
${h.end_form()}
|
||||
% endif
|
||||
|
||||
</div><!-- timesheet-wrapper -->
|
||||
</%def>
|
||||
|
||||
<%def name="timesheet(render_day=None)">
|
||||
<style type="text/css">
|
||||
.timesheet thead th {
|
||||
width: ${'{:0.2f}'.format(100.0 / 9)}%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<table class="timesheet">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Employee</th>
|
||||
% for day in weekdays:
|
||||
<th>${day.strftime('%A')}<br />${day.strftime('%b %d')}</th>
|
||||
% endfor
|
||||
<th>Total<br />Hours</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
% for emp in sorted(employees, key=unicode):
|
||||
<tr data-employee-uuid="${emp.uuid}">
|
||||
<td class="employee">
|
||||
## TODO: add link to single employee schedule / timesheet here...
|
||||
${emp}
|
||||
</td>
|
||||
% for day in emp.weekdays:
|
||||
<td class="day">
|
||||
% if render_day:
|
||||
${render_day(day)}
|
||||
% endif
|
||||
</td>
|
||||
% endfor
|
||||
<td class="total">${emp.hours_display}</td>
|
||||
</tr>
|
||||
% endfor
|
||||
% if employee is UNDEFINED:
|
||||
<tr class="total">
|
||||
<td class="employee">${len(employees)} employees</td>
|
||||
% for day in weekdays:
|
||||
<td></td>
|
||||
% endfor
|
||||
<td></td>
|
||||
</tr>
|
||||
% else:
|
||||
<tr>
|
||||
<td> </td>
|
||||
% for day in employee.weekdays:
|
||||
<td>${day['hours_display']}</td>
|
||||
% endfor
|
||||
<td>${employee.hours_display}</td>
|
||||
</tr>
|
||||
% endif
|
||||
</tbody>
|
||||
</table>
|
||||
</%def>
|
|
@ -1,6 +1,5 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
<%inherit file="/shifts/base.mako" />
|
||||
<%namespace file="/shifts/lib.mako" import="timesheet_wrapper" />
|
||||
|
||||
<%def name="context_menu()">
|
||||
% if request.has_perm('schedule.edit'):
|
||||
|
@ -14,4 +13,19 @@
|
|||
% endif
|
||||
</%def>
|
||||
|
||||
${timesheet_wrapper(context_menu=context_menu, render_day=self.render_day)}
|
||||
<%def name="render_day(day)">
|
||||
% for shift in day['scheduled_shifts']:
|
||||
<p class="shift">${render_shift(shift)}</p>
|
||||
% endfor
|
||||
</%def>
|
||||
|
||||
<%def name="render_employee_total(employee)">
|
||||
${employee.scheduled_hours_display}
|
||||
</%def>
|
||||
|
||||
<%def name="render_employee_day_total(day)">
|
||||
${day['scheduled_hours_display']}
|
||||
</%def>
|
||||
|
||||
|
||||
${parent.body()}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
<%inherit file="/shifts/base.mako" />
|
||||
<%namespace file="/shifts/lib.mako" import="timesheet_wrapper" />
|
||||
|
||||
<%def name="extra_javascript()">
|
||||
${parent.extra_javascript()}
|
||||
|
@ -69,13 +68,17 @@
|
|||
</%def>
|
||||
|
||||
<%def name="render_day(day)">
|
||||
% for shift in day['shifts']:
|
||||
% for shift in day['scheduled_shifts']:
|
||||
<p class="shift" data-uuid="${shift.uuid}">
|
||||
${render_shift(shift)}
|
||||
</p>
|
||||
% endfor
|
||||
</%def>
|
||||
|
||||
<%def name="render_employee_total(employee)">
|
||||
${employee.scheduled_hours_display}
|
||||
</%def>
|
||||
|
||||
<%def name="edit_form()">
|
||||
${h.form(url('schedule.edit'), id='timetable-form')}
|
||||
${h.csrf_token(request)}
|
||||
|
@ -90,7 +93,8 @@
|
|||
</div>
|
||||
</%def>
|
||||
|
||||
${timesheet_wrapper(edit_form=edit_form, edit_tools=edit_tools, context_menu=context_menu, render_day=render_day)}
|
||||
|
||||
${self.timesheet_wrapper(with_edit_form=True)}
|
||||
|
||||
${edit_tools()}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
<%namespace file="/shifts/lib.mako" import="timesheet" />
|
||||
<%namespace file="/shifts/base.mako" import="render_day" />
|
||||
<%namespace file="/shifts/base.mako" import="timesheet" />
|
||||
<%namespace file="/shifts/schedule.mako" import="render_day" />
|
||||
<html>
|
||||
<head>
|
||||
## TODO: this seems a little hacky..?
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
<%inherit file="/shifts/base.mako" />
|
||||
<%namespace file="/shifts/lib.mako" import="timesheet_wrapper" />
|
||||
|
||||
<%def name="context_menu()">
|
||||
% if employee is not Undefined and request.has_perm('timesheet.edit'):
|
||||
|
@ -11,4 +10,15 @@
|
|||
% endif
|
||||
</%def>
|
||||
|
||||
${timesheet_wrapper(context_menu=context_menu, render_day=self.render_day)}
|
||||
<%def name="render_day(day)">
|
||||
% for shift in day['worked_shifts']:
|
||||
<p class="shift">${render_shift(shift)}</p>
|
||||
% endfor
|
||||
</%def>
|
||||
|
||||
<%def name="render_employee_total(employee)">
|
||||
${employee.worked_hours_display}
|
||||
</%def>
|
||||
|
||||
|
||||
${self.timesheet_wrapper()}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
<%inherit file="/shifts/base.mako" />
|
||||
<%namespace file="/shifts/lib.mako" import="timesheet_wrapper" />
|
||||
|
||||
<%def name="extra_javascript()">
|
||||
${parent.extra_javascript()}
|
||||
|
@ -22,13 +21,17 @@
|
|||
</%def>
|
||||
|
||||
<%def name="render_day(day)">
|
||||
% for shift in day['shifts']:
|
||||
% for shift in day['worked_shifts']:
|
||||
<p class="shift" data-uuid="${shift.uuid}">
|
||||
${render_shift(shift)}
|
||||
</p>
|
||||
% endfor
|
||||
</%def>
|
||||
|
||||
<%def name="render_employee_total(employee)">
|
||||
${employee.worked_hours_display}
|
||||
</%def>
|
||||
|
||||
<%def name="edit_form()">
|
||||
${h.form(url('timesheet.employee.edit'), id='timetable-form')}
|
||||
${h.csrf_token(request)}
|
||||
|
@ -41,7 +44,8 @@
|
|||
</div>
|
||||
</%def>
|
||||
|
||||
${timesheet_wrapper(edit_form=edit_form, edit_tools=edit_tools, context_menu=context_menu, render_day=render_day, change_employee='confirm_leave')}
|
||||
|
||||
${self.timesheet_wrapper(with_edit_form=True, change_employee='confirm_leave')}
|
||||
|
||||
${edit_tools()}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue