feat(plan): drive category select and view label from DB categories

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
BOHA
2026-06-06 00:52:07 +02:00
parent 8b77a0a905
commit dab5ad8aa5
3 changed files with 12 additions and 18 deletions

View File

@@ -7,7 +7,7 @@ import ConfirmModal from "./ConfirmModal";
import useReducedMotion from "../hooks/useReducedMotion"; import useReducedMotion from "../hooks/useReducedMotion";
import { import {
ResolvedCell, ResolvedCell,
PLAN_CATEGORIES, PlanCategory,
planCategoryLabel, planCategoryLabel,
cellProjectLabel, cellProjectLabel,
} from "../lib/queries/plan"; } from "../lib/queries/plan";
@@ -61,6 +61,7 @@ interface Props {
open: boolean; open: boolean;
mode: PlanCellModalMode; mode: PlanCellModalMode;
projects: Project[]; projects: Project[];
categories: PlanCategory[];
onClose: () => void; onClose: () => void;
onSaveEntry: (body: any) => Promise<void>; onSaveEntry: (body: any) => Promise<void>;
onUpdateEntry: (id: number, body: any) => Promise<void>; onUpdateEntry: (id: number, body: any) => Promise<void>;
@@ -112,6 +113,7 @@ function EditForm(props: Props) {
} }
const isOverride = mode.kind === "edit-override"; const isOverride = mode.kind === "edit-override";
const activeCategories = props.categories.filter((c) => c.is_active);
const initial = (() => { const initial = (() => {
if (mode.kind === "create") { if (mode.kind === "create") {
@@ -292,8 +294,8 @@ function EditForm(props: Props) {
value={category} value={category}
onChange={(e) => setCategory(e.target.value)} onChange={(e) => setCategory(e.target.value)}
> >
{PLAN_CATEGORIES.map((c) => ( {activeCategories.map((c) => (
<option key={c.value} value={c.value}> <option key={c.key} value={c.key}>
{c.label} {c.label}
</option> </option>
))} ))}
@@ -419,7 +421,7 @@ function DayInRangeModal(
} }
function ViewModal(props: Props) { function ViewModal(props: Props) {
const { mode, onClose, projects } = props; const { mode, onClose, projects, categories } = props;
if (mode.kind !== "view") return null; if (mode.kind !== "view") return null;
const c = mode.cell; const c = mode.cell;
// Prefer the server-embedded project label; fall back to the projects-list // Prefer the server-embedded project label; fall back to the projects-list
@@ -440,7 +442,11 @@ function ViewModal(props: Props) {
<strong>Datum:</strong> {formatDate(c.shift_date)} <strong>Datum:</strong> {formatDate(c.shift_date)}
</p> </p>
<p> <p>
<strong>Kategorie:</strong> {planCategoryLabel(c.category)} <strong>Kategorie:</strong>{" "}
{planCategoryLabel(
c.category,
Object.fromEntries(categories.map((x) => [x.key, x])),
)}
</p> </p>
<p> <p>
<strong>Projekt:</strong> {projectLabel || "—"} <strong>Projekt:</strong> {projectLabel || "—"}

View File

@@ -53,19 +53,6 @@ export function categoryMap(
return map; return map;
} }
/** 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é" },
];
/** Czech label for a plan category key, resolved from the loaded categories /** Czech label for a plan category key, resolved from the loaded categories
* map, falling back to the raw key. The `map` arg is optional so callers not * map, falling back to the raw key. The `map` arg is optional so callers not
* yet threading categories still compile (they show the raw key until wired). */ * yet threading categories still compile (they show the raw key until wired). */

View File

@@ -684,6 +684,7 @@ export default function PlanWork() {
open={hookModal.kind !== "closed"} open={hookModal.kind !== "closed"}
mode={modalMode} mode={modalMode}
projects={projects} projects={projects}
categories={categories}
onClose={closeModal} onClose={closeModal}
onSaveEntry={saveEntry} onSaveEntry={saveEntry}
onUpdateEntry={updateEntryFn} onUpdateEntry={updateEntryFn}