feat: add Kropáček Ondřej + May–Jul feature work (half-cell marks, copy/paste, exports, roles)

New worker: Kropáček Ondřej (TKB, part-time student) inserted between
Dvořák Václav and Vondrák Pavel in data.json, the full-month Excel
template (new row 13, everything below shifted) and the docházka
template (13 person rows). Not added to the harmonogram/CIS roster —
he has no CIS personal number.

Also checkpoints the uncommitted work deployed to production between
May and July 2026:
- half-cell day/night preference marks (color + text per half)
- cell copy/paste (Ctrl+C/V, context menu), incl. from info rows
- light/dark theme toggle, TKB people filter, 162 filter
- full-month Excel export (template) and harmonogram export for CIS
- docházka export: half-time workers, retired flag, contractor handling
- third login role "cis" (viewer + export access)
- retired flag hides a person from UI/FPD while keeping past data

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Docker Config Backup
2026-09-17 13:02:52 +02:00
parent 131b0d0df1
commit 3d306e641c
22 changed files with 2231 additions and 242 deletions

View File

@@ -0,0 +1,132 @@
# Half-cell day/night preference marks — Design
**Date:** 2026-04-22
**Status:** approved, ready to implement
## Problem
In the original Excel schedule, each day cell was split horizontally
(left = night, right = day). Users marked preferences/obstacles by
filling the appropriate half with a color before shift planning began.
In the current app, each day = one cell. Users can only express
day-vs-night preferences via cell comments (small blue triangle), which
is not visual at a glance and therefore "annoying."
Multiple users have requested restoring the Excel behavior.
## Decisions
1. **Coexist with shifts** — preference marks stay visible after a shift
is assigned (so we can see whether we honored or violated the
request).
2. **Free color from palette** — same flexibility as the existing
whole-cell color picker; semantics are user-defined.
3. **Horizontal split: left = night, right = day** — matches the
original Excel.
4. **Visual when shift is assigned: corner triangles** — full shift
color fills the cell; small ~8×8 px triangles in the bottom corners
indicate the marks (bottom-left = night, bottom-right = day).
5. **Toggle in context menu** — segmented control `Celá | Noční | Denní`
above the color palette selects which field the next color click
updates.
## Data model
`CellValue` (in `types.ts`) gains two optional fields:
```ts
interface CellValue {
v?: string
color?: string // existing — full-cell background
dayColor?: string // NEW — right half / day mark
nightColor?: string // NEW — left half / night mark
}
```
The change is purely additive. Existing JSON files load unchanged.
## Rendering rules
| State | Look |
|-------|------|
| empty + no marks | empty (current) |
| `dayColor` and/or `nightColor` set, no shift | left half = `nightColor`, right half = `dayColor` (each independent; missing half = transparent or `color` fallback) |
| shift assigned, no marks | full shift color (current) |
| shift assigned + marks | full shift color + 8 px triangles: bottom-left = night, bottom-right = day |
Priority for picking renderer:
1. If `dayColor || nightColor` → split-half mode
2. Else if `color` → full-cell color (current behavior)
3. Else → empty
## Interaction
Right-click cell → existing context menu, with new segmented toggle
above the color palette:
```
Barva:
[ Celá ] [ Noční ] [ Denní ] ← default: Celá
● ● ● ● ● ● ● [Bez barvy]
```
- Toggle selects target field (`color`, `nightColor`, `dayColor`)
- Color click writes only to the selected target
- "Bez barvy" clears only the selected target
- Three fields are independent
## Drag-and-drop
Half marks are tied to the **day**, not the shift. When a user drags a
shift cell:
- Only `v` (and `color` of the shift) moves to the destination
- `dayColor` / `nightColor` stay on both source and destination days
## Compare / diff view
Differences in `dayColor` / `nightColor` count as cell changes — render
the same orange "modified" border as for value changes.
## Filters
- "Color only" filter (rainbow dot) — also hides cells whose only
content is `dayColor` / `nightColor` (no `v`)
- Hidden value filter (e.g. hide "A") — hides the cell entirely
including marks (marks are auxiliary)
## Scope
Half-mark editing is available on:
- ✅ Person cells (Pohotovost TKB / Pohotovost IT)
- ✅ Info rows (TKB / SAZLT / Metro / D8)
- ❌ PMS columns (month-end summary, doesn't make sense)
## Read-only
Existing `isReadOnly` guard handles viewer mode automatically. Viewers
see marks but cannot edit.
## Out of scope (phase 1)
- **Excel export/import** — original template has no clean
representation; round-trip would lose marks. Documented as a known
limitation; revisit if users request it.
- **PDF export** — will render half marks using same rules (no extra
work expected).
## Files to change
1. `web/src/types.ts` — extend `CellValue`
2. `web/src/useScheduleState.ts` — add `setCellHalfColor(personId,
dayIdx, target, color)` reducer + undo support
3. `web/src/ScheduleTable.tsx` — render split halves / corner triangles
in `PersonRow` and `renderInfoRowCells`
4. `web/src/ContextMenu.tsx` — add segmented toggle, route color clicks
to selected target
5. `web/src/cellColors.ts` — no change
Estimate: ~150 LoC across 4 files plus minimal CSS.