Compare commits

...

2 Commits

Author SHA1 Message Date
BOHA
92252382ac chore(release): v2.0.8 — show all employees in dashboard attendance
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 13:07:59 +02:00
BOHA
8bed920de1 feat(dashboard): show every active employee in "Docházka dnes"
The attendance card listed only employees with a record today (present /
break / clocked-out / on-leave). Now every active employee appears;
those with no record today show as "absent" (Nepřítomen), so the card
reflects the whole team. Loads active users (was a bare count) and
appends the unrecorded ones.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 13:00:09 +02:00
3 changed files with 28 additions and 3 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "app-ts",
"version": "2.0.7",
"version": "2.0.8",
"description": "",
"main": "dist/server.js",
"scripts": {

View File

@@ -16,6 +16,7 @@ export const STATUS_LABELS: Record<string, string> = {
away: "Přestávka",
out: "Nepřihlášen",
leave: "Nepřítomen",
absent: "Nepřítomen",
};
// Re-exported from the single source of truth so the dashboard activity feed

View File

@@ -69,7 +69,7 @@ export default async function dashboardRoutes(
// Attendance admin — only for attendance.manage
if (has("attendance.manage")) {
const [todayAttendance, onLeaveToday, usersCount] = await Promise.all([
const [todayAttendance, onLeaveToday, activeUsers] = await Promise.all([
prisma.attendance.findMany({
where: {
shift_date: { gte: todayStart, lt: todayEnd },
@@ -89,8 +89,13 @@ export default async function dashboardRoutes(
users: { select: { id: true, first_name: true, last_name: true } },
},
}),
prisma.users.count({ where: { is_active: true } }),
prisma.users.findMany({
where: { is_active: true },
select: { id: true, first_name: true, last_name: true },
orderBy: [{ last_name: "asc" }, { first_name: "asc" }],
}),
]);
const usersCount = activeUsers.length;
const userAttendanceMap = new Map<number, (typeof todayAttendance)[0]>();
for (const a of todayAttendance) {
@@ -153,6 +158,25 @@ export default async function dashboardRoutes(
});
}
// Show every active employee — those with no attendance record today
// appear as "absent" so the card reflects the whole team, not just those
// who clocked in or are on leave.
const recordedUserIds = new Set<number>([
...userAttendanceMap.keys(),
...leaveUserIds,
]);
for (const user of activeUsers) {
if (recordedUserIds.has(user.id)) continue;
attendanceUsers.push({
user_id: user.id,
name: `${user.first_name} ${user.last_name}`,
initials:
`${user.first_name?.charAt(0) ?? ""}${user.last_name?.charAt(0) ?? ""}`.toUpperCase(),
status: "absent",
arrived_at: null,
});
}
result.attendance = {
present_today: presentCount,
total_active: usersCount,