Skip to content

[feature]: Apply View Filter to Sub-Issues #5578

Description

@justthecontent

Is there an existing issue for this?

  • I have searched the existing issues

Summary

When a filter is applied in Views, it should also be automatically applied to all relevant sub-issues.

Let's say I have issues and sub issues with todo, in progress and done statuses. Applying a todo, in progress filter in views should also filter the sub-issues according to the selected criteria like todo, in progress.

Currently, the filter works only for the parent issues, while sub-issues do not reflect the applied filter and continue to show done items.

Why should this be worked on?

View behavior and filters should be consistent irrespective of issue type. This would help triage out completed items better.

Activity

  1. leedsjb commented on Aug 20, 2025

    @leedsjb

    I too have observed this problem but in the inverse (fewer work items than expected shown as opposed to more than expected based on applied filters). It has resulted in confusion on my part. Specifically, epics summarize the state of Work Items by State Group as shown:

    Image

    I would expect to be able to filter the Work Items in the epic by "Backlog" state group to review the 5 items in the backlog state. However, since all 5 items are sub-Work Items the filter returns no results:

    Image
  2. gchanchal commented on Aug 20, 2025

    @gchanchal

    Hi @leedsjb , @justthecontent ,

    The point is valid, the solution is tricky due to an amazing capability of unlimited nesting in Plane.

    If I keep on filtering all children, imagine this scenario -
    Parent - To DO
    Child 1- To DO
    Child 2 - IN Progress
    Sub-Child2 - To DO

    In this case, since Child 2 got filtered, I will never be able to show Sub-Child2 -- and the idea of filtering the payload will still be lost.

    Lets consider this - under "Display" we have a toggle called" Show sub-work items" - Enable it. Now you will see the full payload in parallel. Just ignore the ">" to any parent because filter doesn't apply there. Now you have entire payload filtered properly irrespective of nesting. Only thing you are loosing is nesting view

    Thoughts?

    Image
  3. hwuu commented on Sep 29, 2026

    @hwuu

    Hi @vihar @pushya22, I'd like to pick this up. I went through the code first and have a proposal and a few questions. If someone on the team is already working on it, let me know and I'll leave it.

    What happens now

    Say you filter out Done and have this:

    A        In Progress
    ├─ B     Done
    │  └─ C  Todo
    ├─ D     Done
    └─ E     Todo
    

    Expanding A shows B, D and E. D is Done and nothing under it matches, but it still shows up.

    Image

    This only happens in the List and Spreadsheet layouts, because they're the only ones that expand a parent inline (IssueBlockRoot in list/block-root.tsx, SpreadsheetIssueRow in spreadsheet/issue-row.tsx). Kanban, Calendar and Gantt never nest children. Sub-work items only show up there as regular items when "Show sub-work items" is on, and those are filtered like everything else.

    The reason: the top-level list is fetched with the view's filters param and filtered on the server by ComplexFilterBackend / IssueFilterSet. Expanding a row calls a different endpoint, GET .../issues/<id>/sub-issues/. SubIssuesEndpoint doesn't look at filters at all (it only reads order_by and group_by), and the client doesn't send any.

    What I'd change

    Same example, after the change:

    A        In Progress
    ├─ B     Done         muted, only here because C matches
    │  └─ C  Todo
    └─ E     Todo
    
    • The top-level list stays as it is.

    • When you expand a row, a child shows up if it matches, or if something below it matches.

    • Rows that are only there because of a match further down (B) are muted. Otherwise it looks like the filter is broken: you filtered out Done and still see a Done row.

    • Children with nothing matching below them are hidden (D).

    • Only matches you can actually reach from the list count. Both layouts stop expanding inline at nesting level 3 and open the peek view instead, so anything deeper is ignored:

      level 0  A              In Progress
      level 1  └─ B           Done
      level 2     └─ C        Done
      level 3        └─ D     Done    <- expanding D opens peek instead
      level 4           └─ E  Todo
      

      If E counted, you'd get three muted rows and still couldn't get to E from the list. So here B is hidden and expanding A shows nothing. With "Show sub-work items" on, E still shows up as its own row.

    The sub-work items widget on the detail page works differently: it only filters the first level (since #7047 ). I'd leave the widget alone in this PR.

    How

    API: SubIssuesEndpoint takes the same filters param as the list, plus a depth for how many levels below the children the UI can still expand (0 to 2; the client knows this from the row's nesting level). When filters is set, it loads the children and their descendants down to that depth. Since depth is at most 2, that's a few parent_id__in queries, no recursive SQL. It then applies the filters with ComplexFilterBackend + IssueFilterSet and returns the children that match or have a match below them. Each child gets a matches_filters flag so the UI knows which rows to mute. Without filters, the response doesn't change.

    Web: expanding a row sends the current filters and the depth. The result goes into a separate store, not the existing subIssues map. That map is also used by the detail-page widget, siblings and parent selection, and fetchSubIssues overwrites the parent's sub_issues_count with however many items came back, so filtered results can't go there. Expanded rows get re-fetched when the filters change.

    Why not do it on the client: the client only loads direct children, so finding matches further down would mean a request per child per level. We'd also have to re-implement IssueFilterSet in TypeScript, since the existing getFilteredWorkItems only understands the old flat filter format.

    Tests: API tests for a direct match, a muted ancestor, nothing matching below, and a match below the depth limit. Unit tests for the new store.

    Questions

    1. Are you OK with the muted rows and the depth limit above? If there's an existing style you'd want for the muted rows, point me to it.
    2. With filters on, what should the sub-work item count and the expand arrow show? In the first example A has 3 children but only 2 are shown. In the depth example A has an expand arrow, but expanding it shows nothing.
    3. In cycle and module views, the endpoint itself limits the list to items in that cycle/module; it's not part of filters. So after this change, children outside the cycle/module would still show up under an expanded parent. Should they be limited too, or is that a separate issue?
    4. fix(web): sort sub-work items by the layout's order_by in spreadsheet and list layouts #9879 changes the same render code (block-root.tsx, issue-row.tsx) to sort nested items by the layout's order_by. Should I wait for it to merge and build on top of it?

    If this sounds right, I'll start on the PR.

  4. hwuu commented on Sep 29, 2026

    @hwuu

    One thing I should have addressed: @gchanchal's point above about deep nesting. Taking his example and filtering for To Do:

    Parent            To Do
    ├─ Child 1        To Do
    └─ Child 2        In Progress
       └─ Sub-Child 2 To Do
    

    With this proposal, expanding Parent shows Child 1 and Child 2, with Child 2 muted since it's only there because of Sub-Child 2. Expanding Child 2 then shows Sub-Child 2. So nothing becomes unreachable, and you keep the nesting instead of switching to the flat list.

    On unlimited nesting: items can nest as deep as you like, but List and Spreadsheet only expand inline down to level 3. So the server never has to look more than 2 levels below the children of the row being expanded, which keeps the query cheap.

    @leedsjb's case goes the other way: with "Show sub-work items" off, a matching sub-work item whose parent doesn't match never shows up. This proposal doesn't change that. Fixing it would mean pulling non-matching parents into the top-level list, which touches pagination, counts and grouping, so I'd keep it out of this PR. Turning on "Show sub-work items" covers it for now, as @gchanchal suggested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Fields

Edition

None yet

Version

None yet

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions