fix(plan): add 'Upravit celý rozsah' button, use class-based action rows
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user