fix(plan): add 'Upravit celý rozsah' button, use class-based action rows

This commit is contained in:
BOHA
2026-06-05 13:58:07 +02:00
parent 9a11a8f001
commit 2f76fe0bc1
3 changed files with 61 additions and 23 deletions

View File

@@ -8,6 +8,7 @@ import { ResolvedCell } from "../lib/queries/plan";
interface Project { interface Project {
id: number; id: number;
name: string; name: string;
project_number?: string;
} }
export type PlanCellModalMode = export type PlanCellModalMode =
@@ -64,6 +65,7 @@ interface Props {
userId: number, userId: number,
date: string, date: string,
) => Promise<void>; ) => Promise<void>;
onSwitchToEditRange: (entryId: number, userId: number, date: string) => void;
} }
const CATEGORIES = [ const CATEGORIES = [
@@ -218,13 +220,7 @@ function EditForm(props: Props) {
loading={submitting} loading={submitting}
> >
{mode.kind !== "create" && ( {mode.kind !== "create" && (
<div <div className="plan-modal-actions">
style={{
marginBottom: 12,
display: "flex",
justifyContent: "flex-end",
}}
>
<button <button
type="button" type="button"
className="admin-btn admin-btn-danger" className="admin-btn admin-btn-danger"
@@ -314,7 +310,8 @@ function EditForm(props: Props) {
function DayInRangeModal( function DayInRangeModal(
props: Props & { mode: Extract<PlanCellModalMode, { kind: "day-in-range" }> }, props: Props & { mode: Extract<PlanCellModalMode, { kind: "day-in-range" }> },
) { ) {
const { mode, onClose, onCreateOverrideFromRange } = props; const { mode, onClose, onCreateOverrideFromRange, onSwitchToEditRange } =
props;
return ( return (
<FormModal <FormModal
isOpen isOpen
@@ -331,22 +328,17 @@ function DayInRangeModal(
<p>Co chcete udělat?</p> <p>Co chcete udělat?</p>
<ul> <ul>
<li> <li>
Upravit celý rozsah klikněte na tlačítko níže nebo zavřete a <strong>Upravit celý rozsah</strong> otevře editor celého rozsahu.
klikněte znovu na buňku v režimu editace rozsahu.
</li> </li>
<li> <li>
Upravit pouze tento den vytvoří přepsání (override) pro toto datum. <strong>Upravit pouze tento den</strong> vytvoří přepsání (override)
pro toto datum; zbytek rozsahu zůstane beze změny.
</li>
<li>
<strong>Zavřít</strong> ponechá rozsah beze změny.
</li> </li>
<li>Zavřít ponechá rozsah beze změny.</li>
</ul> </ul>
<div <div className="plan-modal-actions">
style={{
marginTop: 12,
display: "flex",
gap: 8,
justifyContent: "flex-end",
}}
>
<button <button
type="button" type="button"
className="admin-btn admin-btn-secondary" className="admin-btn admin-btn-secondary"
@@ -368,15 +360,27 @@ function DayInRangeModal(
> >
Upravit pouze tento den Upravit pouze tento den
</button> </button>
<button
type="button"
className="admin-btn admin-btn-primary"
onClick={() =>
onSwitchToEditRange(mode.entryId, mode.userId, mode.date)
}
>
Upravit celý rozsah
</button>
</div> </div>
</FormModal> </FormModal>
); );
} }
function ViewModal(props: Props) { function ViewModal(props: Props) {
const { mode, onClose } = props; const { mode, onClose, projects } = props;
if (mode.kind !== "view") return null; if (mode.kind !== "view") return null;
const c = mode.cell; const c = mode.cell;
const project = c.project_id
? (projects.find((p) => p.id === c.project_id) ?? null)
: null;
return ( return (
<FormModal isOpen title="Detail plánu" onClose={onClose} hideFooter> <FormModal isOpen title="Detail plánu" onClose={onClose} hideFooter>
<p> <p>
@@ -386,10 +390,15 @@ function ViewModal(props: Props) {
<strong>Kategorie:</strong> {c.category} <strong>Kategorie:</strong> {c.category}
</p> </p>
<p> <p>
<strong>Projekt:</strong> {c.project_id ?? ""} <strong>Projekt:</strong>{" "}
{project
? project.project_number
? `${project.project_number}${project.name}`
: project.name
: "—"}
</p> </p>
<p> <p>
<strong>Text:</strong> {c.note} <strong>Text:</strong> {c.note || "—"}
</p> </p>
{c.rangeFrom && c.rangeTo && ( {c.rangeFrom && c.rangeTo && (
<p> <p>

View File

@@ -203,6 +203,23 @@ export default function PlanWork() {
setModalCell(null); setModalCell(null);
}, [setHookModal]); }, [setHookModal]);
// Switch the modal from "day-in-range" to "edit-range" mode, keeping the
// same cell context so the EditForm opens with the range's values.
const switchToEditRange = useCallback(
(entryId: number, userId: number, date: string) => {
const cell = getCell(grid, userId, date);
if (!cell) return;
setModalCell(cell);
setHookModal({
kind: "edit-range",
entryId,
userId,
date,
});
},
[grid, setHookModal],
);
// --- Mutation wrappers ----------------------------------------------------- // --- Mutation wrappers -----------------------------------------------------
// The modal calls these with plain objects / ids. We resolve them to the // The modal calls these with plain objects / ids. We resolve them to the
// hook's mutateAsync calls and surface server errors as alerts. // hook's mutateAsync calls and surface server errors as alerts.
@@ -468,6 +485,7 @@ export default function PlanWork() {
onUpdateOverride={updateOverrideFn} onUpdateOverride={updateOverrideFn}
onDeleteOverride={deleteOverrideFn} onDeleteOverride={deleteOverrideFn}
onCreateOverrideFromRange={createOverrideFromRange} onCreateOverrideFromRange={createOverrideFromRange}
onSwitchToEditRange={switchToEditRange}
/> />
</div> </div>
); );

View File

@@ -167,3 +167,14 @@
background: transparent; background: transparent;
padding: 0; padding: 0;
} }
/* Action row inside a modal body (e.g. Delete button at top, or button
group in the day-in-range chooser). Mirrors .admin-modal-footer
styling but lives inside .admin-modal-body. */
.plan-modal-actions {
display: flex;
gap: 8px;
justify-content: flex-end;
margin-top: 12px;
margin-bottom: 0;
}