From e4eaca378bf1c6f975d69777bed8f32d4b8958b6 Mon Sep 17 00:00:00 2001 From: Ross Date: Sun, 14 Dec 2025 09:22:47 +0000 Subject: [PATCH] . --- .../djangorota/static/output/timetable.css | 295 ++++++++++++++++++ .../templates/rota/leave_request.html | 111 +++++++ .../templates/rota/worker_detail.html | 102 ++++-- djangorota/rota/views.py | 29 +- 4 files changed, 505 insertions(+), 32 deletions(-) create mode 100644 djangorota/djangorota/static/output/timetable.css diff --git a/djangorota/djangorota/static/output/timetable.css b/djangorota/djangorota/static/output/timetable.css new file mode 100644 index 0000000..bc48266 --- /dev/null +++ b/djangorota/djangorota/static/output/timetable.css @@ -0,0 +1,295 @@ +html { + + /* color: red; */ +} + +table { + /* margin-top: 50px; */ + text-align: center; + /* table-layout : fixed; */ + /* width:150px */ + /* width: 200%; */ + /* overflow-x: auto; + display: block; + position: relative; */ + border-collapse: separate; + border-spacing: 0; + +} + +#main-table { + padding-top: 100px; +} + +.shift-table { + padding-top: 10px; +} + +.shift-table thead { + font-weight: bold; +} + +.table-div { + /* overflow-x: auto; */ + /* width: 80%; */ + overflow-x: scroll; + margin-left: 200px; + overflow-y: visible; + padding: 0; +} + +#main-table th { + text-align: center; + white-space: nowrap; + transform: rotate(90deg) translateX(-100px); + position: sticky; + top: 0; + +} + +#main-table th p { + margin: 0 -100%; + display: inline-block; +} + +#main-table th p:before { + content: ''; + width: 0; + padding-top: 110%; + /* takes width as reference, + 10% for faking some extra padding */ + display: inline-block; + vertical-align: middle; +} + +#main-table td, +th { + max-width: 10px; + padding: 0px; +} + +#main-table tr { + padding: 0px; +} + +#main-table tr:hover { + background-color: lightblue; +} + +#main-table tr:hover .unavailable { + + background-color: lightgray; +} + +.Sat { + /* opacity: 30%; */ + /* background-color: lightsteelblue; */ + border-left: solid 1px lightsteelblue; +} + +.Sun { + border-right: solid 1px lightsteelblue; + +} + +.bank-holiday { + border-bottom: dotted 1px blue; + +} + +#main-table th.bank-holiday { + color: darkblue; + +} + +.plymouth { + color: #9169FF; +} + +.exeter { + color: #5F60E8; +} + +.truro { + color: #0074D9; +} + +.torquay, +.torbay { + color: #5FA8E8; +} + +.taunton { + color: #e85fdf; +} + + +.unavailable { + color: lightgray; +} + +.shift-requested { + color: green; +} + +.worker-summary { + position: absolute; + display: none; + overflow-x: visible; + width: 100%; + text-align: left; +} + +.site-summary { + display: inline-flex; +} + +.site-summary .site { + border: 1px solid black; + padding: 5px; + margin: 20px; +} + +.site-name { + font-weight: bold; +} + +.worker-summary span { + min-width: 160px; + display: inline-flex; +} + +.training-days-lost { + padding-top: 5px; +} + +.tdl-settings { + padding: 2px; +} + +.table-div+pre { + display: none; +} + +.shift-breakdown-button+pre { + display: none; +} + +.shift-breakdown-button { + display: block; +} + +.nwd { + color: lightcoral; +} + +#main-table th.worker, +#main-table td.worker { + position: absolute; + width: 200px; + max-width: 200px; + left: 0; + top: auto; + border-top-width: 1px; + /*only relevant for first row*/ + margin-top: -1px; + /*compensate for top border*/ +} + +.hidden { + opacity: 0%; +} + +.tsummary { + max-width: auto; +} + +#main-table.header th { + max-width: 200px; + +} + +table.transposed {} + +table.transposed tr {} + +table.transposed th, +table.transposed td { + width: fit-content; + max-width: unset; + position: relative; + border-top: solid 0.5px black; + border-right: solid 0.5px black; +} + +table.transposed .Sat { + /* opacity: 30%; */ + /* background-color: lightsteelblue; */ + border-top: solid 2px lightsteelblue !important; +} + +table.transposed .Sun { + border-bottom: solid 2px lightsteelblue !important; + +} + +table.transposed .bank-holiday { + border-bottom: dotted 2px blue !important; + +} + +table.transposed th.bank-holiday { + color: darkblue; + +} + +.target-assigned.no-colour { + background-color: white !important; +} + +.locum-shift { + background-color: lightgreen; +} + +.multi-shift { + line-height: 1; +} + +button.selected { + background: #0074d9; + color: #fff; +} + +#main-table th.col-hover { + background: #ffe066 !important; + color: #222 !important; +} + +.highlight-day-btn.highlighted { + background: #ffe066 !important; + color: #222 !important; + border: 2px solid #bfa600 !important; +} + +.highlight-day-btn.highlighted { + background: #ffe066 !important; + color: #222 !important; + border: 2px solid #bfa600 !important; +} + +#main-table td.day-highlighted, +#main-table th.day-highlighted { + /* background is set inline for custom color */ +} + +#display-settings-modal { + transition: box-shadow 0.2s; +} + +#main-table td.force-assigned.force-assigned-highlight { + background-color: #ffe066 !important; + border: 2px solid #ff8800 !important; +} + +#linear-shift-timetable td, #linear-shift-timetable th { + max-width: unset; +} diff --git a/djangorota/djangorota/templates/rota/leave_request.html b/djangorota/djangorota/templates/rota/leave_request.html index 38f8116..17bbef9 100644 --- a/djangorota/djangorota/templates/rota/leave_request.html +++ b/djangorota/djangorota/templates/rota/leave_request.html @@ -3,6 +3,14 @@ {% block content %}

Request leave{% if worker %} for {{ worker.name }}{% endif %}

+ +
+

Request leave on calendar

+ {% include 'rota/partials/flatpickr_includes.html' %} +
+

Click a start date then a second date to select a range and prefill the leave form.

+
+
{% csrf_token %} {{ form|crispy }} @@ -13,4 +21,107 @@
+ + + + {% endblock %} diff --git a/djangorota/djangorota/templates/rota/worker_detail.html b/djangorota/djangorota/templates/rota/worker_detail.html index f1bdccc..85bdbe7 100644 --- a/djangorota/djangorota/templates/rota/worker_detail.html +++ b/djangorota/djangorota/templates/rota/worker_detail.html @@ -6,11 +6,13 @@ {% include 'rota/partials/flatpickr_includes.html' %} @@ -18,8 +20,8 @@

Request leave on calendar

-
-

Click a date to request leave for that day.

+
+

Select a date or drag to select a range to request leave.

{{ worker.name }}

{{ worker.email }} - {{ worker.site }}

@@ -51,66 +53,104 @@ diff --git a/djangorota/rota/views.py b/djangorota/rota/views.py index 0d0ebc8..9d6aae6 100644 --- a/djangorota/rota/views.py +++ b/djangorota/rota/views.py @@ -515,7 +515,34 @@ def request_leave(request, token=None): return response return redirect("rota:worker_detail", worker_id=worker.id) else: - form = LeaveForm() + # Prefill dates when provided via query params for both full page and HTMX modal + date_q = request.GET.get("date") or request.POST.get("date") + start_q = request.GET.get("start_date") or request.POST.get("start_date") + end_q = request.GET.get("end_date") or request.POST.get("end_date") + if date_q: + try: + import datetime + + d = datetime.date.fromisoformat(date_q) + form = LeaveForm(initial={"start_date": d, "end_date": d}) + except Exception: + form = LeaveForm() + elif start_q or end_q: + try: + import datetime + + sd = datetime.date.fromisoformat(start_q) if start_q else None + ed = datetime.date.fromisoformat(end_q) if end_q else None + init = {} + if sd: + init["start_date"] = sd + if ed: + init["end_date"] = ed + form = LeaveForm(initial=init) + except Exception: + form = LeaveForm() + else: + form = LeaveForm() # Render modal or full page if is_hx: