Add negative label filtering for cards

This commit is contained in:
Symon
2026-06-05 16:43:45 +03:00
parent 856768c45e
commit 55d0e2f877
23 changed files with 638 additions and 235 deletions
+20
View File
@@ -0,0 +1,20 @@
const getLabelIds = (card) =>
card.labels.toRefArray
? card.labels.toRefArray().map((label) => label.id)
: card.labels.map((label) => label.id);
const filterCardLabels = (cards, includedLabelIds, excludedLabelIds) =>
cards.filter((card) => {
const labelIds = getLabelIds(card);
if (
includedLabelIds.length > 0 &&
!labelIds.some((labelId) => includedLabelIds.includes(labelId))
) {
return false;
}
return !labelIds.some((labelId) => excludedLabelIds.includes(labelId));
});
export default filterCardLabels;
@@ -0,0 +1,34 @@
import filterCardLabels from './filter-card-labels';
const makeCard = (id, labelIds) => ({
id,
labels: labelIds.map((labelId) => ({ id: labelId })),
});
describe('filterCardLabels', () => {
it('keeps cards that have any included label', () => {
const cards = [makeCard('card-1', ['frontend']), makeCard('card-2', ['backend'])];
expect(filterCardLabels(cards, ['frontend'], [])).toEqual([cards[0]]);
});
it('keeps cards that have none of the excluded labels, including unlabeled cards', () => {
const cards = [
makeCard('card-1', ['frontend']),
makeCard('card-2', ['backend']),
makeCard('card-3', []),
];
expect(filterCardLabels(cards, [], ['frontend'])).toEqual([cards[1], cards[2]]);
});
it('combines included and excluded labels with AND semantics', () => {
const cards = [
makeCard('card-1', ['frontend', 'blocked']),
makeCard('card-2', ['frontend']),
makeCard('card-3', ['backend']),
];
expect(filterCardLabels(cards, ['frontend'], ['blocked'])).toEqual([cards[1]]);
});
});