Add ignore_dates field to worker constraints and implement related tests
This commit is contained in:
+100
-10
@@ -422,12 +422,11 @@ function renderWorkerList() {
|
||||
const displayName = (w.display_name || '') + '';
|
||||
const site = (w.site || '') + '';
|
||||
const searchName = (displayName || name).toLowerCase();
|
||||
if (
|
||||
filter
|
||||
&& searchName.indexOf(filter) === -1
|
||||
&& name.toLowerCase().indexOf(filter) === -1
|
||||
&& site.toLowerCase().indexOf(filter) === -1
|
||||
) return;
|
||||
if (filter) {
|
||||
const matchesName = searchName.indexOf(filter) !== -1;
|
||||
const matchesSite = site.toLowerCase().indexOf(filter) !== -1;
|
||||
if (!matchesName && !matchesSite) return;
|
||||
}
|
||||
// if shiftFilter, ensure worker has target or assigned for that shift
|
||||
// attempt to read per-worker targets and counts from DOM if not present in JSON
|
||||
let targets = w.shift_target_number || {};
|
||||
@@ -451,21 +450,112 @@ function renderWorkerList() {
|
||||
}
|
||||
const fte = w.fte || '';
|
||||
const labelName = displayName || name;
|
||||
const card = $(`<div class='worker-card' style='border:1px solid #ccc;padding:8px;margin-bottom:6px;'><strong>${labelName}</strong> <span style='color:#666'>${site}</span><div>FTE: ${fte}</div></div>`);
|
||||
const grade = w.grade || '';
|
||||
const id = w.id ? String(w.id).substring(0, 8) : '';
|
||||
const card = $(`<div class='worker-card'><div class='worker-header'><strong>${labelName}</strong> <span class='worker-id'>${id}</span></div><div class='worker-meta'><span class='worker-site'>${site}</span> • <span class='worker-grade'>Grade: ${grade}</span> • <span class='worker-fte'>FTE: ${fte}%</span></div></div>`);
|
||||
// show shift targets summary
|
||||
if (w.shift_target_number) {
|
||||
const tbl = $("<table style='margin-top:6px; width:100%;'></table>");
|
||||
if (w.shift_target_number && Object.keys(w.shift_target_number).length > 0) {
|
||||
const tbl = $("<table class='worker-shifts-table'></table>");
|
||||
const header = $("<thead><tr><th>Shift</th><th class='text-right'>Assigned</th><th class='text-right'>Target</th></tr></thead>");
|
||||
tbl.append(header);
|
||||
const tbody = $("<tbody></tbody>");
|
||||
Object.keys(w.shift_target_number).forEach(s => {
|
||||
const t = w.shift_target_number[s];
|
||||
const c = (w.shift_counts && w.shift_counts[s]) ? w.shift_counts[s] : 0;
|
||||
tbl.append(`<tr><td style='width:60%'>${s}</td><td style='text-align:right'>${c} assigned</td><td style='text-align:right'>target ${parseFloat(t).toFixed(2)}</td></tr>`);
|
||||
tbody.append(`<tr><td>${s}</td><td class='text-right'>${c}</td><td class='text-right'>${parseFloat(t).toFixed(2)}</td></tr>`);
|
||||
});
|
||||
tbl.append(tbody);
|
||||
card.append(tbl);
|
||||
}
|
||||
$list.append(card);
|
||||
});
|
||||
}
|
||||
|
||||
// Add CSS for worker details styling and dark mode
|
||||
if ($('#worker-details-style').length === 0) {
|
||||
$('head').append(`<style id='worker-details-style'>
|
||||
.worker-card {
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
padding: 8px;
|
||||
margin-bottom: 8px;
|
||||
background: #fff;
|
||||
transition: background-color 0.2s, border-color 0.2s;
|
||||
}
|
||||
.worker-card:hover {
|
||||
background: #f5f5f5;
|
||||
border-color: #999;
|
||||
}
|
||||
.worker-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.worker-header strong {
|
||||
flex: 1;
|
||||
margin: 0;
|
||||
}
|
||||
.worker-id {
|
||||
font-size: 0.8em;
|
||||
color: #999;
|
||||
font-family: monospace;
|
||||
}
|
||||
.worker-meta {
|
||||
font-size: 0.9em;
|
||||
color: #666;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.worker-site, .worker-grade, .worker-fte {
|
||||
display: inline;
|
||||
}
|
||||
.worker-shifts-table {
|
||||
margin-top: 6px;
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
.worker-shifts-table thead {
|
||||
background: #f0f0f0;
|
||||
font-weight: bold;
|
||||
}
|
||||
.worker-shifts-table th, .worker-shifts-table td {
|
||||
padding: 4px 6px;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
.worker-shifts-table tr:nth-child(even) {
|
||||
background: #fafafa;
|
||||
}
|
||||
.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.worker-card {
|
||||
background: #2d2d2d;
|
||||
border-color: #444;
|
||||
color: #e0e0e0;
|
||||
}
|
||||
.worker-card:hover {
|
||||
background: #333;
|
||||
border-color: #666;
|
||||
}
|
||||
.worker-meta, .worker-id {
|
||||
color: #aaa;
|
||||
}
|
||||
.worker-shifts-table thead {
|
||||
background: #1e1e1e;
|
||||
color: #e0e0e0;
|
||||
}
|
||||
.worker-shifts-table th, .worker-shifts-table td {
|
||||
border-color: #444;
|
||||
}
|
||||
.worker-shifts-table tr:nth-child(even) {
|
||||
background: #252525;
|
||||
}
|
||||
}
|
||||
</style>`);
|
||||
}
|
||||
|
||||
// initialize panels
|
||||
renderShiftSettings();
|
||||
renderWorkerFilterOptions();
|
||||
|
||||
Reference in New Issue
Block a user