Merge pull request #1683 from symonbaikov/feat/negative-label-filter
Add negative label filtering for cards Two conflicts, both from work that landed while this branch was open. In the endless list query, master had added an ORDER BY so the cursor and the limit agree. The exclusion clause belongs in the WHERE part, so it is placed before it rather than after; the other way round the statement does not parse. The label item had been restructured here for the tri-state filter and had gained a tooltip on master. The restructured version is kept and the tooltip put back on top of it, which also brings back the translation hook this branch had dropped.
This commit is contained in:
@@ -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]]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user