"""Application list rendering.
Routines for formatting lists of applications as HTML tables. Provides column
definitions for use with :func:`uw.web.html.format.make_table_format`.
"""
from operator import attrgetter
from ll.xist import xsc
from ll.xist.ns import html
from uw.web.html.form import render_checkbox, render_hidden
from uw.web.html.sorttable import make_table_format_sortable, table_column
from uw.web.html.join import html_join
[docs]def make_application_link_column (base_prefix="", subpage="", confirm=False):
"""Compute a table column specification for linking to applications.
:param base_prefix: the base URL of the application (typically relative).
:param subpage: the subpage of the application to target.
:param bool confirm: whether to include the appl_id as a hidden field.
:return: A column specification suitable for use with
:func:`uw.web.html.format.make_table_format`.
The contents will be the UW ID as a link to the application.
"""
return (
html.col (width='9%'),
'UW ID', lambda r: [
render_hidden ("appl_id", r.appl_id) if confirm else None,
html.a (r.uw_id, href="%sview/%s/%s" % (base_prefix, r.appl_id, subpage), target="_blank"),
],
lambda x: {},
)
[docs]def attribute_rating_column (unitapp):
"""Compute the HTML attributes for the rating column.
:param unitapp: the candidate application.
:return: a dictionary of HTML attribute values.
The returned attributes always include the sort value used for ordering
when the column header is clicked. Additionally, a style attribute to
set the background colour will be provided if the rating has a colour.
"""
if unitapp.rating:
return {
"style": "background: #%s" % unitapp.rating.rating_colour,
"data_sort_value": "a%02d" % unitapp.rating.rating_sequence,
}
else:
return {
"data_sort_value": "a",
}
[docs]def attribute_due_column (unitapp):
"""Compute the basic HTML attributes for the due column.
:param unitapp: the candidate application.
:return: a dictionary of HTML attribute values.
The returned attributes are either a style attribute that sets the
background, or none at all. The background colour is set to indicate an
imminent or passed workflow deadline.
Also used for the status display on the individual application view.
"""
result = {}
diff = unitapp.find_due_days ()
if diff is None:
colour = None
elif diff <= 2:
colour = 'F88'
elif diff <= 5:
colour = 'FF8'
else:
colour = None
if colour is not None:
result['style'] = "background: #%s" % colour
return result
[docs]def attribute_due_column_sort (unitapp):
"""Compute the complete HTML attributes for the due column.
:param unitapp: the candidate application.
:return: a dictionary of HTML attribute values.
The returned attributes are those provided by attribute_due_column, with
an additional attribute providing the sort value used for ordering when the
column header is clicked.
"""
result = attribute_due_column (unitapp)
days = unitapp.find_due_days ()
if days is None:
days = 499999
result['data_sort_value'] = "a%06d" % (days + 500000)
return result
[docs]def attribute_state_column (unitapp):
"""Compute the HTML attributes for the state column.
:param unitapp: the candidate application.
:return: a dictionary of HTML attribute values.
The returned attributes are just a data-sort-value providing the sort value
used for ordering when the column header is clicked.
"""
result = {}
if unitapp.accept_count:
accept_status = 1
elif unitapp.waitlist_count:
accept_status = 2
else:
accept_status = 3
result['data_sort_value'] = "a%02d%d" % (unitapp.statusseq, accept_status)
return result
status_codes = {
'Student Permit': 'SP',
'Permanent Resident': 'PR',
}
[docs]def abbreviate_citizenship_status (status):
"""Abbreviate a citizenship status for convenient display.
:param status: a citizenship status as provided in the data extracts.
:return: an HTML fragment containing a possibly-abbreviated version of the
status.
If the status is abbreviated, the result is an HTML span with the
original status as a tooltip.
"""
code = status_codes.get (status)
if code is None:
return status
else:
return html.span (code, title=status)
citizenship_order = {
'Citizen': 'b',
'Permanent Resident': 'b',
'Student Permit': 'c',
}
[docs]def attribute_citizenship_column (unitapp):
"""Compute the HTML attributes for the citizenship column.
:param unitapp: the candidate application.
:return: a dictionary of HTML attribute values.
The only attribute returned is the sort value used for ordering when the
column header is clicked.
"""
applicant = unitapp.applicant
result = citizenship_order.get (applicant.imm_status, 'a')
citizen_country = applicant.citizen_country
if result == 'c' and citizen_country is not None:
result += citizen_country
return {'data_sort_value': result}
# Format (Col, Name, ContentFunc, AttrFunc)
application_list_columns = (
(html.col (width='10%'), 'Last Name, First Name (Preferred Name)', attrgetter ('names'), lambda x: {}),
(html.col (width='11%'), 'Plan', lambda r: html_join (html.span (r.plan_code, title=r.plan_transcript_description), html.br ()), lambda x: {}),
(html.col (width='9%'), 'Citizenship', format_citizenship, attribute_citizenship_column),
(html.col (width='4%'), 'Sex', lambda r: r.applicant.gender, lambda x: {}),
(html.col (width='6%'), 'Rating', lambda r: r.rating.rating_code if r.rating else None, attribute_rating_column),
(html.col (width='9%'), 'State', lambda r: [r.statusdesc, r.format_accept_counts ()], attribute_state_column),
(html.col (width='8%'), 'Due', lambda r: r.format_deadline (), attribute_due_column_sort),
)
application_term_column = (html.col (width='6%'), 'Admit Term', lambda r: r.admit_term.description (), lambda x: {})
application_select_column = (html.col (width='5%'), 'Select', lambda r: render_checkbox ("appl_id", value=r.appl_id, class_="table-checkbox"), lambda r: {'class_': "checkbox"})
[docs]def render_sort_table (table_columns, data, fixed=False):
"""Render a table so that the columns can be sorted by clicking the header.
:param table_columns: column specifications for passing to
:func:`uw.web.html.format.make_table_format`.
:param data: the data for the rows of the table.
:param fixed: whether the table should include fixed col percentages
Formats the table using make_table_format and then alters the table to work
with the sort table JavaScript module.
"""
cols = [table_column (col=col if fixed else None, head=head, content=content, attr=attr)
for col, head, content, attr in table_columns]
table_func = make_table_format_sortable (*cols)
table = table_func (data)
return table