diff --git a/src/components/Controls.vue b/src/components/Controls.vue index 2c09e1fbe7..b0e4febb9a 100644 --- a/src/components/Controls.vue +++ b/src/components/Controls.vue @@ -146,6 +146,22 @@ :hideStatus="true" /> {{ user.displayname }} +

{{ t('deck', 'Filter by creator') }}

+
+ + +
+

{{ t('deck', 'Filter by status') }}

{ + it('matches an owner given as user id', () => { + expect(cardCreatedByAny({ owner: 'alice' }, ['alice'])).toBe(true) + }) + + it('matches an owner given as user object', () => { + expect(cardCreatedByAny({ owner: { uid: 'alice', displayname: 'Alice' } }, ['alice'])).toBe(true) + }) + + it('matches if the owner is any of several users', () => { + expect(cardCreatedByAny({ owner: 'bob' }, ['alice', 'bob'])).toBe(true) + expect(cardCreatedByAny({ owner: { uid: 'bob' } }, ['alice', 'bob'])).toBe(true) + }) + + it('does not match other owners', () => { + expect(cardCreatedByAny({ owner: 'carol' }, ['alice', 'bob'])).toBe(false) + expect(cardCreatedByAny({ owner: { uid: 'carol' } }, ['alice', 'bob'])).toBe(false) + }) + + it('does not match a card without owner', () => { + expect(cardCreatedByAny({ owner: null }, ['alice'])).toBe(false) + expect(cardCreatedByAny({}, ['alice'])).toBe(false) + }) + + it('does not match when no users are given', () => { + expect(cardCreatedByAny({ owner: 'alice' }, [])).toBe(false) + }) +}) diff --git a/src/stores/board.js b/src/stores/board.js index d0f2d2b25e..651fc006e0 100644 --- a/src/stores/board.js +++ b/src/stores/board.js @@ -25,7 +25,7 @@ export const useBoardStore = defineStore('board', { showArchived: false, viewModeByBoard: {}, assignableUsers: [], - filter: { tags: [], users: [], due: '', unassigned: false, completed: 'both' }, + filter: { tags: [], users: [], creators: [], due: '', unassigned: false, completed: 'both' }, boardFilter: BOARD_FILTERS.ALL, boards: loadState('deck', 'initialBoards', {}), }), @@ -145,7 +145,7 @@ export const useBoardStore = defineStore('board', { localStorage.setItem(`deck.viewMode.${this.currentBoard.id}`, mode) }, async loadBoardById(boardId) { - this.filter = { tags: [], users: [], due: '', unassigned: false, completed: 'both' } + this.filter = { tags: [], users: [], creators: [], due: '', unassigned: false, completed: 'both' } this.setCurrentBoard(null) const board = await apiClient.loadById(boardId) this.setCurrentBoard(board) diff --git a/src/stores/card.js b/src/stores/card.js index 666b042a0e..38a090e766 100644 --- a/src/stores/card.js +++ b/src/stores/card.js @@ -5,6 +5,7 @@ import moment from 'moment' import { defineStore } from 'pinia' +import { cardCreatedByAny } from '../helpers/cardFilters.js' import { CardApi } from '../services/CardApi.js' import { useBoardStore } from './board.js' import { useSettingsStore } from './settings.js' @@ -20,7 +21,7 @@ export const useCardStore = defineStore('card', { getters: { cardsByStack(state) { return (id) => state.cards.filter((card) => { - const { tags, users, due, unassigned, completed } = useBoardStore().filter + const { tags, users, creators, due, unassigned, completed } = useBoardStore().filter if (completed === 'open' && card.done !== null) { return false } @@ -49,6 +50,10 @@ export const useCardStore = defineStore('card', { } } + if (creators.length > 0 && !cardCreatedByAny(card, creators)) { + return false + } + if (unassigned && card.assignedUsers.length > 0) { return false }