"Create" button opens sprint form on timeline page

This commit is contained in:
Oliver Bryan
2026-01-21 21:22:52 +00:00
parent 1a0d2e51e4
commit db0be8330e
2 changed files with 24 additions and 6 deletions

View File

@@ -2,6 +2,7 @@ import { useMemo } from "react";
import { useLocation, useNavigate } from "react-router-dom"; import { useLocation, useNavigate } from "react-router-dom";
import Account from "@/components/account"; import Account from "@/components/account";
import { IssueForm } from "@/components/issue-form"; import { IssueForm } from "@/components/issue-form";
import { SprintForm } from "@/components/sprint-form";
import LogOutButton from "@/components/log-out-button"; import LogOutButton from "@/components/log-out-button";
import OrgIcon from "@/components/org-icon"; import OrgIcon from "@/components/org-icon";
import { OrganisationSelect } from "@/components/organisation-select"; import { OrganisationSelect } from "@/components/organisation-select";
@@ -23,12 +24,13 @@ import Icon from "@/components/ui/icon";
import { IconButton } from "@/components/ui/icon-button"; import { IconButton } from "@/components/ui/icon-button";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { BREATHING_ROOM } from "@/lib/layout"; import { BREATHING_ROOM } from "@/lib/layout";
import { useOrganisations } from "@/lib/query/hooks"; import { useOrganisations, useSprints } from "@/lib/query/hooks";
export default function TopBar({ showIssueForm = true }: { showIssueForm?: boolean }) { export default function TopBar({ showIssueForm = true }: { showIssueForm?: boolean }) {
const { user } = useAuthenticatedSession(); const { user } = useAuthenticatedSession();
const { selectedOrganisationId, selectedProjectId, selectIssue } = useSelection(); const { selectedOrganisationId, selectedProjectId, selectIssue } = useSelection();
const { data: organisationsData = [] } = useOrganisations(); const { data: organisationsData = [] } = useOrganisations();
const { data: sprintsData = [] } = useSprints(selectedProjectId);
const location = useLocation(); const location = useLocation();
const navigate = useNavigate(); const navigate = useNavigate();
const activeView = location.pathname.startsWith("/timeline") ? "timeline" : "issues"; const activeView = location.pathname.startsWith("/timeline") ? "timeline" : "issues";
@@ -85,7 +87,7 @@ export default function TopBar({ showIssueForm = true }: { showIssueForm?: boole
</TabsList> </TabsList>
</Tabs> </Tabs>
)} )}
{selectedOrganisationId && selectedProjectId && showIssueForm && ( {selectedOrganisationId && selectedProjectId && showIssueForm && activeView === "issues" && (
<IssueForm <IssueForm
trigger={ trigger={
<IconButton <IconButton
@@ -99,6 +101,22 @@ export default function TopBar({ showIssueForm = true }: { showIssueForm?: boole
} }
/> />
)} )}
{selectedOrganisationId && selectedProjectId && showIssueForm && activeView === "timeline" && (
<SprintForm
projectId={selectedProjectId}
sprints={sprintsData}
trigger={
<IconButton
variant="outline"
className="w-9 h-9"
title="Create Sprint"
aria-label="Create sprint"
>
<Icon icon="plus" />
</IconButton>
}
/>
)}
</div> </div>
<div className={`flex gap-${BREATHING_ROOM} items-center`}> <div className={`flex gap-${BREATHING_ROOM} items-center`}>
<DropdownMenu> <DropdownMenu>

View File

@@ -286,9 +286,9 @@ export default function Timeline() {
> >
{sprint.name} {sprint.name}
</span> </span>
</div> <div className="text-[12px] text-muted-foreground tabular-nums">
<div className="text-xs text-muted-foreground tabular-nums"> {getSprintDateRange(sprint)}
{getSprintDateRange(sprint)} </div>
</div> </div>
{sprintIssues.length === 0 && ( {sprintIssues.length === 0 && (
<div className="text-xs text-muted-foreground text-pretty">No issues assigned.</div> <div className="text-xs text-muted-foreground text-pretty">No issues assigned.</div>
@@ -348,7 +348,7 @@ export default function Timeline() {
<button <button
type="button" type="button"
aria-label={`Edit sprint ${sprint.name}`} aria-label={`Edit sprint ${sprint.name}`}
className="absolute top-1/2 z-0 h-4 rounded cursor-pointer" className="absolute top-1/2 -translate-y-1/2 z-0 h-4 rounded cursor-pointer"
style={barStyle} style={barStyle}
title={`${sprint.name}: ${getSprintDateRange(sprint)}`} title={`${sprint.name}: ${getSprintDateRange(sprint)}`}
/> />