From db2fb631f8d940328a0543fdd71681ce04b09cf8 Mon Sep 17 00:00:00 2001 From: Don Kendall Date: Sun, 22 Mar 2026 01:04:23 -0400 Subject: [PATCH] fix(view): "Not Specified" group shows assigned issues (#10606) (#10666) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When grouping by assignee with a secondary grouping (e.g. by Status), the "Not Specified" category passed `undefined` as the query value. Since `undefined` is stripped during JSON serialization, the server received no filter and returned all documents — causing assigned issues to appear under "Not Specified". Use `null` instead so the filter survives serialization and correctly matches only documents where the field is unset. Fixes #10606 Signed-off-by: Don Kendall Co-authored-by: Claude Opus 4.6 (1M context) --- .../packages/core/src/__tests__/query.test.ts | 65 +++++++++++++++++++ .../src/components/list/ListCategories.svelte | 2 +- 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 foundations/core/packages/core/src/__tests__/query.test.ts diff --git a/foundations/core/packages/core/src/__tests__/query.test.ts b/foundations/core/packages/core/src/__tests__/query.test.ts new file mode 100644 index 0000000000..e7c06bebb8 --- /dev/null +++ b/foundations/core/packages/core/src/__tests__/query.test.ts @@ -0,0 +1,65 @@ +// +// Copyright © 2026 Hardcore Engineering Inc. +// +// Licensed under the Eclipse Public License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. You may +// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import { findProperty } from '../query' +import type { Doc, Ref, Class } from '../classes' + +function doc (id: string, fields: Record = {}): Doc { + return { _id: id as Ref, _class: 'test:class:Issue' as Ref>, ...fields } as Doc +} + +describe('findProperty', () => { + const assigned1 = doc('i1', { assignee: 'person:1' }) + const assigned2 = doc('i2', { assignee: 'person:2' }) + const unassigned = doc('i3', { assignee: null }) + const missingField = doc('i4') + const allDocs = [assigned1, assigned2, unassigned, missingField] + + it('should match a specific value', () => { + const result = findProperty(allDocs, 'assignee', 'person:1') + expect(result).toEqual([assigned1]) + }) + + it('should match null to docs with null or missing field', () => { + const result = findProperty(allDocs, 'assignee', null) + expect(result).toEqual([unassigned, missingField]) + }) + + it('should match undefined to docs with null or missing field', () => { + const result = findProperty(allDocs, 'assignee', undefined) + expect(result).toEqual([unassigned, missingField]) + }) + + describe('JSON round-trip (simulates server query)', () => { + it('null survives JSON serialization and filters correctly', () => { + const query = { assignee: null } + const roundTripped = JSON.parse(JSON.stringify(query)) + expect(roundTripped).toHaveProperty('assignee') + + const result = findProperty(allDocs, 'assignee', roundTripped.assignee) + expect(result).toEqual([unassigned, missingField]) + }) + + it('undefined is stripped by JSON serialization, losing the filter', () => { + const query = { assignee: undefined } + const roundTripped = JSON.parse(JSON.stringify(query)) + expect(roundTripped).not.toHaveProperty('assignee') + + // Without the 'assignee' key, matchQuery iterates only the remaining keys + // and never calls findProperty for assignee, so all docs pass through. + // This is the root cause of #10606. + }) + }) +}) diff --git a/plugins/view-resources/src/components/list/ListCategories.svelte b/plugins/view-resources/src/components/list/ListCategories.svelte index ab9df328ed..8a0c03c646 100644 --- a/plugins/view-resources/src/components/list/ListCategories.svelte +++ b/plugins/view-resources/src/components/list/ListCategories.svelte @@ -378,7 +378,7 @@ : resultQuery[groupByKey]?.$in?.length !== 0 ? undefined : [] - : category + : category ?? null } }