Skip to content

[FEAT] Implement cycles page#39

Merged
martian56 merged 11 commits intomainfrom
30-implement-cycles-page
Mar 20, 2026
Merged

[FEAT] Implement cycles page#39
martian56 merged 11 commits intomainfrom
30-implement-cycles-page

Conversation

@martian56
Copy link
Member

Description

This PR implements the Cycles page

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • Feature (non-breaking change which adds functionality)
  • Improvement (change that would cause existing functionality to not work as expected)
  • Code refactoring
  • Performance improvements
  • Documentation update

Closes #30

@martian56 martian56 added this to the Deadline milestone Mar 20, 2026
@martian56 martian56 self-assigned this Mar 20, 2026
@martian56 martian56 added enhancement New feature or request API UI labels Mar 20, 2026
Copilot AI review requested due to automatic review settings March 20, 2026 19:31
@martian56 martian56 requested review from nazarli-shabnam and removed request for Copilot March 20, 2026 19:32
@martian56 martian56 changed the title 30 implement cycles page [FEAT] Implement cycles page Mar 20, 2026
Copilot AI review requested due to automatic review settings March 20, 2026 19:36
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements the Cycles page end-to-end by expanding the UI (list + active-cycle insights, create/edit/delete flows, filters, favorites) and aligning backend cycle status behavior with date-derived “Plane-style” statuses.

Changes:

  • Added Cycle CRUD support in the UI (service + Create/Edit modals) and implemented the Cycles page UI with filtering + insights.
  • Introduced local “favorite cycles” (localStorage + cross-component eventing) and surfaced favorites in the sidebar.
  • Updated backend cycle status to be computed from start/end dates on List/Get/Create/Update.

Reviewed changes

Copilot reviewed 14 out of 15 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
ui/src/services/cycleService.ts Adds Cycle create/update/delete + listIssueIds API calls for the new Cycles UI.
ui/src/pages/ModulesPage.tsx Minor UI tweak to module name styling (removes hover underline).
ui/src/pages/CyclesPage.tsx Replaces placeholder with full Cycles page: active-cycle section, upcoming/completed lists, favorites, edit/delete actions, filtering event handling.
ui/src/lib/projectCyclesEvents.ts Adds window event constants to sync cycles filtering/refresh across header + page.
ui/src/hooks/useCycleFavorites.ts Implements localStorage-backed cycle favorites with a global change event.
ui/src/components/layout/Sidebar.tsx Loads and displays favorite cycles in the favorites section; listens for cycle favorites changes.
ui/src/components/layout/PageHeader.tsx Adds Cycles-specific Filters dropdown and “Add cycle” button; dispatches filter/refresh events; mounts CreateCycleModal.
ui/src/components/layout/AppShell.tsx Adjusts main content padding for the Cycles page layout.
ui/src/components/UpdateCycleModal.tsx Adds modal for editing a cycle (title/description/date range) via cycleService.update.
ui/src/components/CreateCycleModal.tsx Adds modal for creating cycles (project selection + fields) via cycleService.create.
ui/package.json Bumps UI version to 0.5.0.
ui/package-lock.json Updates lockfile version metadata to 0.5.0.
api/internal/service/cycle.go Computes cycle status from start/end dates during reads and after create/update.
api/internal/model/cycle.go Changes cycle JSON tags for start/end dates (removes omitempty).
api/internal/handler/cycle.go Enhances cycle date parsing to accept RFC3339 timestamps and date-only strings.
Files not reviewed (1)
  • ui/package-lock.json: Language not supported
Comments suppressed due to low confidence (2)

api/internal/handler/cycle.go:31

  • parseOptionalTime returns nil when parsing fails, which means invalid start_date/end_date values are silently treated as “not provided” (e.g. Create would succeed and produce a draft cycle). Consider returning an error from the parser and responding with 400 (similar to IssueHandler’s date validation) so clients get clear feedback on malformed dates.
func parseOptionalTime(s string) *time.Time {
	if s == "" {
		return nil
	}
	// Try RFC3339 first (full timestamp), then date-only YYYY-MM-DD
	t, err := time.Parse(time.RFC3339, s)
	if err == nil {
		return &t
	}
	t, err = time.Parse("2006-01-02", s)
	if err != nil {
		return nil
	}
	return &t

api/internal/service/cycle.go:149

  • Cycle Update still accepts a status argument, but the service no longer applies it (status is recomputed from dates). This creates an API footgun where clients can send status and get it ignored. Either remove/ignore status at the handler level (don’t bind/forward it) or make the service signature not accept it and/or return 400 if a status is provided.
func (s *CycleService) Update(ctx context.Context, workspaceSlug string, projectID, cycleID uuid.UUID, userID uuid.UUID, name, description, status string, startDate, endDate *time.Time) (*model.Cycle, error) {
	cy, err := s.Get(ctx, workspaceSlug, projectID, cycleID, userID)
	if err != nil {
		return nil, err
	}
	if name != "" {
		cy.Name = name
	}
	if description != "" {
		cy.Description = description
	}
	if startDate != nil {
		cy.StartDate = startDate
	}
	if endDate != nil {
		cy.EndDate = endDate
	}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@martian56 martian56 merged commit e6983ad into main Mar 20, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

API enhancement New feature or request UI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement Cycles page

2 participants