fix(plan): readable audit descriptions, project labels, dashboard invalidation, view-only & sticky-column UI
Work-plan fixes from this session: - Czech audit descriptions for plan entries/overrides (was empty '-') - server-embedded project label on grid cells (was '-' past the 100-project cap) - dashboard activity + audit-log cache invalidation on plan mutations - read-only cells: no '+' on empty, keep hover on cells with a record - view modal: Czech category + formatted dates - sticky date column made opaque (no bleed-through on horizontal scroll) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -18,12 +18,52 @@ export interface ResolvedCell {
|
||||
user_id: number;
|
||||
shift_date: string;
|
||||
project_id: number | null;
|
||||
/** Project label resolved server-side (see resolveGrid). Lets the UI show
|
||||
* the project without depending on the capped/permission-gated projects
|
||||
* list. Null when the cell has no project. */
|
||||
project_number: string | null;
|
||||
project_name: string | null;
|
||||
category: string;
|
||||
note: string;
|
||||
rangeFrom: string | null;
|
||||
rangeTo: string | null;
|
||||
}
|
||||
|
||||
/** Czech labels for the plan_category enum — single source of truth shared
|
||||
* by the grid chips, the detail view, and aria-labels. */
|
||||
export const PLAN_CATEGORIES: ReadonlyArray<{ value: string; label: string }> =
|
||||
[
|
||||
{ value: "work", label: "Práce" },
|
||||
{ value: "preparation", label: "Příprava" },
|
||||
{ value: "travel", label: "Cesta / Montáž" },
|
||||
{ value: "leave", label: "Dovolená" },
|
||||
{ value: "sick", label: "Nemoc" },
|
||||
{ value: "training", label: "Školení" },
|
||||
{ value: "other", label: "Jiné" },
|
||||
];
|
||||
|
||||
const PLAN_CATEGORY_LABELS: Record<string, string> = Object.fromEntries(
|
||||
PLAN_CATEGORIES.map((c) => [c.value, c.label]),
|
||||
);
|
||||
|
||||
/** Czech label for a plan category, falling back to the raw value. */
|
||||
export function planCategoryLabel(value: string): string {
|
||||
return PLAN_CATEGORY_LABELS[value] ?? value;
|
||||
}
|
||||
|
||||
/** Build the display label for a cell's project, preferring the server-
|
||||
* embedded fields. Returns null when the cell has no project. */
|
||||
export function cellProjectLabel(cell: {
|
||||
project_number: string | null;
|
||||
project_name: string | null;
|
||||
}): string | null {
|
||||
if (!cell.project_number && !cell.project_name) return null;
|
||||
if (cell.project_number && cell.project_name) {
|
||||
return `${cell.project_number} — ${cell.project_name}`;
|
||||
}
|
||||
return cell.project_number ?? cell.project_name;
|
||||
}
|
||||
|
||||
export interface GridData {
|
||||
view: "week" | "month";
|
||||
date_from: string;
|
||||
|
||||
Reference in New Issue
Block a user