Skip to content

79 feat projects order and filter buttons#92

Open
Rafetikus wants to merge 7 commits intomainfrom
79-feat-projects-order-and-filter-buttons
Open

79 feat projects order and filter buttons#92
Rafetikus wants to merge 7 commits intomainfrom
79-feat-projects-order-and-filter-buttons

Conversation

@Rafetikus
Copy link
Copy Markdown
Member

@Rafetikus Rafetikus commented Apr 20, 2026

This pull request significantly enhances the filtering, sorting, and user experience of the ProjectsListPage component. The changes introduce support for multiple URL-based filters (such as access, lead, member, date, and favorites), add sorting options, and improve the empty state messaging to better reflect the user's filter selections.

Filtering and Sorting Improvements:

  • Added parsing of URL search parameters to support filtering projects by access type (private/public), project lead, members, creation date, favorites, and "my projects only". These filters are now applied in sequence to the project list. [1] [2]
  • Implemented robust sorting logic for projects, allowing sorting by name, creation date, member count, and manual order, with both ascending and descending directions.

User Experience Enhancements:

  • Improved the empty state message: now displays "No projects match the selected filters." if any filters are active and no projects are found, otherwise shows "No projects yet."
  • Simplified the logic for closing the "create project" modal by directly manipulating the search parameters, improving code clarity.

Authentication Context Usage:

Copilot AI review requested due to automatic review settings April 20, 2026 09:14
@Rafetikus Rafetikus linked an issue Apr 20, 2026 that may be closed by this pull request
@Rafetikus Rafetikus self-assigned this Apr 20, 2026
@Rafetikus Rafetikus added this to the Deadline milestone Apr 20, 2026
Copy link
Copy Markdown

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

Adds sorting and richer filtering controls for the workspace Projects list, wiring UI query params in the header to client-side filtering/sorting on the list page (Issue #79).

Changes:

  • Add query-param driven filtering (access, lead, members, created-date, “my projects”, favorites) and sorting logic to the projects list.
  • Replace placeholder header buttons with functional Sort and Filters dropdowns (including workspace member lookups for lead/member filters).
  • Improve empty-state messaging when filters are active.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
ui/src/pages/ProjectsListPage.tsx Parses filter/sort params from the URL and applies filtering + sorting to the projects collection.
ui/src/components/layout/PageHeader.tsx Implements “Sort projects” and “Filter projects” dropdowns that write filter/sort state into URL search params.

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

Comment thread ui/src/pages/ProjectsListPage.tsx
Comment thread ui/src/pages/ProjectsListPage.tsx Outdated
Comment thread ui/src/pages/ProjectsListPage.tsx Outdated
Comment thread ui/src/components/layout/PageHeader.tsx Outdated
@Rafetikus Rafetikus added enhancement New feature or request UI UX labels Apr 20, 2026
@nazarli-shabnam
Copy link
Copy Markdown
Member

consider copilot comments, and re-request review from me

Copy link
Copy Markdown
Member

@nazarli-shabnam nazarli-shabnam left a comment

Choose a reason for hiding this comment

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

improve search query.

Copy link
Copy Markdown

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

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.


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

Copy link
Copy Markdown

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

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.


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

Comment thread ui/src/components/layout/PageHeader.tsx Outdated
Copy link
Copy Markdown
Member

@Javenn0 Javenn0 left a comment

Choose a reason for hiding this comment

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

Well done!

Copy link
Copy Markdown

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

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.


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

Comment thread ui/src/lib/projectsListSearchParams.ts Outdated
Comment thread ui/src/pages/ProjectsListPage.tsx Outdated
Comment thread ui/src/components/layout/PageHeader.tsx
Comment thread ui/src/components/layout/PageHeader.tsx
Comment thread ui/src/pages/ProjectsListPage.tsx
@Rafetikus
Copy link
Copy Markdown
Member Author

@nazarli-shabnam quick review

@Rafetikus Rafetikus requested a review from Copilot April 28, 2026 10:45
@Rafetikus
Copy link
Copy Markdown
Member Author

ctrl+enter AND enter should work in project settings->add member

Copy link
Copy Markdown

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

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.


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

Comment on lines +215 to +221
.filter((p) => {
if (memberFilters.length === 0) return true;
const memberIds = membersByProject[p.id] ?? [];
return memberFilters.some(
(memberId) => memberIds.includes(memberId) || p.project_lead_id === memberId,
);
})
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

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

memberFilters depends on membersByProject, but while members are still loading membersByProject[p.id] is [], which makes this filter exclude every project (temporary empty list / misleading empty-state) whenever a member filter is active. Consider tracking a “membersByProjectLoaded” boolean (e.g., keys count === allProjects.length) and either (a) show a loading indicator while filters require member data, or (b) treat missing member data as “unknown” and keep projects until the member list has loaded.

Copilot uses AI. Check for mistakes.
Comment on lines +217 to +224
const memberIds = membersByProject[p.id] ?? [];
return memberFilters.some(
(memberId) => memberIds.includes(memberId) || p.project_lead_id === memberId,
);
})
.filter((p) => {
if (!myProjectsOnly || !authUser) return true;
const memberIds = membersByProject[p.id] ?? [];
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

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

myProjectsOnly has the same issue as the member filter: until membersByProject finishes loading, memberIds is [] so this condition filters out projects the user may belong to, causing a brief “no projects” state. Consider gating this filter on member-data readiness (or showing a loading state) to avoid flicker and incorrect empty messaging.

Suggested change
const memberIds = membersByProject[p.id] ?? [];
return memberFilters.some(
(memberId) => memberIds.includes(memberId) || p.project_lead_id === memberId,
);
})
.filter((p) => {
if (!myProjectsOnly || !authUser) return true;
const memberIds = membersByProject[p.id] ?? [];
const hasMembersLoaded = Object.prototype.hasOwnProperty.call(membersByProject, p.id);
if (!hasMembersLoaded) return true;
const memberIds = membersByProject[p.id];
return memberFilters.some(
(memberId) => memberIds.includes(memberId) || p.project_lead_id === memberId,
);
})
.filter((p) => {
if (!myProjectsOnly || !authUser) return true;
const hasMembersLoaded = Object.prototype.hasOwnProperty.call(membersByProject, p.id);
if (!hasMembersLoaded) return true;
const memberIds = membersByProject[p.id];

Copilot uses AI. Check for mistakes.
Comment on lines +248 to +252
999,
).getTime()
: NaN;
if (!Number.isFinite(afterMs) || !Number.isFinite(beforeMs)) return true;
return createdAtMs >= afterMs && createdAtMs <= beforeMs;
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

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

For createdDateFilter === 'custom', the filter is effectively disabled unless both createdAfter and createdBefore parse to finite timestamps (if (!Number.isFinite(afterMs) || !Number.isFinite(beforeMs)) return true). This makes the UI state inconsistent if one bound is missing/invalid (e.g. URL edited manually): the filter appears active but doesn’t filter anything. Consider supporting open-ended ranges (only after / only before) and treating invalid bounds as non-matching (or clearing the custom filter).

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request UI UX

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feat: projects order and filter buttons

4 participants